Merge changes I0a75c440,Ief9e8925,Ie03e8276,If0ac9a64,I716bd771 am: 63bc7bd3c2
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1573943 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I20a0f2d4a59222083d1c17a7732b7fe0b8461502
This commit is contained in:
@@ -24,7 +24,6 @@ import android.net.Network;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.UidRange;
|
||||
import android.os.INetworkActivityListener;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -294,25 +293,6 @@ interface INetworkManagementService
|
||||
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
|
||||
boolean isBandwidthControlEnabled();
|
||||
|
||||
/**
|
||||
* Sets idletimer for an interface.
|
||||
*
|
||||
* This either initializes a new idletimer or increases its
|
||||
* reference-counting if an idletimer already exists for given
|
||||
* {@code iface}.
|
||||
*
|
||||
* {@code type} is the type of the interface, such as TYPE_MOBILE.
|
||||
*
|
||||
* Every {@code addIdleTimer} should be paired with a
|
||||
* {@link removeIdleTimer} to cleanup when the network disconnects.
|
||||
*/
|
||||
void addIdleTimer(String iface, int timeout, int type);
|
||||
|
||||
/**
|
||||
* Removes idletimer for an interface.
|
||||
*/
|
||||
void removeIdleTimer(String iface);
|
||||
|
||||
void setFirewallEnabled(boolean enabled);
|
||||
boolean isFirewallEnabled();
|
||||
void setFirewallInterfaceRule(String iface, boolean allow);
|
||||
@@ -320,21 +300,6 @@ interface INetworkManagementService
|
||||
void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
|
||||
void setFirewallChainEnabled(int chain, boolean enable);
|
||||
|
||||
/**
|
||||
* Start listening for mobile activity state changes.
|
||||
*/
|
||||
void registerNetworkActivityListener(INetworkActivityListener listener);
|
||||
|
||||
/**
|
||||
* Stop listening for mobile activity state changes.
|
||||
*/
|
||||
void unregisterNetworkActivityListener(INetworkActivityListener listener);
|
||||
|
||||
/**
|
||||
* Check whether the mobile radio is currently active.
|
||||
*/
|
||||
boolean isNetworkActive();
|
||||
|
||||
void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,8 +49,6 @@ import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.INetworkActivityListener;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
@@ -835,7 +833,6 @@ public class ConnectivityManager {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private INetworkManagementService mNMService;
|
||||
private INetworkPolicyManager mNPManager;
|
||||
private final TetheringManager mTetheringManager;
|
||||
|
||||
@@ -2211,17 +2208,6 @@ public class ConnectivityManager {
|
||||
void onNetworkActive();
|
||||
}
|
||||
|
||||
private INetworkManagementService getNetworkManagementService() {
|
||||
synchronized (this) {
|
||||
if (mNMService != null) {
|
||||
return mNMService;
|
||||
}
|
||||
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
|
||||
mNMService = INetworkManagementService.Stub.asInterface(b);
|
||||
return mNMService;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
|
||||
mNetworkActivityListeners = new ArrayMap<>();
|
||||
|
||||
@@ -2246,7 +2232,7 @@ public class ConnectivityManager {
|
||||
};
|
||||
|
||||
try {
|
||||
getNetworkManagementService().registerNetworkActivityListener(rl);
|
||||
mService.registerNetworkActivityListener(rl);
|
||||
mNetworkActivityListeners.put(l, rl);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -2263,7 +2249,7 @@ public class ConnectivityManager {
|
||||
INetworkActivityListener rl = mNetworkActivityListeners.get(l);
|
||||
Preconditions.checkArgument(rl != null, "Listener was not registered.");
|
||||
try {
|
||||
getNetworkManagementService().unregisterNetworkActivityListener(rl);
|
||||
mService.registerNetworkActivityListener(rl);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -2279,7 +2265,7 @@ public class ConnectivityManager {
|
||||
*/
|
||||
public boolean isDefaultNetworkActive() {
|
||||
try {
|
||||
return getNetworkManagementService().isNetworkActive();
|
||||
return mService.isDefaultNetworkActive();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.net.ConnectionInfo;
|
||||
import android.net.ConnectivityDiagnosticsManager;
|
||||
import android.net.IConnectivityDiagnosticsCallback;
|
||||
import android.net.IOnSetOemNetworkPreferenceListener;
|
||||
import android.net.INetworkActivityListener;
|
||||
import android.net.IQosCallback;
|
||||
import android.net.ISocketKeepaliveCallback;
|
||||
import android.net.LinkProperties;
|
||||
@@ -36,7 +37,6 @@ import android.net.UidRange;
|
||||
import android.net.QosSocketInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.INetworkActivityListener;
|
||||
import android.os.Messenger;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
package android.net;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -90,6 +90,7 @@ import android.net.IConnectivityDiagnosticsCallback;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.INetworkActivityListener;
|
||||
import android.net.INetworkManagementEventObserver;
|
||||
import android.net.INetworkMonitor;
|
||||
import android.net.INetworkMonitorCallbacks;
|
||||
@@ -147,13 +148,13 @@ import android.net.netlink.InetDiagMessage;
|
||||
import android.net.shared.PrivateDnsConfig;
|
||||
import android.net.util.MultinetworkPolicyTracker;
|
||||
import android.net.util.NetdService;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.INetworkActivityListener;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -163,6 +164,7 @@ import android.os.Parcelable;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.SystemClock;
|
||||
@@ -172,6 +174,7 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.LocalLog;
|
||||
import android.util.Log;
|
||||
@@ -558,6 +561,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
|
||||
|
||||
/**
|
||||
* Used to indicate the system default network becomes active.
|
||||
*/
|
||||
private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
|
||||
|
||||
/**
|
||||
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
|
||||
* should be shown.
|
||||
@@ -1192,7 +1200,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
|
||||
null /* broadcastPermission */, mHandler);
|
||||
|
||||
mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNMS);
|
||||
mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd);
|
||||
|
||||
mSettingsObserver = new SettingsObserver(mContext, mHandler);
|
||||
registerSettingsCallbacks();
|
||||
@@ -2404,7 +2412,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
@Override
|
||||
public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
|
||||
// TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
|
||||
mNetworkActivityTracker.registerNetworkActivityListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2412,7 +2420,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
@Override
|
||||
public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
|
||||
// TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
|
||||
mNetworkActivityTracker.unregisterNetworkActivityListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2420,8 +2428,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
@Override
|
||||
public boolean isDefaultNetworkActive() {
|
||||
// TODO: Replace isNetworkActive() in NMS.
|
||||
return false;
|
||||
return mNetworkActivityTracker.isDefaultNetworkActive();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2686,6 +2693,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
pw.increaseIndent();
|
||||
mPermissionMonitor.dump(pw);
|
||||
pw.decreaseIndent();
|
||||
|
||||
pw.println();
|
||||
pw.println("Legacy network activity:");
|
||||
pw.increaseIndent();
|
||||
mNetworkActivityTracker.dump(pw);
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
private void dumpNetworks(IndentingPrintWriter pw) {
|
||||
@@ -4452,6 +4465,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
loge("handleMessage.EVENT_SET_OEM_NETWORK_PREFERENCE failed", e);
|
||||
}
|
||||
break;
|
||||
case EVENT_REPORT_NETWORK_ACTIVITY:
|
||||
mNetworkActivityTracker.handleReportNetworkActivity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8639,13 +8655,35 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
* changes.
|
||||
*/
|
||||
private static final class LegacyNetworkActivityTracker {
|
||||
private static final int NO_UID = -1;
|
||||
private final Context mContext;
|
||||
private final INetd mNetd;
|
||||
private final INetworkManagementService mNMS;
|
||||
private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
|
||||
new RemoteCallbackList<>();
|
||||
// Indicate the current system default network activity is active or not.
|
||||
@GuardedBy("mActiveIdleTimers")
|
||||
private boolean mNetworkActive;
|
||||
@GuardedBy("mActiveIdleTimers")
|
||||
private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap();
|
||||
private final Handler mHandler;
|
||||
|
||||
LegacyNetworkActivityTracker(@NonNull Context context,
|
||||
@NonNull INetworkManagementService nms) {
|
||||
private class IdleTimerParams {
|
||||
public final int timeout;
|
||||
public final int transportType;
|
||||
|
||||
IdleTimerParams(int timeout, int transport) {
|
||||
this.timeout = timeout;
|
||||
this.transportType = transport;
|
||||
}
|
||||
}
|
||||
|
||||
LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
|
||||
@NonNull INetworkManagementService nms, @NonNull INetd netd) {
|
||||
mContext = context;
|
||||
mNMS = nms;
|
||||
mNetd = netd;
|
||||
mHandler = handler;
|
||||
try {
|
||||
mNMS.registerObserver(mDataActivityObserver);
|
||||
} catch (RemoteException e) {
|
||||
@@ -8661,9 +8699,50 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
long tsNanos, int uid) {
|
||||
sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active,
|
||||
tsNanos);
|
||||
synchronized (mActiveIdleTimers) {
|
||||
mNetworkActive = active;
|
||||
// If there are no idle timers, it means that system is not monitoring
|
||||
// activity, so the system default network for those default network
|
||||
// unspecified apps is always considered active.
|
||||
//
|
||||
// TODO: If the mActiveIdleTimers is empty, netd will actually not send
|
||||
// any network activity change event. Whenever this event is received,
|
||||
// the mActiveIdleTimers should be always not empty. The legacy behavior
|
||||
// is no-op. Remove to refer to mNetworkActive only.
|
||||
if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
|
||||
mHandler.sendMessage(
|
||||
mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// The network activity should only be updated from ConnectivityService handler thread
|
||||
// when mActiveIdleTimers lock is held.
|
||||
@GuardedBy("mActiveIdleTimers")
|
||||
private void reportNetworkActive() {
|
||||
final int length = mNetworkActivityListeners.beginBroadcast();
|
||||
if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
|
||||
try {
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
loge("Fail to send network activie to listener " + e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mNetworkActivityListeners.finishBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mActiveIdleTimers")
|
||||
public void handleReportNetworkActivity() {
|
||||
synchronized (mActiveIdleTimers) {
|
||||
reportNetworkActive();
|
||||
}
|
||||
}
|
||||
|
||||
// This is deprecated and only to support legacy use cases.
|
||||
private int transportTypeToLegacyType(int type) {
|
||||
switch (type) {
|
||||
@@ -8728,10 +8807,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return; // do not track any other networks
|
||||
}
|
||||
|
||||
updateRadioPowerState(true /* isActive */, type);
|
||||
|
||||
if (timeout > 0 && iface != null) {
|
||||
try {
|
||||
// TODO: Access INetd directly instead of NMS
|
||||
mNMS.addIdleTimer(iface, timeout, type);
|
||||
synchronized (mActiveIdleTimers) {
|
||||
// Networks start up.
|
||||
mNetworkActive = true;
|
||||
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
|
||||
mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
|
||||
reportNetworkActive();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// You shall not crash!
|
||||
loge("Exception in setupDataActivityTracking " + e);
|
||||
@@ -8746,16 +8832,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
final String iface = networkAgent.linkProperties.getInterfaceName();
|
||||
final NetworkCapabilities caps = networkAgent.networkCapabilities;
|
||||
|
||||
if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
|| caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
|
||||
try {
|
||||
// the call fails silently if no idle timer setup for this interface
|
||||
// TODO: Access INetd directly instead of NMS
|
||||
mNMS.removeIdleTimer(iface);
|
||||
} catch (Exception e) {
|
||||
// You shall not crash!
|
||||
loge("Exception in removeDataActivityTracking " + e);
|
||||
if (iface == null) return;
|
||||
|
||||
final int type;
|
||||
if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
|
||||
type = NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
} else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||
type = NetworkCapabilities.TRANSPORT_WIFI;
|
||||
} else {
|
||||
return; // do not track any other networks
|
||||
}
|
||||
|
||||
try {
|
||||
updateRadioPowerState(false /* isActive */, type);
|
||||
synchronized (mActiveIdleTimers) {
|
||||
final IdleTimerParams params = mActiveIdleTimers.remove(iface);
|
||||
// The call fails silently if no idle timer setup for this interface
|
||||
mNetd.idletimerRemoveInterface(iface, params.timeout,
|
||||
Integer.toString(params.transportType));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// You shall not crash!
|
||||
loge("Exception in removeDataActivityTracking " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8771,6 +8869,53 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
removeDataActivityTracking(oldNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRadioPowerState(boolean isActive, int transportType) {
|
||||
final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
|
||||
switch (transportType) {
|
||||
case NetworkCapabilities.TRANSPORT_CELLULAR:
|
||||
bs.reportMobileRadioPowerState(isActive, NO_UID);
|
||||
break;
|
||||
case NetworkCapabilities.TRANSPORT_WIFI:
|
||||
bs.reportWifiRadioPowerState(isActive, NO_UID);
|
||||
break;
|
||||
default:
|
||||
logw("Untracked transport type:" + transportType);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDefaultNetworkActive() {
|
||||
synchronized (mActiveIdleTimers) {
|
||||
// If there are no idle timers, it means that system is not monitoring activity,
|
||||
// so the default network is always considered active.
|
||||
//
|
||||
// TODO : Distinguish between the cases where mActiveIdleTimers is empty because
|
||||
// tracking is disabled (negative idle timer value configured), or no active default
|
||||
// network. In the latter case, this reports active but it should report inactive.
|
||||
return mNetworkActive || mActiveIdleTimers.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
|
||||
mNetworkActivityListeners.register(l);
|
||||
}
|
||||
|
||||
public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
|
||||
mNetworkActivityListeners.unregister(l);
|
||||
}
|
||||
|
||||
public void dump(IndentingPrintWriter pw) {
|
||||
synchronized (mActiveIdleTimers) {
|
||||
pw.print("mNetworkActive="); pw.println(mNetworkActive);
|
||||
pw.println("Idle timers:");
|
||||
for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
|
||||
pw.print(" "); pw.print(ent.getKey()); pw.println(":");
|
||||
final IdleTimerParams params = ent.getValue();
|
||||
pw.print(" timeout="); pw.print(params.timeout);
|
||||
pw.print(" type="); pw.println(params.transportType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,7 +69,6 @@ import android.os.BatteryStats;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.INetworkActivityListener;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallbackList;
|
||||
@@ -80,7 +79,6 @@ import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.telephony.DataConnectionRealTimeInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -229,32 +227,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
|
||||
@GuardedBy("mQuotaLock")
|
||||
private volatile boolean mDataSaverMode;
|
||||
|
||||
private final Object mIdleTimerLock = new Object();
|
||||
/** Set of interfaces with active idle timers. */
|
||||
private static class IdleTimerParams {
|
||||
public final int timeout;
|
||||
public final int type;
|
||||
public int networkCount;
|
||||
|
||||
IdleTimerParams(int timeout, int type) {
|
||||
this.timeout = timeout;
|
||||
this.type = type;
|
||||
this.networkCount = 1;
|
||||
}
|
||||
}
|
||||
private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
|
||||
|
||||
private volatile boolean mFirewallEnabled;
|
||||
private volatile boolean mStrictEnabled;
|
||||
|
||||
private boolean mMobileActivityFromRadio = false;
|
||||
private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
|
||||
private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
|
||||
|
||||
private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
|
||||
new RemoteCallbackList<>();
|
||||
private boolean mNetworkActive;
|
||||
|
||||
/**
|
||||
* Constructs a new NetworkManagementService instance
|
||||
*
|
||||
@@ -397,55 +372,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
|
||||
*/
|
||||
private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
|
||||
int uid) {
|
||||
final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
|
||||
int powerState = isActive
|
||||
? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
|
||||
: DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
|
||||
if (isMobile) {
|
||||
if (mLastPowerStateFromRadio != powerState) {
|
||||
mLastPowerStateFromRadio = powerState;
|
||||
try {
|
||||
// TODO: The interface changes that comes from netd are handled by BSS itself.
|
||||
// There are still events caused by setting or removing idle timer, so keep
|
||||
// reporting from here until setting idler timer moved to CS.
|
||||
getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectivityManager.isNetworkTypeWifi(type)) {
|
||||
if (mLastPowerStateFromWifi != powerState) {
|
||||
mLastPowerStateFromWifi = powerState;
|
||||
try {
|
||||
// TODO: The interface changes that comes from netd are handled by BSS itself.
|
||||
// There are still events caused by setting or removing idle timer, so keep
|
||||
// reporting from here until setting idler timer moved to CS.
|
||||
getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean active = isActive;
|
||||
invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
|
||||
type, active, tsNanos, uid));
|
||||
|
||||
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();
|
||||
}
|
||||
type, isActive, tsNanos, uid));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1121,60 +1049,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdleTimer(String iface, int timeout, final int type) {
|
||||
NetworkStack.checkNetworkStackPermission(mContext);
|
||||
|
||||
if (DBG) Slog.d(TAG, "Adding idletimer");
|
||||
|
||||
synchronized (mIdleTimerLock) {
|
||||
IdleTimerParams params = mActiveIdleTimers.get(iface);
|
||||
if (params != null) {
|
||||
// the interface already has idletimer, update network count
|
||||
params.networkCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
|
||||
|
||||
// Networks start up.
|
||||
if (ConnectivityManager.isNetworkTypeMobile(type)) {
|
||||
mNetworkActive = false;
|
||||
}
|
||||
mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
|
||||
SystemClock.elapsedRealtimeNanos(), -1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIdleTimer(String iface) {
|
||||
NetworkStack.checkNetworkStackPermission(mContext);
|
||||
|
||||
if (DBG) Slog.d(TAG, "Removing idletimer");
|
||||
|
||||
synchronized (mIdleTimerLock) {
|
||||
final IdleTimerParams params = mActiveIdleTimers.get(iface);
|
||||
if (params == null || --(params.networkCount) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mNetdService.idletimerRemoveInterface(iface,
|
||||
params.timeout, Integer.toString(params.type));
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
mActiveIdleTimers.remove(iface);
|
||||
mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
|
||||
SystemClock.elapsedRealtimeNanos(), -1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterfaceQuota(String iface, long quotaBytes) {
|
||||
NetworkStack.checkNetworkStackPermission(mContext);
|
||||
@@ -1812,45 +1686,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNetworkActivityListener(INetworkActivityListener listener) {
|
||||
mNetworkActivityListeners.register(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
|
||||
mNetworkActivityListeners.unregister(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkActive() {
|
||||
synchronized (mNetworkActivityListeners) {
|
||||
return mNetworkActive || mActiveIdleTimers.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private void reportNetworkActive() {
|
||||
final int length = mNetworkActivityListeners.beginBroadcast();
|
||||
try {
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mNetworkActivityListeners.finishBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
||||
|
||||
pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
|
||||
pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
|
||||
pw.print("mNetworkActive="); pw.println(mNetworkActive);
|
||||
|
||||
synchronized (mQuotaLock) {
|
||||
pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
|
||||
pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
|
||||
@@ -1882,17 +1721,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
|
||||
mUidFirewallRestrictedRules);
|
||||
}
|
||||
|
||||
synchronized (mIdleTimerLock) {
|
||||
pw.println("Idle timers:");
|
||||
for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
|
||||
pw.print(" "); pw.print(ent.getKey()); pw.println(":");
|
||||
IdleTimerParams params = ent.getValue();
|
||||
pw.print(" timeout="); pw.print(params.timeout);
|
||||
pw.print(" type="); pw.print(params.type);
|
||||
pw.print(" networkCount="); pw.println(params.networkCount);
|
||||
}
|
||||
}
|
||||
|
||||
pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
|
||||
pw.print("Netd service status: " );
|
||||
if (mNetdService == null) {
|
||||
|
||||
@@ -8222,8 +8222,8 @@ public class ConnectivityServiceTest {
|
||||
reset(mNetworkManagementService);
|
||||
mCellNetworkAgent.connect(true);
|
||||
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(NetworkCapabilities.TRANSPORT_CELLULAR));
|
||||
verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_CELLULAR)));
|
||||
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||
final LinkProperties wifiLp = new LinkProperties();
|
||||
@@ -8231,25 +8231,27 @@ public class ConnectivityServiceTest {
|
||||
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
|
||||
|
||||
// Network switch
|
||||
reset(mNetworkManagementService);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
|
||||
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
|
||||
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
|
||||
eq(NetworkCapabilities.TRANSPORT_WIFI));
|
||||
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
|
||||
verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_WIFI)));
|
||||
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_CELLULAR)));
|
||||
|
||||
// Disconnect wifi and switch back to cell
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockNetd);
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||
assertNoCallbacks(networkCallback);
|
||||
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
|
||||
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(NetworkCapabilities.TRANSPORT_CELLULAR));
|
||||
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_WIFI)));
|
||||
verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_CELLULAR)));
|
||||
|
||||
// reconnect wifi
|
||||
reset(mMockNetd);
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||
wifiLp.setInterfaceName(WIFI_IFNAME);
|
||||
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
|
||||
@@ -8257,9 +8259,12 @@ public class ConnectivityServiceTest {
|
||||
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
|
||||
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
|
||||
verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_WIFI)));
|
||||
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_CELLULAR)));
|
||||
|
||||
// Disconnect cell
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockNetd);
|
||||
mCellNetworkAgent.disconnect();
|
||||
networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||
@@ -8267,17 +8272,18 @@ public class ConnectivityServiceTest {
|
||||
// sent as network being switched. Ensure rule removal for cell will not be triggered
|
||||
// unexpectedly before network being removed.
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
|
||||
verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_CELLULAR)));
|
||||
verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
|
||||
verify(mMockDnsResolver, times(1))
|
||||
.destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
|
||||
|
||||
// Disconnect wifi
|
||||
ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
|
||||
reset(mNetworkManagementService);
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
b.expectBroadcast();
|
||||
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
|
||||
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
|
||||
eq(Integer.toString(TRANSPORT_WIFI)));
|
||||
|
||||
// Clean up
|
||||
mCm.unregisterNetworkCallback(networkCallback);
|
||||
|
||||
Reference in New Issue
Block a user