Merge "Add an API to listen for changes in network blocked status of an uid." into sc-dev

This commit is contained in:
Remi NGUYEN VAN
2021-03-18 08:50:24 +00:00
committed by Android (Google) Code Review
6 changed files with 607 additions and 180 deletions

View File

@@ -191,6 +191,25 @@ package android.net {
method public int getResourceId(); method public int getResourceId();
} }
public class NetworkPolicyManager {
method @NonNull public static String blockedReasonsToString(int);
method public static boolean isUidBlocked(int, boolean);
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
field public static final int BLOCKED_REASON_NONE = 0; // 0x0
field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
}
public static interface NetworkPolicyManager.NetworkPolicyCallback {
method public default void onUidBlockedReasonChanged(int, int);
}
public final class NetworkStateSnapshot implements android.os.Parcelable { public final class NetworkStateSnapshot implements android.os.Parcelable {
ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int); ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
method public int describeContents(); method public int describeContents();

View File

@@ -25,4 +25,5 @@ oneway interface INetworkPolicyListener {
void onUidPoliciesChanged(int uid, int uidPolicies); void onUidPoliciesChanged(int uid, int uidPolicies);
void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, in int[] networkTypes); void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, in int[] networkTypes);
void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans); void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans);
void onBlockedReasonChanged(int uid, int oldBlockedReason, int newBlockedReason);
} }

View File

@@ -23,6 +23,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService; import android.annotation.SystemService;
import android.annotation.TestApi; import android.annotation.TestApi;
import android.app.ActivityManager; import android.app.ActivityManager;
@@ -44,6 +45,8 @@ import android.util.DebugUtils;
import android.util.Pair; import android.util.Pair;
import android.util.Range; import android.util.Range;
import com.android.internal.util.function.pooled.PooledLambda;
import com.google.android.collect.Sets; import com.google.android.collect.Sets;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -53,6 +56,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
/** /**
* Manager for creating and modifying network policy rules. * Manager for creating and modifying network policy rules.
@@ -60,6 +64,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @hide * @hide
*/ */
@TestApi @TestApi
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@SystemService(Context.NETWORK_POLICY_SERVICE) @SystemService(Context.NETWORK_POLICY_SERVICE)
public class NetworkPolicyManager { public class NetworkPolicyManager {
@@ -198,12 +203,157 @@ public class NetworkPolicyManager {
}) })
public @interface SubscriptionOverrideMask {} public @interface SubscriptionOverrideMask {}
/**
* Flag to indicate that an app is not subject to any restrictions that could result in its
* network access blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_REASON_NONE = 0;
/**
* Flag to indicate that an app is subject to Battery saver restrictions that would
* result in its network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
/**
* Flag to indicate that an app is subject to Doze restrictions that would
* result in its network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_REASON_DOZE = 1 << 1;
/**
* Flag to indicate that an app is subject to App Standby restrictions that would
* result in its network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
/**
* Flag to indicate that an app is subject to Restricted mode restrictions that would
* result in its network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
/**
* Flag to indicate that an app is subject to Data saver restrictions that would
* result in its metered network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
/**
* Flag to indicate that an app is subject to user restrictions that would
* result in its metered network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
/**
* Flag to indicate that an app is subject to Device admin restrictions that would
* result in its metered network access being blocked.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
/** @hide */
public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
/**
* Flag to indicate that app is not exempt from any network restrictions.
*
* @hide
*/
public static final int ALLOWED_REASON_NONE = 0;
/**
* Flag to indicate that app is exempt from certain network restrictions because of it being a
* system component.
*
* @hide
*/
public static final int ALLOWED_REASON_SYSTEM = 1 << 0;
/**
* Flag to indicate that app is exempt from certain network restrictions because of it being
* in the foreground.
*
* @hide
*/
public static final int ALLOWED_REASON_FOREGROUND = 1 << 1;
/**
* Flag to indicate that app is exempt from certain network restrictions because of it being
* in the {@code allow-in-power-save} list.
*
* @hide
*/
public static final int ALLOWED_REASON_POWER_SAVE_ALLOWLIST = 1 << 2;
/**
* Flag to indicate that app is exempt from certain network restrictions because of it being
* in the {@code allow-in-power-save-except-idle} list.
*
* @hide
*/
public static final int ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST = 1 << 3;
/**
* Flag to indicate that app is exempt from certain network restrictions because of it holding
* certain privileged permissions.
*
* @hide
*/
public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4;
/**
* Flag to indicate that app is exempt from certain metered network restrictions because user
* explicitly exempted it.
*
* @hide
*/
public static final int ALLOWED_METERED_REASON_USER_EXEMPTED = 1 << 16;
/** @hide */
public static final int ALLOWED_METERED_REASON_MASK = 0xffff0000;
/**
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
BLOCKED_REASON_NONE,
BLOCKED_REASON_BATTERY_SAVER,
BLOCKED_REASON_DOZE,
BLOCKED_REASON_APP_STANDBY,
BLOCKED_REASON_RESTRICTED_MODE,
BLOCKED_METERED_REASON_DATA_SAVER,
BLOCKED_METERED_REASON_USER_RESTRICTED,
BLOCKED_METERED_REASON_ADMIN_DISABLED,
})
public @interface BlockedReason {}
private final Context mContext; private final Context mContext;
@UnsupportedAppUsage @UnsupportedAppUsage
private INetworkPolicyManager mService; private INetworkPolicyManager mService;
private final Map<SubscriptionCallback, SubscriptionCallbackProxy> private final Map<SubscriptionCallback, SubscriptionCallbackProxy>
mCallbackMap = new ConcurrentHashMap<>(); mSubscriptionCallbackMap = new ConcurrentHashMap<>();
private final Map<NetworkPolicyCallback, NetworkPolicyCallbackProxy>
mNetworkPolicyCallbackMap = new ConcurrentHashMap<>();
/** @hide */ /** @hide */
public NetworkPolicyManager(Context context, INetworkPolicyManager service) { public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
@@ -318,7 +468,7 @@ public class NetworkPolicyManager {
} }
final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback); final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback);
if (null != mCallbackMap.putIfAbsent(callback, callbackProxy)) { if (null != mSubscriptionCallbackMap.putIfAbsent(callback, callbackProxy)) {
throw new IllegalArgumentException("Callback is already registered."); throw new IllegalArgumentException("Callback is already registered.");
} }
registerListener(callbackProxy); registerListener(callbackProxy);
@@ -331,7 +481,7 @@ public class NetworkPolicyManager {
throw new NullPointerException("Callback cannot be null."); throw new NullPointerException("Callback cannot be null.");
} }
final SubscriptionCallbackProxy callbackProxy = mCallbackMap.remove(callback); final SubscriptionCallbackProxy callbackProxy = mSubscriptionCallbackMap.remove(callback);
if (callbackProxy == null) return; if (callbackProxy == null) return;
unregisterListener(callbackProxy); unregisterListener(callbackProxy);
@@ -689,6 +839,142 @@ public class NetworkPolicyManager {
return WifiInfo.sanitizeSsid(ssid); return WifiInfo.sanitizeSsid(ssid);
} }
/**
* Returns whether network access of an UID is blocked or not based on {@code blockedReasons}
* corresponding to it.
*
* {@code blockedReasons} would be a bitwise {@code OR} combination of the
* {@code BLOCKED_REASON_*} and/or {@code BLOCKED_METERED_REASON_*} constants.
*
* @param blockedReasons Value indicating the reasons for why the network access of an UID is
* blocked. If the value is equal to {@link #BLOCKED_REASON_NONE}, then
* it indicates that an app's network access is not blocked.
* @param meteredNetwork Value indicating whether the network is metered or not.
* @return Whether network access is blocked or not.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static boolean isUidBlocked(@BlockedReason int blockedReasons, boolean meteredNetwork) {
if (blockedReasons == BLOCKED_REASON_NONE) {
return false;
}
final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK);
if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) {
return true;
}
if (meteredNetwork) {
return blockedReasons != BLOCKED_REASON_NONE;
}
return false;
}
/**
* Returns the {@code string} representation of {@code blockedReasons} argument.
*
* @param blockedReasons Value indicating the reasons for why the network access of an UID is
* blocked.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
public static String blockedReasonsToString(@BlockedReason int blockedReasons) {
return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
}
/**
* Register a {@link NetworkPolicyCallback} to listen for changes to network blocked status
* of apps.
*
* Note that when a caller tries to register a new callback, it might replace a previously
* registered callback if it is considered equal to the new one, based on the
* {@link Object#equals(Object)} check.
*
* @param executor The {@link Executor} to run the callback on.
* @param callback The {@link NetworkPolicyCallback} to be registered.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
public void registerNetworkPolicyCallback(@Nullable Executor executor,
@NonNull NetworkPolicyCallback callback) {
if (callback == null) {
throw new NullPointerException("Callback cannot be null.");
}
final NetworkPolicyCallbackProxy callbackProxy = new NetworkPolicyCallbackProxy(
executor, callback);
registerListener(callbackProxy);
mNetworkPolicyCallbackMap.put(callback, callbackProxy);
}
/**
* Unregister a previously registered {@link NetworkPolicyCallback}.
*
* @param callback The {@link NetworkPolicyCallback} to be unregistered.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
public void unregisterNetworkPolicyCallback(@NonNull NetworkPolicyCallback callback) {
if (callback == null) {
throw new NullPointerException("Callback cannot be null.");
}
final NetworkPolicyCallbackProxy callbackProxy = mNetworkPolicyCallbackMap.remove(callback);
if (callbackProxy == null) return;
unregisterListener(callbackProxy);
}
/**
* Interface for the callback to listen for changes to network blocked status of apps.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public interface NetworkPolicyCallback {
/**
* Called when the reason for why the network access of an UID is blocked changes.
*
* @param uid The UID for which the blocked status changed.
* @param blockedReasons Value indicating the reasons for why the network access of an
* UID is blocked.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
default void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {}
}
/** @hide */
public static class NetworkPolicyCallbackProxy extends Listener {
private final Executor mExecutor;
private final NetworkPolicyCallback mCallback;
NetworkPolicyCallbackProxy(@Nullable Executor executor,
@NonNull NetworkPolicyCallback callback) {
mExecutor = executor;
mCallback = callback;
}
@Override
public void onBlockedReasonChanged(int uid, @BlockedReason int oldBlockedReasons,
@BlockedReason int newBlockedReasons) {
if (oldBlockedReasons != newBlockedReasons) {
dispatchOnUidBlockedReasonChanged(mExecutor, mCallback, uid, newBlockedReasons);
}
}
}
private static void dispatchOnUidBlockedReasonChanged(@Nullable Executor executor,
@NonNull NetworkPolicyCallback callback, int uid, @BlockedReason int blockedReasons) {
if (executor == null) {
callback.onUidBlockedReasonChanged(uid, blockedReasons);
} else {
executor.execute(PooledLambda.obtainRunnable(
NetworkPolicyCallback::onUidBlockedReasonChanged,
callback, uid, blockedReasons).recycleOnUse());
}
}
/** @hide */ /** @hide */
public static class SubscriptionCallback { public static class SubscriptionCallback {
/** /**
@@ -743,5 +1029,7 @@ public class NetworkPolicyManager {
@Override public void onSubscriptionOverride(int subId, int overrideMask, @Override public void onSubscriptionOverride(int subId, int overrideMask,
int overrideValue, int[] networkTypes) { } int overrideValue, int[] networkTypes) { }
@Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { } @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { }
@Override public void onBlockedReasonChanged(int uid,
int oldBlockedReasons, int newBlockedReasons) { }
} }
} }

View File

@@ -72,8 +72,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST; import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkPolicyManager.RULE_NONE; import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkPolicyManager.blockedReasonsToString;
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired; import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
import static android.os.Process.INVALID_UID; import static android.os.Process.INVALID_UID;
@@ -117,7 +117,6 @@ import android.net.INetd;
import android.net.INetworkActivityListener; import android.net.INetworkActivityListener;
import android.net.INetworkMonitor; import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks; import android.net.INetworkMonitorCallbacks;
import android.net.INetworkPolicyListener;
import android.net.IOnCompleteListener; import android.net.IOnCompleteListener;
import android.net.IQosCallback; import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback; import android.net.ISocketKeepaliveCallback;
@@ -135,6 +134,7 @@ import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMonitorManager; import android.net.NetworkMonitorManager;
import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager;
import android.net.NetworkPolicyManager.NetworkPolicyCallback;
import android.net.NetworkProvider; import android.net.NetworkProvider;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.NetworkScore; import android.net.NetworkScore;
@@ -331,12 +331,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
private volatile boolean mLockdownEnabled; private volatile boolean mLockdownEnabled;
/** /**
* Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
* handler thread, they don't need a lock. * internal handler thread, they don't need a lock.
*/ */
private SparseIntArray mUidRules = new SparseIntArray(); private SparseIntArray mUidBlockedReasons = new SparseIntArray();
/** Flag indicating if background data is restricted. */
private boolean mRestrictBackground;
private final Context mContext; private final Context mContext;
private final ConnectivityResources mResources; private final ConnectivityResources mResources;
@@ -510,16 +508,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Handle private DNS validation status updates. // Handle private DNS validation status updates.
private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
/**
* Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
*/
private static final int EVENT_UID_RULES_CHANGED = 39;
/**
* Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
*/
private static final int EVENT_DATA_SAVER_CHANGED = 40;
/** /**
* Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
* been tested. * been tested.
@@ -595,6 +583,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/ */
private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50; private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
/**
* Event to specify that reasons for why an uid is blocked changed.
* arg1 = uid
* arg2 = blockedReasons
*/
private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
/** /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown. * should be shown.
@@ -1253,10 +1248,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = new LocationPermissionChecker(mContext); mLocationPermissionChecker = new LocationPermissionChecker(mContext);
// To ensure uid rules are synchronized with Network Policy, register for // To ensure uid state is synchronized with Network Policy, register for
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
// reading existing policy from disk. // reading existing policy from disk.
mPolicyManager.registerListener(mPolicyListener); mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
final PowerManager powerManager = (PowerManager) context.getSystemService( final PowerManager powerManager = (PowerManager) context.getSystemService(
Context.POWER_SERVICE); Context.POWER_SERVICE);
@@ -2237,53 +2232,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() { private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
@Override @Override
public void onUidRulesChanged(int uid, int uidRules) { public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
} uid, blockedReasons));
@Override
public void onRestrictBackgroundChanged(boolean restrictBackground) {
// caller is NPMS, since we only register with them
if (LOGD_BLOCKED_NETWORKINFO) {
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
}
mHandler.sendMessage(mHandler.obtainMessage(
EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
} }
}; };
void handleUidRulesChanged(int uid, int newRules) { void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
// skip update when we've already applied rules maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
final int oldRules = mUidRules.get(uid, RULE_NONE); mUidBlockedReasons.put(uid, blockedReasons);
if (oldRules == newRules) return;
maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
if (newRules == RULE_NONE) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, newRules);
}
}
void handleRestrictBackgroundChanged(boolean restrictBackground) {
if (mRestrictBackground == restrictBackground) return;
final List<UidRange> blockedRanges = mVpnBlockedUidRanges;
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean curMetered = nai.networkCapabilities.isMetered();
maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
restrictBackground, blockedRanges, blockedRanges);
}
mRestrictBackground = restrictBackground;
}
private boolean isUidBlockedByRules(int uid, int uidRules, boolean isNetworkMetered,
boolean isBackgroundRestricted) {
return mPolicyManager.checkUidNetworkingBlocked(uid, uidRules, isNetworkMetered,
isBackgroundRestricted);
} }
private boolean checkAnyPermissionOf(String... permissions) { private boolean checkAnyPermissionOf(String... permissions) {
@@ -2757,19 +2716,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.decreaseIndent(); pw.decreaseIndent();
pw.println(); pw.println();
pw.print("Restrict background: ");
pw.println(mRestrictBackground);
pw.println();
pw.println("Status for known UIDs:"); pw.println("Status for known UIDs:");
pw.increaseIndent(); pw.increaseIndent();
final int size = mUidRules.size(); final int size = mUidBlockedReasons.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
// Don't crash if the array is modified while dumping in bugreports. // Don't crash if the array is modified while dumping in bugreports.
try { try {
final int uid = mUidRules.keyAt(i); final int uid = mUidBlockedReasons.keyAt(i);
final int uidRules = mUidRules.get(uid, RULE_NONE); final int blockedReasons = mUidBlockedReasons.valueAt(i);
pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules)); pw.println("UID=" + uid + " blockedReasons="
+ blockedReasonsToString(blockedReasons));
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
pw.println(" ArrayIndexOutOfBoundsException"); pw.println(" ArrayIndexOutOfBoundsException");
} catch (ConcurrentModificationException e) { } catch (ConcurrentModificationException e) {
@@ -4565,11 +4521,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
handlePrivateDnsValidationUpdate( handlePrivateDnsValidationUpdate(
(PrivateDnsValidationUpdate) msg.obj); (PrivateDnsValidationUpdate) msg.obj);
break; break;
case EVENT_UID_RULES_CHANGED: case EVENT_UID_BLOCKED_REASON_CHANGED:
handleUidRulesChanged(msg.arg1, msg.arg2); handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
break;
case EVENT_DATA_SAVER_CHANGED:
handleRestrictBackgroundChanged(toBool(msg.arg1));
break; break;
case EVENT_SET_REQUIRE_VPN_FOR_UIDS: case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
@@ -5042,8 +4995,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (final NetworkAgentInfo nai : mNetworkAgentInfos) { for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean curMetered = nai.networkCapabilities.isMetered(); final boolean curMetered = nai.networkCapabilities.isMetered();
maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground, maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
mRestrictBackground, mVpnBlockedUidRanges, newVpnBlockedUidRanges); mVpnBlockedUidRanges, newVpnBlockedUidRanges);
} }
mVpnBlockedUidRanges = newVpnBlockedUidRanges; mVpnBlockedUidRanges = newVpnBlockedUidRanges;
@@ -6826,8 +6779,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean meteredChanged = oldMetered != newMetered; final boolean meteredChanged = oldMetered != newMetered;
if (meteredChanged) { if (meteredChanged) {
maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground, maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
mRestrictBackground, mVpnBlockedUidRanges, mVpnBlockedUidRanges); mVpnBlockedUidRanges, mVpnBlockedUidRanges);
} }
final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
@@ -7950,8 +7903,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean metered = nai.networkCapabilities.isMetered(); final boolean metered = nai.networkCapabilities.isMetered();
boolean blocked; boolean blocked;
blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges); blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges);
blocked |= isUidBlockedByRules(nri.mUid, mUidRules.get(nri.mUid), blocked |= NetworkPolicyManager.isUidBlocked(
metered, mRestrictBackground); mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE), metered);
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0); callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
} }
@@ -7969,16 +7922,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
* *
* @param nai The target NetworkAgentInfo. * @param nai The target NetworkAgentInfo.
* @param oldMetered True if the previous network capabilities is metered. * @param oldMetered True if the previous network capabilities is metered.
* @param newRestrictBackground True if data saver is enabled.
*/ */
private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground, boolean newMetered, List<UidRange> oldBlockedUidRanges,
List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges) { List<UidRange> newBlockedUidRanges) {
for (int i = 0; i < nai.numNetworkRequests(); i++) { for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest nr = nai.requestAt(i); NetworkRequest nr = nai.requestAt(i);
NetworkRequestInfo nri = mNetworkRequests.get(nr); NetworkRequestInfo nri = mNetworkRequests.get(nr);
final int uidRules = mUidRules.get(nri.mUid);
final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked; final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;
oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges); oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges);
@@ -7986,10 +7937,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges) ? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges)
: oldVpnBlocked; : oldVpnBlocked;
oldBlocked = oldVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, oldMetered, final int blockedReasons = mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE);
oldRestrictBackground); oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
newBlocked = newVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, newMetered, blockedReasons, oldMetered);
newRestrictBackground); newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
blockedReasons, newMetered);
if (oldBlocked != newBlocked) { if (oldBlocked != newBlocked) {
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
@@ -7999,19 +7951,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
/** /**
* Notify apps with a given UID of the new blocked state according to new uid rules. * Notify apps with a given UID of the new blocked state according to new uid state.
* @param uid The uid for which the rules changed. * @param uid The uid for which the rules changed.
* @param newRules The new rules to apply. * @param blockedReasons The reasons for why an uid is blocked.
*/ */
private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) { private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
for (final NetworkAgentInfo nai : mNetworkAgentInfos) { for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean metered = nai.networkCapabilities.isMetered(); final boolean metered = nai.networkCapabilities.isMetered();
final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
final boolean oldBlocked, newBlocked; final boolean oldBlocked, newBlocked;
oldBlocked = vpnBlocked || isUidBlockedByRules(
uid, mUidRules.get(uid), metered, mRestrictBackground); oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
newBlocked = vpnBlocked || isUidBlockedByRules( mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
uid, newRules, metered, mRestrictBackground); newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
blockedReasons, metered);
if (oldBlocked == newBlocked) { if (oldBlocked == newBlocked) {
continue; continue;
} }

View File

@@ -58,6 +58,23 @@ import static android.net.NetworkIdentity.OEM_NONE;
import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED;
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
import static android.net.NetworkPolicyManager.BLOCKED_REASON_APP_STANDBY;
import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
import static android.net.NetworkPolicyManager.BLOCKED_REASON_DOZE;
import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.NetworkPolicyManager.BLOCKED_REASON_RESTRICTED_MODE;
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
@@ -413,6 +430,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18; private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19; private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20; private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20;
// TODO: Add similar docs for other messages.
/**
* Message to indicate that reasons for why an uid is blocked changed.
* arg1 = uid
* arg2 = oldBlockedReasons
* obj = newBlockedReasons
*/
private static final int MSG_BLOCKED_REASON_CHANGED = 21;
private static final int UID_MSG_STATE_CHANGED = 100; private static final int UID_MSG_STATE_CHANGED = 100;
private static final int UID_MSG_GONE = 101; private static final int UID_MSG_GONE = 101;
@@ -559,7 +584,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Foreground at UID granularity. */ /** Foreground at UID granularity. */
@GuardedBy("mUidRulesFirstLock") @GuardedBy("mUidRulesFirstLock")
final SparseArray<UidState> mUidState = new SparseArray<UidState>(); private final SparseArray<UidState> mUidState = new SparseArray<>();
@GuardedBy("mUidRulesFirstLock")
private final SparseArray<UidBlockedState> mUidBlockedState = new SparseArray<>();
/** Map from network ID to last observed meteredness state */ /** Map from network ID to last observed meteredness state */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
@@ -2876,15 +2904,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
@Override @Override
public void registerListener(INetworkPolicyListener listener) { public void registerListener(@NonNull INetworkPolicyListener listener) {
Objects.requireNonNull(listener);
// TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
// have declared OBSERVE_NETWORK_POLICY. // have declared OBSERVE_NETWORK_POLICY.
enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY); enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
mListeners.register(listener); mListeners.register(listener);
// TODO: Send callbacks to the newly registered listener
} }
@Override @Override
public void unregisterListener(INetworkPolicyListener listener) { public void unregisterListener(@NonNull INetworkPolicyListener listener) {
Objects.requireNonNull(listener);
// TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
// have declared OBSERVE_NETWORK_POLICY. // have declared OBSERVE_NETWORK_POLICY.
enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY); enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
@@ -3921,6 +3952,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mUidRules.put(uid, newUidRule); mUidRules.put(uid, newUidRule);
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget(); mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
} }
updateBlockedReasonsForRestrictedModeUL(uid);
}); });
if (mRestrictedNetworkingMode) { if (mRestrictedNetworkingMode) {
// firewall rules only need to be set when this mode is being enabled. // firewall rules only need to be set when this mode is being enabled.
@@ -3941,6 +3973,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mUidRules.put(uid, newUidRule); mUidRules.put(uid, newUidRule);
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget(); mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
} }
updateBlockedReasonsForRestrictedModeUL(uid);
// if restricted networking mode is on, and the app has an access exemption, the uid rule // if restricted networking mode is on, and the app has an access exemption, the uid rule
// will not change, but the firewall rule will have to be updated. // will not change, but the firewall rule will have to be updated.
@@ -3952,6 +3985,31 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
} }
private void updateBlockedReasonsForRestrictedModeUL(int uid) {
UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
if (uidBlockedState == null) {
uidBlockedState = new UidBlockedState();
mUidBlockedState.put(uid, uidBlockedState);
}
final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
if (mRestrictedNetworkingMode) {
uidBlockedState.blockedReasons |= BLOCKED_REASON_RESTRICTED_MODE;
} else {
uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
}
if (hasRestrictedModeAccess(uid)) {
uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
} else {
uidBlockedState.allowedReasons &= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
}
uidBlockedState.updateEffectiveBlockedReasons();
if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
.sendToTarget();
}
}
private int getNewRestrictedModeUidRule(int uid, int oldUidRule) { private int getNewRestrictedModeUidRule(int uid, int oldUidRule) {
int newRule = oldUidRule; int newRule = oldUidRule;
newRule &= ~MASK_RESTRICTED_MODE_NETWORKS; newRule &= ~MASK_RESTRICTED_MODE_NETWORKS;
@@ -4072,11 +4130,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
|| mPowerSaveWhitelistAppIds.get(appId); || mPowerSaveWhitelistAppIds.get(appId);
if (!deviceIdleMode) { if (!deviceIdleMode) {
isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId); isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid);
} }
return isWhitelisted; return isWhitelisted;
} }
/**
* Returns whether a uid is allowlisted from power saving restrictions, except Device idle
* (eg: Battery Saver and app idle).
*/
@GuardedBy("mUidRulesFirstLock")
private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) {
final int appId = UserHandle.getAppId(uid);
return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
}
// NOTE: since both fw_dozable and fw_powersave uses the same map // NOTE: since both fw_dozable and fw_powersave uses the same map
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method. // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
@GuardedBy("mUidRulesFirstLock") @GuardedBy("mUidRulesFirstLock")
@@ -4521,6 +4589,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int oldUidRules = mUidRules.get(uid, RULE_NONE); final int oldUidRules = mUidRules.get(uid, RULE_NONE);
final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid); final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid); final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
if (uidBlockedState == null) {
uidBlockedState = new UidBlockedState();
mUidBlockedState.put(uid, uidBlockedState);
}
final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
@@ -4545,6 +4618,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
} }
int newBlockedReasons = BLOCKED_REASON_NONE;
int newAllowedReasons = ALLOWED_REASON_NONE;
newBlockedReasons |= (isRestrictedByAdmin ? BLOCKED_METERED_REASON_ADMIN_DISABLED : 0);
newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0);
newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0);
newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0);
if (LOGV) { if (LOGV) {
Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")" Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
+ ": isForeground=" +isForeground + ": isForeground=" +isForeground
@@ -4616,6 +4699,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// Dispatch changed rule to existing listeners. // Dispatch changed rule to existing listeners.
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
& ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
& ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
uidBlockedState.updateEffectiveBlockedReasons();
if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
.sendToTarget();
}
} }
} }
@@ -4690,6 +4785,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// Copy existing uid rules and clear ALL_NETWORK rules. // Copy existing uid rules and clear ALL_NETWORK rules.
int newUidRules = oldUidRules & (~MASK_ALL_NETWORKS); int newUidRules = oldUidRules & (~MASK_ALL_NETWORKS);
UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
if (uidBlockedState == null) {
uidBlockedState = new UidBlockedState();
mUidBlockedState.put(uid, uidBlockedState);
}
// First step: define the new rule based on user restrictions and foreground state. // First step: define the new rule based on user restrictions and foreground state.
// NOTE: if statements below could be inlined, but it's easier to understand the logic // NOTE: if statements below could be inlined, but it's easier to understand the logic
@@ -4702,6 +4803,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
newUidRules |= isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL; newUidRules |= isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
} }
int newBlockedReasons = BLOCKED_REASON_NONE;
int newAllowedReasons = ALLOWED_REASON_NONE;
newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0);
newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0);
newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
if (LOGV) { if (LOGV) {
Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")" Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
+ ", isIdle: " + isUidIdle + ", isIdle: " + isUidIdle
@@ -4733,6 +4848,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
} }
final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
& BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
& ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
uidBlockedState.updateEffectiveBlockedReasons();
if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
.sendToTarget();
}
return newUidRules; return newUidRules;
} }
@@ -4762,61 +4889,57 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
if (listener != null) { try {
try { listener.onUidRulesChanged(uid, uidRules);
listener.onUidRulesChanged(uid, uidRules); } catch (RemoteException ignored) {
} catch (RemoteException ignored) {
}
} }
} }
private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
String[] meteredIfaces) { String[] meteredIfaces) {
if (listener != null) { try {
try { listener.onMeteredIfacesChanged(meteredIfaces);
listener.onMeteredIfacesChanged(meteredIfaces); } catch (RemoteException ignored) {
} catch (RemoteException ignored) {
}
} }
} }
private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
boolean restrictBackground) { boolean restrictBackground) {
if (listener != null) { try {
try { listener.onRestrictBackgroundChanged(restrictBackground);
listener.onRestrictBackgroundChanged(restrictBackground); } catch (RemoteException ignored) {
} catch (RemoteException ignored) {
}
} }
} }
private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid, private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
int uidPolicies) { int uidPolicies) {
if (listener != null) { try {
try { listener.onUidPoliciesChanged(uid, uidPolicies);
listener.onUidPoliciesChanged(uid, uidPolicies); } catch (RemoteException ignored) {
} catch (RemoteException ignored) {
}
} }
} }
private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId, private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
int overrideMask, int overrideValue, int[] networkTypes) { int overrideMask, int overrideValue, int[] networkTypes) {
if (listener != null) { try {
try { listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes); } catch (RemoteException ignored) {
} catch (RemoteException ignored) {
}
} }
} }
private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId, private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
SubscriptionPlan[] plans) { SubscriptionPlan[] plans) {
if (listener != null) { try {
try { listener.onSubscriptionPlansChanged(subId, plans);
listener.onSubscriptionPlansChanged(subId, plans); } catch (RemoteException ignored) {
} catch (RemoteException ignored) { }
} }
private void dispatchBlockedReasonChanged(INetworkPolicyListener listener, int uid,
int oldBlockedReasons, int newBlockedReasons) {
try {
listener.onBlockedReasonChanged(uid, oldBlockedReasons, newBlockedReasons);
} catch (RemoteException ignored) {
} }
} }
@@ -4973,6 +5096,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mListeners.finishBroadcast(); mListeners.finishBroadcast();
return true; return true;
} }
case MSG_BLOCKED_REASON_CHANGED: {
final int uid = msg.arg1;
final int newBlockedReasons = msg.arg2;
final int oldBlockedReasons = (int) msg.obj;
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
dispatchBlockedReasonChanged(listener, uid,
oldBlockedReasons, newBlockedReasons);
}
mListeners.finishBroadcast();
return true;
}
default: { default: {
return false; return false;
} }
@@ -5704,6 +5840,51 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue; return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
} }
private class UidBlockedState {
public int blockedReasons;
public int allowedReasons;
public int effectiveBlockedReasons;
UidBlockedState() {
blockedReasons = BLOCKED_REASON_NONE;
allowedReasons = ALLOWED_REASON_NONE;
effectiveBlockedReasons = BLOCKED_REASON_NONE;
}
void updateEffectiveBlockedReasons() {
effectiveBlockedReasons = blockedReasons;
// If the uid is not subject to any blocked reasons, then return early
if (blockedReasons == BLOCKED_REASON_NONE) {
return;
}
if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
effectiveBlockedReasons = BLOCKED_REASON_NONE;
}
if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) {
effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
}
if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) {
effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
}
if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) {
effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
}
if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) {
effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
}
if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
}
}
}
private class NotificationId { private class NotificationId {
private final String mTag; private final String mTag;
private final int mId; private final int mId;

View File

@@ -87,10 +87,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
import static android.net.NetworkPolicyManager.RULE_NONE; import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -187,7 +187,6 @@ import android.net.IDnsResolver;
import android.net.INetd; import android.net.INetd;
import android.net.INetworkMonitor; import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks; import android.net.INetworkMonitorCallbacks;
import android.net.INetworkPolicyListener;
import android.net.IOnCompleteListener; import android.net.IOnCompleteListener;
import android.net.IQosCallback; import android.net.IQosCallback;
import android.net.InetAddresses; import android.net.InetAddresses;
@@ -206,6 +205,7 @@ import android.net.NetworkFactory;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager;
import android.net.NetworkPolicyManager.NetworkPolicyCallback;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.NetworkScore; import android.net.NetworkScore;
import android.net.NetworkSpecifier; import android.net.NetworkSpecifier;
@@ -422,7 +422,7 @@ public class ConnectivityServiceTest {
private TestNetworkAgentWrapper mEthernetNetworkAgent; private TestNetworkAgentWrapper mEthernetNetworkAgent;
private MockVpn mMockVpn; private MockVpn mMockVpn;
private Context mContext; private Context mContext;
private INetworkPolicyListener mPolicyListener; private NetworkPolicyCallback mPolicyCallback;
private WrappedMultinetworkPolicyTracker mPolicyTracker; private WrappedMultinetworkPolicyTracker mPolicyTracker;
private HandlerThread mAlarmManagerThread; private HandlerThread mAlarmManagerThread;
private TestNetIdManager mNetIdManager; private TestNetIdManager mNetIdManager;
@@ -434,8 +434,7 @@ public class ConnectivityServiceTest {
private TestNetworkCallback mProfileDefaultNetworkCallback; private TestNetworkCallback mProfileDefaultNetworkCallback;
// State variables required to emulate NetworkPolicyManagerService behaviour. // State variables required to emulate NetworkPolicyManagerService behaviour.
private int mUidRules = RULE_NONE; private int mBlockedReasons = BLOCKED_REASON_NONE;
private boolean mRestrictBackground = false;
@Mock DeviceIdleInternal mDeviceIdleInternal; @Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService; @Mock INetworkManagementService mNetworkManagementService;
@@ -1374,28 +1373,13 @@ public class ConnectivityServiceTest {
} }
private void mockUidNetworkingBlocked() { private void mockUidNetworkingBlocked() {
doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class) doAnswer(i -> NetworkPolicyManager.isUidBlocked(mBlockedReasons, i.getArgument(1))
.checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
i.getArgument(1) /* metered */, mRestrictBackground)
).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
doAnswer(inv -> mContext.getSystemService(NetworkPolicyManager.class)
.checkUidNetworkingBlocked(inv.getArgument(0) /* uid */,
inv.getArgument(1) /* uidRules */,
inv.getArgument(2) /* isNetworkMetered */,
inv.getArgument(3) /* isBackgroundRestricted */)
).when(mNetworkPolicyManager).checkUidNetworkingBlocked(
anyInt(), anyInt(), anyBoolean(), anyBoolean());
} }
private void setUidRulesChanged(int uidRules) throws RemoteException { private void setBlockedReasonChanged(int blockedReasons) {
mUidRules = uidRules; mBlockedReasons = blockedReasons;
mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules); mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons);
}
private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
mRestrictBackground = restrictBackground;
mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
} }
private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) {
@@ -1537,10 +1521,11 @@ public class ConnectivityServiceTest {
mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS;
verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any()); verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any());
final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor = final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor =
ArgumentCaptor.forClass(INetworkPolicyListener.class); ArgumentCaptor.forClass(NetworkPolicyCallback.class);
verify(mNetworkPolicyManager).registerListener(policyListenerCaptor.capture()); verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(),
mPolicyListener = policyListenerCaptor.getValue(); policyCallbackCaptor.capture());
mPolicyCallback = policyCallbackCaptor.getValue();
// Create local CM before sending system ready so that we can answer // Create local CM before sending system ready so that we can answer
// getSystemService() correctly. // getSystemService() correctly.
@@ -7263,7 +7248,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent); assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_ALL); setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork()); assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7271,17 +7256,17 @@ public class ConnectivityServiceTest {
assertExtraInfoFromCmBlocked(mCellNetworkAgent); assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// ConnectivityService should cache it not to invoke the callback again. // ConnectivityService should cache it not to invoke the callback again.
setUidRulesChanged(RULE_REJECT_METERED); setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
setUidRulesChanged(RULE_NONE); setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent); assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_METERED); setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork()); assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7306,33 +7291,33 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertExtraInfoFromCmBlocked(mCellNetworkAgent); assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setUidRulesChanged(RULE_ALLOW_METERED); setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent); assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_NONE); setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
// Restrict background data. Networking is not blocked because the network is unmetered. // Restrict background data. Networking is not blocked because the network is unmetered.
setRestrictBackgroundChanged(true); setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork()); assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertExtraInfoFromCmBlocked(mCellNetworkAgent); assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setRestrictBackgroundChanged(true); setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
setUidRulesChanged(RULE_ALLOW_METERED); setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent); assertExtraInfoFromCmPresent(mCellNetworkAgent);
setRestrictBackgroundChanged(false); setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7349,9 +7334,9 @@ public class ConnectivityServiceTest {
mockUidNetworkingBlocked(); mockUidNetworkingBlocked();
// No Networkcallbacks invoked before any network is active. // No Networkcallbacks invoked before any network is active.
setUidRulesChanged(RULE_REJECT_ALL); setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
setUidRulesChanged(RULE_NONE); setBlockedReasonChanged(BLOCKED_REASON_NONE);
setUidRulesChanged(RULE_REJECT_METERED); setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
defaultCallback.assertNoCallback(); defaultCallback.assertNoCallback();
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -7376,8 +7361,8 @@ public class ConnectivityServiceTest {
defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
// Verify there's no Networkcallbacks invoked after data saver on/off. // Verify there's no Networkcallbacks invoked after data saver on/off.
setRestrictBackgroundChanged(true); setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
setRestrictBackgroundChanged(false); setBlockedReasonChanged(BLOCKED_REASON_NONE);
defaultCallback.assertNoCallback(); defaultCallback.assertNoCallback();
mCellNetworkAgent.disconnect(); mCellNetworkAgent.disconnect();