Revert "Extract network observer code from NetworkManagementService."

This reverts commit d8bc829a85.

Reason for revert: Refactoring was unnecessary

Merged-In: Ib4e7da3274e49f25676505a08e6ce7e7b0dfdb8d
Change-Id: Iff332c680315b560f0b762c1d7311ec83d539115
This commit is contained in:
Remi NGUYEN VAN
2019-01-29 04:03:38 +00:00
parent d8bc829a85
commit bfd0aa022e
2 changed files with 250 additions and 367 deletions

View File

@@ -47,8 +47,10 @@ import android.app.ActivityManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.INetdUnsolicitedEventListener;
import android.net.INetworkManagementEventObserver;
import android.net.ITetheringStatsProvider;
import android.net.InetAddresses;
import android.net.InterfaceConfiguration;
import android.net.InterfaceConfigurationParcel;
import android.net.IpPrefix;
@@ -61,7 +63,6 @@ import android.net.RouteInfo;
import android.net.TetherStatsParcel;
import android.net.UidRange;
import android.net.shared.NetdService;
import android.net.shared.NetworkObserverRegistry;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
@@ -205,13 +206,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private INetd mNetdService;
private NMSNetworkObserverRegistry mNetworkObserverRegistry;
private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener;
private IBatteryStats mBatteryStats;
private final Thread mThread;
private CountDownLatch mConnectedSignal = new CountDownLatch(1);
private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
new RemoteCallbackList<>();
private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
@GuardedBy("mTetheringStatsProviders")
@@ -321,6 +325,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mDaemonHandler = new Handler(FgThread.get().getLooper());
mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
@@ -339,7 +345,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mFgHandler = null;
mThread = null;
mServices = null;
mNetworkObserverRegistry = null;
mNetdUnsolicitedEventListener = null;
}
static NetworkManagementService create(Context context, String socket, SystemServices services)
@@ -387,12 +393,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub
@Override
public void registerObserver(INetworkManagementEventObserver observer) {
mNetworkObserverRegistry.registerObserver(observer);
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
mObservers.register(observer);
}
@Override
public void unregisterObserver(INetworkManagementEventObserver observer) {
mNetworkObserverRegistry.unregisterObserver(observer);
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
mObservers.unregister(observer);
}
@FunctionalInterface
@@ -400,97 +408,123 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
}
private class NMSNetworkObserverRegistry extends NetworkObserverRegistry {
NMSNetworkObserverRegistry(Context context, Handler handler, INetd netd)
throws RemoteException {
super(context, handler, netd);
private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) {
final int length = mObservers.beginBroadcast();
try {
for (int i = 0; i < length; i++) {
try {
eventCallback.sendCallback(mObservers.getBroadcastItem(i));
} catch (RemoteException | RuntimeException e) {
}
}
} finally {
mObservers.finishBroadcast();
}
}
/**
* Notify our observers of a change in the data activity state of the interface
*/
@Override
public void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
int uid, boolean fromRadio) {
final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
int powerState = isActive
? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
: DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
/**
* Notify our observers of an interface status change
*/
private void notifyInterfaceStatusChanged(String iface, boolean up) {
invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up));
}
if (isMobile) {
if (!fromRadio) {
if (mMobileActivityFromRadio) {
// If this call is not coming from a report from the radio itself, but we
// have previously received reports from the radio, then we will take the
// power state to just be whatever the radio last reported.
powerState = mLastPowerStateFromRadio;
}
} else {
mMobileActivityFromRadio = true;
}
if (mLastPowerStateFromRadio != powerState) {
mLastPowerStateFromRadio = powerState;
try {
getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
} catch (RemoteException e) {
}
/**
* Notify our observers of an interface link state change
* (typically, an Ethernet cable has been plugged-in or unplugged).
*/
private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up));
}
/**
* Notify our observers of an interface addition.
*/
private void notifyInterfaceAdded(String iface) {
invokeForAllObservers(o -> o.interfaceAdded(iface));
}
/**
* Notify our observers of an interface removal.
*/
private void notifyInterfaceRemoved(String iface) {
// netd already clears out quota and alerts for removed ifaces; update
// our sanity-checking state.
mActiveAlerts.remove(iface);
mActiveQuotas.remove(iface);
invokeForAllObservers(o -> o.interfaceRemoved(iface));
}
/**
* Notify our observers of a limit reached.
*/
private void notifyLimitReached(String limitName, String iface) {
invokeForAllObservers(o -> o.limitReached(limitName, iface));
}
/**
* Notify our observers of a change in the data activity state of the interface
*/
private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
int uid, boolean fromRadio) {
final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
int powerState = isActive
? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
: DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
if (isMobile) {
if (!fromRadio) {
if (mMobileActivityFromRadio) {
// If this call is not coming from a report from the radio itself, but we
// have previously received reports from the radio, then we will take the
// power state to just be whatever the radio last reported.
powerState = mLastPowerStateFromRadio;
}
} else {
mMobileActivityFromRadio = true;
}
if (ConnectivityManager.isNetworkTypeWifi(type)) {
if (mLastPowerStateFromWifi != powerState) {
mLastPowerStateFromWifi = powerState;
try {
getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
} catch (RemoteException e) {
}
if (mLastPowerStateFromRadio != powerState) {
mLastPowerStateFromRadio = powerState;
try {
getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
} catch (RemoteException e) {
}
}
if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
// Report the change in data activity. We don't do this if this is a change
// on the mobile network, that is not coming from the radio itself, and we
// have previously seen change reports from the radio. In that case only
// the radio is the authority for the current state.
final boolean active = isActive;
super.notifyInterfaceClassActivity(type, isActive, tsNanos, uid, fromRadio);
}
boolean report = false;
synchronized (mIdleTimerLock) {
if (mActiveIdleTimers.isEmpty()) {
// If there are no idle timers, we are not monitoring activity, so we
// are always considered active.
isActive = true;
}
if (mNetworkActive != isActive) {
mNetworkActive = isActive;
report = isActive;
}
}
if (report) {
reportNetworkActive();
}
}
/**
* Notify our observers of an interface removal.
*/
@Override
public void notifyInterfaceRemoved(String iface) {
// netd already clears out quota and alerts for removed ifaces; update
// our sanity-checking state.
mActiveAlerts.remove(iface);
mActiveQuotas.remove(iface);
super.notifyInterfaceRemoved(iface);
if (ConnectivityManager.isNetworkTypeWifi(type)) {
if (mLastPowerStateFromWifi != powerState) {
mLastPowerStateFromWifi = powerState;
try {
getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
} catch (RemoteException e) {
}
}
}
@Override
public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
// Don't need to post to mDaemonHandler because the only thing
// that notifyCleartextNetwork does is post to a handler
ActivityManager.getService().notifyCleartextNetwork(uid,
HexDump.hexStringToByteArray(hex));
if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
// Report the change in data activity. We don't do this if this is a change
// on the mobile network, that is not coming from the radio itself, and we
// have previously seen change reports from the radio. In that case only
// the radio is the authority for the current state.
final boolean active = isActive;
invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
Integer.toString(type), active, tsNanos));
}
boolean report = false;
synchronized (mIdleTimerLock) {
if (mActiveIdleTimers.isEmpty()) {
// If there are no idle timers, we are not monitoring activity, so we
// are always considered active.
isActive = true;
}
if (mNetworkActive != isActive) {
mNetworkActive = isActive;
report = isActive;
}
}
if (report) {
reportNetworkActive();
}
}
@@ -519,8 +553,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
return;
}
// No current code examines the interface parameter in a global alert. Just pass null.
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyLimitReached(
LIMIT_GLOBAL_ALERT, null));
mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null));
}
}
@@ -552,11 +585,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private void connectNativeNetdService() {
mNetdService = mServices.getNetd();
try {
mNetworkObserverRegistry = new NMSNetworkObserverRegistry(
mContext, mDaemonHandler, mNetdService);
if (DBG) Slog.d(TAG, "Registered NetworkObserverRegistry");
mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
if (DBG) Slog.d(TAG, "Register unsolicited event listener");
} catch (RemoteException | ServiceSpecificException e) {
Slog.wtf(TAG, "Failed to register NetworkObserverRegistry: " + e);
Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e);
}
}
@@ -660,6 +692,118 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
/**
* Notify our observers of a new or updated interface address.
*/
private void notifyAddressUpdated(String iface, LinkAddress address) {
invokeForAllObservers(o -> o.addressUpdated(iface, address));
}
/**
* Notify our observers of a deleted interface address.
*/
private void notifyAddressRemoved(String iface, LinkAddress address) {
invokeForAllObservers(o -> o.addressRemoved(iface, address));
}
/**
* Notify our observers of DNS server information received.
*/
private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses));
}
/**
* Notify our observers of a route change.
*/
private void notifyRouteChange(boolean updated, RouteInfo route) {
if (updated) {
invokeForAllObservers(o -> o.routeUpdated(route));
} else {
invokeForAllObservers(o -> o.routeRemoved(route));
}
}
private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
@Override
public void onInterfaceClassActivityChanged(boolean isActive,
int label, long timestamp, int uid) throws RemoteException {
final long timestampNanos;
if (timestamp <= 0) {
timestampNanos = SystemClock.elapsedRealtimeNanos();
} else {
timestampNanos = timestamp;
}
mDaemonHandler.post(() ->
notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false));
}
@Override
public void onQuotaLimitReached(String alertName, String ifName)
throws RemoteException {
mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName));
}
@Override
public void onInterfaceDnsServerInfo(String ifName,
long lifetime, String[] servers) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers));
}
@Override
public void onInterfaceAddressUpdated(String addr,
String ifName, int flags, int scope) throws RemoteException {
final LinkAddress address = new LinkAddress(addr, flags, scope);
mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address));
}
@Override
public void onInterfaceAddressRemoved(String addr,
String ifName, int flags, int scope) throws RemoteException {
final LinkAddress address = new LinkAddress(addr, flags, scope);
mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address));
}
@Override
public void onInterfaceAdded(String ifName) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceAdded(ifName));
}
@Override
public void onInterfaceRemoved(String ifName) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName));
}
@Override
public void onInterfaceChanged(String ifName, boolean up)
throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up));
}
@Override
public void onInterfaceLinkStateChanged(String ifName, boolean up)
throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up));
}
@Override
public void onRouteChanged(boolean updated,
String route, String gateway, String ifName) throws RemoteException {
final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
ifName);
mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
}
@Override
public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
// Don't need to post to mDaemonHandler because the only thing
// that notifyCleartextNetwork does is post to a handler
ActivityManager.getService().notifyCleartextNetwork(uid,
HexDump.hexStringToByteArray(hex));
}
}
//
// Netd Callback handling
//
@@ -708,18 +852,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage);
}
if (cooked[2].equals("added")) {
mNetworkObserverRegistry.notifyInterfaceAdded(cooked[3]);
notifyInterfaceAdded(cooked[3]);
return true;
} else if (cooked[2].equals("removed")) {
mNetworkObserverRegistry.notifyInterfaceRemoved(cooked[3]);
notifyInterfaceRemoved(cooked[3]);
return true;
} else if (cooked[2].equals("changed") && cooked.length == 5) {
mNetworkObserverRegistry.notifyInterfaceStatusChanged(
cooked[3], cooked[4].equals("up"));
notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
return true;
} else if (cooked[2].equals("linkstate") && cooked.length == 5) {
mNetworkObserverRegistry.notifyInterfaceLinkStateChanged(
cooked[3], cooked[4].equals("up"));
notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
return true;
}
throw new IllegalStateException(errorMessage);
@@ -733,7 +875,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage);
}
if (cooked[2].equals("alert")) {
mNetworkObserverRegistry.notifyLimitReached(cooked[3], cooked[4]);
notifyLimitReached(cooked[3], cooked[4]);
return true;
}
throw new IllegalStateException(errorMessage);
@@ -759,9 +901,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
timestampNanos = SystemClock.elapsedRealtimeNanos();
}
boolean isActive = cooked[2].equals("active");
mNetworkObserverRegistry.notifyInterfaceClassActivity(
Integer.parseInt(cooked[3]), isActive,
timestampNanos, processUid, false);
notifyInterfaceClassActivity(Integer.parseInt(cooked[3]),
isActive, timestampNanos, processUid, false);
return true;
// break;
case NetdResponseCode.InterfaceAddressChange:
@@ -787,9 +928,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
if (cooked[2].equals("updated")) {
mNetworkObserverRegistry.notifyAddressUpdated(iface, address);
notifyAddressUpdated(iface, address);
} else {
mNetworkObserverRegistry.notifyAddressRemoved(iface, address);
notifyAddressRemoved(iface, address);
}
return true;
// break;
@@ -809,8 +950,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage);
}
String[] servers = cooked[5].split(",");
mNetworkObserverRegistry.notifyInterfaceDnsServerInfo(
cooked[3], lifetime, servers);
notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers);
}
return true;
// break;
@@ -849,8 +989,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
InetAddress gateway = null;
if (via != null) gateway = InetAddress.parseNumericAddress(via);
RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev);
mNetworkObserverRegistry.notifyRouteChange(
cooked[2].equals("updated"), route);
notifyRouteChange(cooked[2].equals("updated"), route);
return true;
} catch (IllegalArgumentException e) {}
}
@@ -1313,8 +1452,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
if (ConnectivityManager.isNetworkTypeMobile(type)) {
mNetworkActive = false;
}
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity(
type, true /* isActive */, SystemClock.elapsedRealtimeNanos(), -1, false));
mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
SystemClock.elapsedRealtimeNanos(), -1, false));
}
}
@@ -1337,9 +1476,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(e);
}
mActiveIdleTimers.remove(iface);
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity(
params.type, false /* isActive */, SystemClock.elapsedRealtimeNanos(), -1,
false));
mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
SystemClock.elapsedRealtimeNanos(), -1, false));
}
}

View File

@@ -1,255 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.shared;
import static android.Manifest.permission.NETWORK_STACK;
import android.content.Context;
import android.net.INetd;
import android.net.INetdUnsolicitedEventListener;
import android.net.INetworkManagementEventObserver;
import android.net.InetAddresses;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.RouteInfo;
import android.os.Handler;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
/**
* A class for reporting network events to clients.
*
* Implements INetdUnsolicitedEventListener and registers with netd, and relays those events to
* all INetworkManagementEventObserver objects that have registered with it.
*
* TODO: Make the notifyXyz methods protected once subclasses (e.g., the NetworkManagementService
* subclass) no longer call them directly.
*
* TODO: change from RemoteCallbackList to direct in-process callbacks.
*/
public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub {
private final Context mContext;
private final Handler mDaemonHandler;
private static final String TAG = "NetworkObserverRegistry";
/**
* Constructs a new instance and registers it with netd.
* This method should only be called once since netd will reject multiple registrations from
* the same process.
*/
public NetworkObserverRegistry(Context context, Handler handler, INetd netd)
throws RemoteException {
mContext = context;
mDaemonHandler = handler;
netd.registerUnsolicitedEventListener(this);
}
private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
new RemoteCallbackList<>();
/**
* Registers the specified observer and start sending callbacks to it.
* This method may be called on any thread.
*/
public void registerObserver(INetworkManagementEventObserver observer) {
mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
mObservers.register(observer);
}
/**
* Unregisters the specified observer and stop sending callbacks to it.
* This method may be called on any thread.
*/
public void unregisterObserver(INetworkManagementEventObserver observer) {
mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
mObservers.unregister(observer);
}
@FunctionalInterface
private interface NetworkManagementEventCallback {
void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
}
private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) {
final int length = mObservers.beginBroadcast();
try {
for (int i = 0; i < length; i++) {
try {
eventCallback.sendCallback(mObservers.getBroadcastItem(i));
} catch (RemoteException | RuntimeException e) {
}
}
} finally {
mObservers.finishBroadcast();
}
}
/**
* Notify our observers of a change in the data activity state of the interface
*/
public void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
int uid, boolean fromRadio) {
invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
Integer.toString(type), isActive, tsNanos));
}
@Override
public void onInterfaceClassActivityChanged(boolean isActive,
int label, long timestamp, int uid) throws RemoteException {
final long timestampNanos;
if (timestamp <= 0) {
timestampNanos = SystemClock.elapsedRealtimeNanos();
} else {
timestampNanos = timestamp;
}
mDaemonHandler.post(() -> notifyInterfaceClassActivity(label, isActive,
timestampNanos, uid, false));
}
/**
* Notify our observers of a limit reached.
*/
@Override
public void onQuotaLimitReached(String alertName, String ifName) throws RemoteException {
mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName));
}
/**
* Notify our observers of a limit reached.
*/
public void notifyLimitReached(String limitName, String iface) {
invokeForAllObservers(o -> o.limitReached(limitName, iface));
}
@Override
public void onInterfaceDnsServerInfo(String ifName,
long lifetime, String[] servers) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers));
}
/**
* Notify our observers of DNS server information received.
*/
public void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses));
}
@Override
public void onInterfaceAddressUpdated(String addr,
String ifName, int flags, int scope) throws RemoteException {
final LinkAddress address = new LinkAddress(addr, flags, scope);
mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address));
}
/**
* Notify our observers of a new or updated interface address.
*/
public void notifyAddressUpdated(String iface, LinkAddress address) {
invokeForAllObservers(o -> o.addressUpdated(iface, address));
}
@Override
public void onInterfaceAddressRemoved(String addr,
String ifName, int flags, int scope) throws RemoteException {
final LinkAddress address = new LinkAddress(addr, flags, scope);
mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address));
}
/**
* Notify our observers of a deleted interface address.
*/
public void notifyAddressRemoved(String iface, LinkAddress address) {
invokeForAllObservers(o -> o.addressRemoved(iface, address));
}
@Override
public void onInterfaceAdded(String ifName) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceAdded(ifName));
}
/**
* Notify our observers of an interface addition.
*/
public void notifyInterfaceAdded(String iface) {
invokeForAllObservers(o -> o.interfaceAdded(iface));
}
@Override
public void onInterfaceRemoved(String ifName) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName));
}
/**
* Notify our observers of an interface removal.
*/
public void notifyInterfaceRemoved(String iface) {
invokeForAllObservers(o -> o.interfaceRemoved(iface));
}
@Override
public void onInterfaceChanged(String ifName, boolean up) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up));
}
/**
* Notify our observers of an interface status change
*/
public void notifyInterfaceStatusChanged(String iface, boolean up) {
invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up));
}
@Override
public void onInterfaceLinkStateChanged(String ifName, boolean up) throws RemoteException {
mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up));
}
/**
* Notify our observers of an interface link state change
* (typically, an Ethernet cable has been plugged-in or unplugged).
*/
public void notifyInterfaceLinkStateChanged(String iface, boolean up) {
invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up));
}
@Override
public void onRouteChanged(boolean updated,
String route, String gateway, String ifName) throws RemoteException {
final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
ifName);
mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
}
/**
* Notify our observers of a route change.
*/
public void notifyRouteChange(boolean updated, RouteInfo route) {
if (updated) {
invokeForAllObservers(o -> o.routeUpdated(route));
} else {
invokeForAllObservers(o -> o.routeRemoved(route));
}
}
@Override
public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
// Don't do anything here because this is not a method of INetworkManagementEventObserver.
// Only the NMS subclass will implement this.
}
}