Merge "Revert "Extract network observer code from NetworkManagementService.""

am: 9fdc6d2963

Change-Id: Ib4a7b32a143b3c8f029ccd92191494cd9579e8bd
This commit is contained in:
Remi NGUYEN VAN
2019-01-29 06:47:16 -08:00
committed by android-build-merger
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.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.INetd; import android.net.INetd;
import android.net.INetdUnsolicitedEventListener;
import android.net.INetworkManagementEventObserver; import android.net.INetworkManagementEventObserver;
import android.net.ITetheringStatsProvider; import android.net.ITetheringStatsProvider;
import android.net.InetAddresses;
import android.net.InterfaceConfiguration; import android.net.InterfaceConfiguration;
import android.net.InterfaceConfigurationParcel; import android.net.InterfaceConfigurationParcel;
import android.net.IpPrefix; import android.net.IpPrefix;
@@ -61,7 +63,6 @@ import android.net.RouteInfo;
import android.net.TetherStatsParcel; import android.net.TetherStatsParcel;
import android.net.UidRange; import android.net.UidRange;
import android.net.shared.NetdService; import android.net.shared.NetdService;
import android.net.shared.NetworkObserverRegistry;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
@@ -205,13 +206,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private INetd mNetdService; private INetd mNetdService;
private NMSNetworkObserverRegistry mNetworkObserverRegistry; private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener;
private IBatteryStats mBatteryStats; private IBatteryStats mBatteryStats;
private final Thread mThread; private final Thread mThread;
private CountDownLatch mConnectedSignal = new CountDownLatch(1); private CountDownLatch mConnectedSignal = new CountDownLatch(1);
private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
new RemoteCallbackList<>();
private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory(); private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
@GuardedBy("mTetheringStatsProviders") @GuardedBy("mTetheringStatsProviders")
@@ -321,6 +325,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mDaemonHandler = new Handler(FgThread.get().getLooper()); mDaemonHandler = new Handler(FgThread.get().getLooper());
mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
// Add ourself to the Watchdog monitors. // Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addMonitor(this);
@@ -339,7 +345,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mFgHandler = null; mFgHandler = null;
mThread = null; mThread = null;
mServices = null; mServices = null;
mNetworkObserverRegistry = null; mNetdUnsolicitedEventListener = null;
} }
static NetworkManagementService create(Context context, String socket, SystemServices services) static NetworkManagementService create(Context context, String socket, SystemServices services)
@@ -387,12 +393,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub
@Override @Override
public void registerObserver(INetworkManagementEventObserver observer) { public void registerObserver(INetworkManagementEventObserver observer) {
mNetworkObserverRegistry.registerObserver(observer); mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
mObservers.register(observer);
} }
@Override @Override
public void unregisterObserver(INetworkManagementEventObserver observer) { public void unregisterObserver(INetworkManagementEventObserver observer) {
mNetworkObserverRegistry.unregisterObserver(observer); mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
mObservers.unregister(observer);
} }
@FunctionalInterface @FunctionalInterface
@@ -400,97 +408,123 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public void sendCallback(INetworkManagementEventObserver o) throws RemoteException; public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
} }
private class NMSNetworkObserverRegistry extends NetworkObserverRegistry { private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) {
NMSNetworkObserverRegistry(Context context, Handler handler, INetd netd) final int length = mObservers.beginBroadcast();
throws RemoteException { try {
super(context, handler, netd); 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 * Notify our observers of an interface status change
*/ */
@Override private void notifyInterfaceStatusChanged(String iface, boolean up) {
public void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up));
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) { * Notify our observers of an interface link state change
if (mMobileActivityFromRadio) { * (typically, an Ethernet cable has been plugged-in or unplugged).
// 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 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
// power state to just be whatever the radio last reported. invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up));
powerState = mLastPowerStateFromRadio; }
}
} else { /**
mMobileActivityFromRadio = true; * Notify our observers of an interface addition.
} */
if (mLastPowerStateFromRadio != powerState) { private void notifyInterfaceAdded(String iface) {
mLastPowerStateFromRadio = powerState; invokeForAllObservers(o -> o.interfaceAdded(iface));
try { }
getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
} catch (RemoteException e) { /**
} * 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 (mLastPowerStateFromRadio != powerState) {
if (ConnectivityManager.isNetworkTypeWifi(type)) { mLastPowerStateFromRadio = powerState;
if (mLastPowerStateFromWifi != powerState) { try {
mLastPowerStateFromWifi = powerState; getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
try { } catch (RemoteException e) {
getBatteryStats().noteWifiRadioPowerState(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();
}
} }
/** if (ConnectivityManager.isNetworkTypeWifi(type)) {
* Notify our observers of an interface removal. if (mLastPowerStateFromWifi != powerState) {
*/ mLastPowerStateFromWifi = powerState;
@Override try {
public void notifyInterfaceRemoved(String iface) { getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
// netd already clears out quota and alerts for removed ifaces; update } catch (RemoteException e) {
// our sanity-checking state. }
mActiveAlerts.remove(iface); }
mActiveQuotas.remove(iface);
super.notifyInterfaceRemoved(iface);
} }
@Override if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
public void onStrictCleartextDetected(int uid, String hex) throws RemoteException { // Report the change in data activity. We don't do this if this is a change
// Don't need to post to mDaemonHandler because the only thing // on the mobile network, that is not coming from the radio itself, and we
// that notifyCleartextNetwork does is post to a handler // have previously seen change reports from the radio. In that case only
ActivityManager.getService().notifyCleartextNetwork(uid, // the radio is the authority for the current state.
HexDump.hexStringToByteArray(hex)); 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; return;
} }
// No current code examines the interface parameter in a global alert. Just pass null. // No current code examines the interface parameter in a global alert. Just pass null.
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyLimitReached( mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null));
LIMIT_GLOBAL_ALERT, null));
} }
} }
@@ -552,11 +585,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private void connectNativeNetdService() { private void connectNativeNetdService() {
mNetdService = mServices.getNetd(); mNetdService = mServices.getNetd();
try { try {
mNetworkObserverRegistry = new NMSNetworkObserverRegistry( mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
mContext, mDaemonHandler, mNetdService); if (DBG) Slog.d(TAG, "Register unsolicited event listener");
if (DBG) Slog.d(TAG, "Registered NetworkObserverRegistry");
} catch (RemoteException | ServiceSpecificException e) { } 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 // Netd Callback handling
// //
@@ -708,18 +852,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
} }
if (cooked[2].equals("added")) { if (cooked[2].equals("added")) {
mNetworkObserverRegistry.notifyInterfaceAdded(cooked[3]); notifyInterfaceAdded(cooked[3]);
return true; return true;
} else if (cooked[2].equals("removed")) { } else if (cooked[2].equals("removed")) {
mNetworkObserverRegistry.notifyInterfaceRemoved(cooked[3]); notifyInterfaceRemoved(cooked[3]);
return true; return true;
} else if (cooked[2].equals("changed") && cooked.length == 5) { } else if (cooked[2].equals("changed") && cooked.length == 5) {
mNetworkObserverRegistry.notifyInterfaceStatusChanged( notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
cooked[3], cooked[4].equals("up"));
return true; return true;
} else if (cooked[2].equals("linkstate") && cooked.length == 5) { } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
mNetworkObserverRegistry.notifyInterfaceLinkStateChanged( notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
cooked[3], cooked[4].equals("up"));
return true; return true;
} }
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
@@ -733,7 +875,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
} }
if (cooked[2].equals("alert")) { if (cooked[2].equals("alert")) {
mNetworkObserverRegistry.notifyLimitReached(cooked[3], cooked[4]); notifyLimitReached(cooked[3], cooked[4]);
return true; return true;
} }
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
@@ -759,9 +901,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
timestampNanos = SystemClock.elapsedRealtimeNanos(); timestampNanos = SystemClock.elapsedRealtimeNanos();
} }
boolean isActive = cooked[2].equals("active"); boolean isActive = cooked[2].equals("active");
mNetworkObserverRegistry.notifyInterfaceClassActivity( notifyInterfaceClassActivity(Integer.parseInt(cooked[3]),
Integer.parseInt(cooked[3]), isActive, isActive, timestampNanos, processUid, false);
timestampNanos, processUid, false);
return true; return true;
// break; // break;
case NetdResponseCode.InterfaceAddressChange: case NetdResponseCode.InterfaceAddressChange:
@@ -787,9 +928,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub
} }
if (cooked[2].equals("updated")) { if (cooked[2].equals("updated")) {
mNetworkObserverRegistry.notifyAddressUpdated(iface, address); notifyAddressUpdated(iface, address);
} else { } else {
mNetworkObserverRegistry.notifyAddressRemoved(iface, address); notifyAddressRemoved(iface, address);
} }
return true; return true;
// break; // break;
@@ -809,8 +950,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
} }
String[] servers = cooked[5].split(","); String[] servers = cooked[5].split(",");
mNetworkObserverRegistry.notifyInterfaceDnsServerInfo( notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers);
cooked[3], lifetime, servers);
} }
return true; return true;
// break; // break;
@@ -849,8 +989,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
InetAddress gateway = null; InetAddress gateway = null;
if (via != null) gateway = InetAddress.parseNumericAddress(via); if (via != null) gateway = InetAddress.parseNumericAddress(via);
RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev); RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev);
mNetworkObserverRegistry.notifyRouteChange( notifyRouteChange(cooked[2].equals("updated"), route);
cooked[2].equals("updated"), route);
return true; return true;
} catch (IllegalArgumentException e) {} } catch (IllegalArgumentException e) {}
} }
@@ -1313,8 +1452,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
if (ConnectivityManager.isNetworkTypeMobile(type)) { if (ConnectivityManager.isNetworkTypeMobile(type)) {
mNetworkActive = false; mNetworkActive = false;
} }
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity( mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
type, true /* isActive */, SystemClock.elapsedRealtimeNanos(), -1, false)); SystemClock.elapsedRealtimeNanos(), -1, false));
} }
} }
@@ -1337,9 +1476,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
mActiveIdleTimers.remove(iface); mActiveIdleTimers.remove(iface);
mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity( mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
params.type, false /* isActive */, SystemClock.elapsedRealtimeNanos(), -1, SystemClock.elapsedRealtimeNanos(), -1, false));
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.
}
}