Loading core/java/android/net/INetworkPolicyManager.aidl +0 −4 Original line number Diff line number Diff line Loading @@ -58,10 +58,6 @@ interface INetworkPolicyManager { /** Callback used to change internal state on tethering */ void onTetheringChanged(String iface, boolean tethering); /** Control which applications can be exempt from background data restrictions */ void addRestrictBackgroundWhitelistedUid(int uid); void removeRestrictBackgroundWhitelistedUid(int uid); int[] getRestrictBackgroundWhitelistedUids(); /** Gets the restrict background status based on the caller's UID: 1 - disabled 2 - whitelisted Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +52 −152 Original line number Diff line number Diff line Loading @@ -1769,16 +1769,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) { setUidPolicyUncheckedUL(uid, policy, persist); final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND; final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND; final boolean notifyApp; if (!isUidValidForWhitelistRules(uid)) { notifyApp = false; } else { final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted); final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted); notifyApp = wasBlocked != isBlocked; } if (isBlacklisted != wasBlacklisted) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED, uid, isBlacklisted ? 1 : 0).sendToTarget(); final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; // Checks if app was added or removed to the blacklist. if ((oldPolicy == POLICY_NONE && isBlacklisted) || (wasBlacklisted && policy == POLICY_NONE)) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null) .sendToTarget(); isBlacklisted ? 1 : 0, Boolean.valueOf(notifyApp)).sendToTarget(); } if (isWhitelisted != wasWhitelisted) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, isWhitelisted ? 1 : 0, Boolean.valueOf(notifyApp)).sendToTarget(); } } Loading Loading @@ -2065,61 +2074,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } /** * @deprecated - should use {@link #setUidPolicy(int, int)} directly. */ @Override @Deprecated public void addRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); final boolean oldStatus; final boolean needFirewallRules; int changed; synchronized (mUidRulesFirstLock) { final int oldUidPolicy = mUidPolicy.get(uid, POLICY_NONE); oldStatus = (oldUidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; if (oldStatus) { if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); return; } needFirewallRules = isUidValidForWhitelistRules(uid); Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); setUidPolicyUncheckedUL(uid, oldUidPolicy, POLICY_ALLOW_METERED_BACKGROUND, false); if (mDefaultRestrictBackgroundWhitelistUids.get(uid) && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { if (LOGD) Slog.d(TAG, "Removing uid " + uid + " from revoked restrict background whitelist"); mRestrictBackgroundWhitelistRevokedUids.delete(uid); } if (needFirewallRules) { // Only update firewall rules if necessary... updateRulesForDataUsageRestrictionsUL(uid); } // ...but always persists the whitelist request. synchronized (mNetworkPoliciesSecondLock) { writePolicyAL(); } changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; } mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, Boolean.TRUE).sendToTarget(); } /** * @deprecated - should use {@link #setUidPolicy(int, int)} directly. */ @Override @Deprecated public void removeRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); final boolean changed; synchronized (mUidRulesFirstLock) { changed = removeRestrictBackgroundWhitelistedUidUL(uid, false, true); } mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, Boolean.FALSE).sendToTarget(); } /** * Removes a uid from the restricted background whitelist, returning whether its current * {@link ConnectivityManager.RestrictBackgroundStatus} changed. Loading Loading @@ -2158,43 +2112,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return mRestrictBackground && needFirewallRules; } /** * @deprecated - should use {@link #getUidsWithPolicy(int)} instead, but first need to change * that method to use logical OR (|). */ @Override @Deprecated public int[] getRestrictBackgroundWhitelistedUids() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); int[] whitelist = null; synchronized (mUidRulesFirstLock) { // First calculate size int size = 0; int policySize = mUidPolicy.size(); for (int i = 0; i < policySize; i++) { if ((mUidPolicy.valueAt(i) & POLICY_ALLOW_METERED_BACKGROUND) != 0) { size ++; } } whitelist = new int[size]; // Then populate it. if (size > 0) { int index = 0; for (int i = 0; i < policySize; i++) { final int uid = mUidPolicy.keyAt(i); if ((mUidPolicy.valueAt(i) & POLICY_ALLOW_METERED_BACKGROUND) != 0) { whitelist[index++] = uid; } } } } if (LOGV) { Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " + Arrays.toString(whitelist)); } return whitelist; } @Override public int getRestrictBackgroundByCaller() { mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); Loading Loading @@ -2412,20 +2329,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } final int[] restrictBackgroundWhitelistUids = getRestrictBackgroundWhitelistedUids(); size = restrictBackgroundWhitelistUids.length; if (size > 0) { fout.println("Restrict background whitelist uids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(restrictBackgroundWhitelistUids[i]); fout.println(); } fout.decreaseIndent(); } size = mDefaultRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Default restrict background whitelist uids:"); Loading Loading @@ -3257,52 +3160,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return true; } case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: // - when an app is whitelisted // - when an app is blacklisted // // Whether the internal listeners (INetworkPolicyListener implementations) or // app broadcast receivers are notified depend on the following rules: // // - App receivers are only notified when the app status changed (msg.arg2 = 1) // - Listeners are only notified when app was whitelisted (msg.obj is not null), // since blacklist notifications are handled through MSG_RULES_CHANGED). final int uid = msg.arg1; final boolean changed = msg.arg2 == 1; final Boolean whitelisted = (Boolean) msg.obj; final boolean whitelisted = msg.arg2 == 1; final Boolean notifyApp = (Boolean) msg.obj; // First notify internal listeners... if (whitelisted != null) { final boolean whitelistedBool = whitelisted.booleanValue(); dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid, whitelistedBool); whitelisted); final int length = mListeners.beginBroadcast(); for (int i = 0; i < length; i++) { final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); dispatchRestrictBackgroundWhitelistChanged(listener, uid, whitelistedBool); dispatchRestrictBackgroundWhitelistChanged(listener, uid, whitelisted); } mListeners.finishBroadcast(); } final PackageManager pm = mContext.getPackageManager(); final String[] packages = pm.getPackagesForUid(uid); if (changed && packages != null) { // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final Intent intent = new Intent( ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); intent.setPackage(packageName); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); } // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED if (notifyApp.booleanValue()) { broadcastRestrictBackgroundChanged(uid, notifyApp); } return true; } case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: { final int uid = msg.arg1; final boolean blacklisted = msg.arg2 == 1; final Boolean notifyApp = (Boolean) msg.obj; // First notify internal listeners... dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid, blacklisted); final int length = mListeners.beginBroadcast(); Loading @@ -3312,6 +3192,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { blacklisted); } mListeners.finishBroadcast(); // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED if (notifyApp.booleanValue()) { broadcastRestrictBackgroundChanged(uid, notifyApp); } return true; } case MSG_ADVISE_PERSIST_THRESHOLD: { Loading Loading @@ -3342,8 +3226,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } }; private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) { final PackageManager pm = mContext.getPackageManager(); final String[] packages = pm.getPackagesForUid(uid); if (packages != null) { final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final Intent intent = new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); intent.setPackage(packageName); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); } } } private void setInterfaceQuota(String iface, long quotaBytes) { try { mNetworkManager.setInterfaceQuota(iface, quotaBytes); Loading services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java +35 −37 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.server.net; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.wifi.WifiInfo.removeDoubleQuotes; import static com.android.server.net.NetworkPolicyManagerService.newWifiPolicy; import static com.android.server.net.NetworkPolicyManagerService.TAG; Loading Loading @@ -191,10 +193,10 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return -1; } private int listRestrictBackgroundWhitelist() throws RemoteException { private int listUidPolicies(String msg, int policy) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getRestrictBackgroundWhitelistedUids(); pw.print("Restrict background whitelisted UIDs: "); final int[] uids = mInterface.getUidsWithPolicy(policy); pw.print(msg); pw.print(": "); if (uids.length == 0) { pw.println("none"); } else { Loading @@ -208,22 +210,14 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return 0; } private int listRestrictBackgroundBlacklist() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND); pw.print("Restrict background blacklisted UIDs: "); if (uids.length == 0) { pw.println("none"); } else { for (int i = 0; i < uids.length; i++) { int uid = uids[i]; pw.print(uid); pw.print(' '); } private int listRestrictBackgroundWhitelist() throws RemoteException { return listUidPolicies("Restrict background whitelisted UIDs", POLICY_ALLOW_METERED_BACKGROUND); } pw.println(); return 0; private int listRestrictBackgroundBlacklist() throws RemoteException { return listUidPolicies("Restrict background blacklisted UIDs", POLICY_REJECT_METERED_BACKGROUND); } private int getRestrictBackground() throws RemoteException { Loading @@ -242,40 +236,44 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return 0; } private int addRestrictBackgroundWhitelist() throws RemoteException { private int setUidPolicy(int policy) throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.addRestrictBackgroundWhitelistedUid(uid); mInterface.setUidPolicy(uid, policy); return 0; } private int removeRestrictBackgroundWhitelist() throws RemoteException { private int resetUidPolicy(String errorMessage, int expectedPolicy) throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.removeRestrictBackgroundWhitelistedUid(uid); int actualPolicy = mInterface.getUidPolicy(uid); if (actualPolicy != expectedPolicy) { final PrintWriter pw = getOutPrintWriter(); pw.print("Error: UID "); pw.print(uid); pw.print(' '); pw.println(errorMessage); return -1; } mInterface.setUidPolicy(uid, POLICY_NONE); return 0; } private int addRestrictBackgroundBlacklist() throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; private int addRestrictBackgroundWhitelist() throws RemoteException { return setUidPolicy(POLICY_ALLOW_METERED_BACKGROUND); } mInterface.setUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND); return 0; private int removeRestrictBackgroundWhitelist() throws RemoteException { return resetUidPolicy("not whitelisted", POLICY_ALLOW_METERED_BACKGROUND); } private int removeRestrictBackgroundBlacklist() throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; private int addRestrictBackgroundBlacklist() throws RemoteException { return setUidPolicy(POLICY_REJECT_METERED_BACKGROUND); } mInterface.setUidPolicy(uid, POLICY_NONE); return 0; private int removeRestrictBackgroundBlacklist() throws RemoteException { return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND); } private int listWifiNetworks() throws RemoteException { Loading services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +31 −12 Original line number Diff line number Diff line Loading @@ -339,13 +339,17 @@ public class NetworkPolicyManagerServiceTest { } private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { assertWhitelistUids(); // Sanity check. // Sanity checks. assertWhitelistUids(); assertUidPolicy(UID_A, POLICY_NONE); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); mService.addRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); assertWhitelistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, true); mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, true); if (expectIntent) { Loading Loading @@ -376,13 +380,17 @@ public class NetworkPolicyManagerServiceTest { } private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { assertWhitelistUids(UID_A); // Sanity check. // Sanity checks. assertWhitelistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); mService.removeRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_NONE); assertWhitelistUids(); assertUidPolicy(UID_A, POLICY_NONE); mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, false); mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, false); if (expectIntent) { Loading @@ -393,13 +401,13 @@ public class NetworkPolicyManagerServiceTest { } /** * Adds blacklist when restrict background is on - app should receive an intent. * Adds blacklist when restrict background is on - app should not receive an intent. */ @Test @NetPolicyXml("restrict-background-on.xml") public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. addRestrictBackgroundBlacklist(true); addRestrictBackgroundBlacklist(false); } /** Loading Loading @@ -429,13 +437,13 @@ public class NetworkPolicyManagerServiceTest { } /** * Removes blacklist when restrict background is on - app should receive an intent. * Removes blacklist when restrict background is on - app should not receive an intent. */ @Test @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. removeRestrictBackgroundBlacklist(true); removeRestrictBackgroundBlacklist(false); } /** Loading Loading @@ -489,6 +497,17 @@ public class NetworkPolicyManagerServiceTest { futureIntent.assertNotReceived(); } @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { // Sanity checks. assertRestrictBackgroundOn(); assertWhitelistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); } @Test @NetPolicyXml("restrict-background-lists-whitelist-format.xml") public void testRestrictBackgroundLists_whitelistFormat() throws Exception { Loading Loading @@ -516,12 +535,12 @@ public class NetworkPolicyManagerServiceTest { assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE // Remove whitelist. mService.removeRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_NONE); assertUidPolicy(UID_A, POLICY_NONE); assertWhitelistUids(UID_B, UID_C); // Add whitelist when blacklisted. mService.addRestrictBackgroundWhitelistedUid(UID_E); mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); assertWhitelistUids(UID_B, UID_C, UID_E); Loading @@ -539,7 +558,7 @@ public class NetworkPolicyManagerServiceTest { public void testRestrictBackgroundLists_mixedFormat() throws Exception { assertWhitelistUids(UID_A, UID_C, UID_D); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails. assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2)); assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND); } Loading Loading @@ -1054,7 +1073,7 @@ public class NetworkPolicyManagerServiceTest { } private void assertWhitelistUids(int... uids) { assertContainsInAnyOrder(mService.getRestrictBackgroundWhitelistedUids(), uids); assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids); } private void assertRestrictBackgroundOn() throws Exception { Loading Loading
core/java/android/net/INetworkPolicyManager.aidl +0 −4 Original line number Diff line number Diff line Loading @@ -58,10 +58,6 @@ interface INetworkPolicyManager { /** Callback used to change internal state on tethering */ void onTetheringChanged(String iface, boolean tethering); /** Control which applications can be exempt from background data restrictions */ void addRestrictBackgroundWhitelistedUid(int uid); void removeRestrictBackgroundWhitelistedUid(int uid); int[] getRestrictBackgroundWhitelistedUids(); /** Gets the restrict background status based on the caller's UID: 1 - disabled 2 - whitelisted Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +52 −152 Original line number Diff line number Diff line Loading @@ -1769,16 +1769,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) { setUidPolicyUncheckedUL(uid, policy, persist); final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND; final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND; final boolean notifyApp; if (!isUidValidForWhitelistRules(uid)) { notifyApp = false; } else { final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted); final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted); notifyApp = wasBlocked != isBlocked; } if (isBlacklisted != wasBlacklisted) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED, uid, isBlacklisted ? 1 : 0).sendToTarget(); final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; // Checks if app was added or removed to the blacklist. if ((oldPolicy == POLICY_NONE && isBlacklisted) || (wasBlacklisted && policy == POLICY_NONE)) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null) .sendToTarget(); isBlacklisted ? 1 : 0, Boolean.valueOf(notifyApp)).sendToTarget(); } if (isWhitelisted != wasWhitelisted) { mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, isWhitelisted ? 1 : 0, Boolean.valueOf(notifyApp)).sendToTarget(); } } Loading Loading @@ -2065,61 +2074,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } /** * @deprecated - should use {@link #setUidPolicy(int, int)} directly. */ @Override @Deprecated public void addRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); final boolean oldStatus; final boolean needFirewallRules; int changed; synchronized (mUidRulesFirstLock) { final int oldUidPolicy = mUidPolicy.get(uid, POLICY_NONE); oldStatus = (oldUidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; if (oldStatus) { if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); return; } needFirewallRules = isUidValidForWhitelistRules(uid); Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); setUidPolicyUncheckedUL(uid, oldUidPolicy, POLICY_ALLOW_METERED_BACKGROUND, false); if (mDefaultRestrictBackgroundWhitelistUids.get(uid) && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { if (LOGD) Slog.d(TAG, "Removing uid " + uid + " from revoked restrict background whitelist"); mRestrictBackgroundWhitelistRevokedUids.delete(uid); } if (needFirewallRules) { // Only update firewall rules if necessary... updateRulesForDataUsageRestrictionsUL(uid); } // ...but always persists the whitelist request. synchronized (mNetworkPoliciesSecondLock) { writePolicyAL(); } changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; } mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, Boolean.TRUE).sendToTarget(); } /** * @deprecated - should use {@link #setUidPolicy(int, int)} directly. */ @Override @Deprecated public void removeRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); final boolean changed; synchronized (mUidRulesFirstLock) { changed = removeRestrictBackgroundWhitelistedUidUL(uid, false, true); } mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, Boolean.FALSE).sendToTarget(); } /** * Removes a uid from the restricted background whitelist, returning whether its current * {@link ConnectivityManager.RestrictBackgroundStatus} changed. Loading Loading @@ -2158,43 +2112,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return mRestrictBackground && needFirewallRules; } /** * @deprecated - should use {@link #getUidsWithPolicy(int)} instead, but first need to change * that method to use logical OR (|). */ @Override @Deprecated public int[] getRestrictBackgroundWhitelistedUids() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); int[] whitelist = null; synchronized (mUidRulesFirstLock) { // First calculate size int size = 0; int policySize = mUidPolicy.size(); for (int i = 0; i < policySize; i++) { if ((mUidPolicy.valueAt(i) & POLICY_ALLOW_METERED_BACKGROUND) != 0) { size ++; } } whitelist = new int[size]; // Then populate it. if (size > 0) { int index = 0; for (int i = 0; i < policySize; i++) { final int uid = mUidPolicy.keyAt(i); if ((mUidPolicy.valueAt(i) & POLICY_ALLOW_METERED_BACKGROUND) != 0) { whitelist[index++] = uid; } } } } if (LOGV) { Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " + Arrays.toString(whitelist)); } return whitelist; } @Override public int getRestrictBackgroundByCaller() { mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); Loading Loading @@ -2412,20 +2329,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } final int[] restrictBackgroundWhitelistUids = getRestrictBackgroundWhitelistedUids(); size = restrictBackgroundWhitelistUids.length; if (size > 0) { fout.println("Restrict background whitelist uids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(restrictBackgroundWhitelistUids[i]); fout.println(); } fout.decreaseIndent(); } size = mDefaultRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Default restrict background whitelist uids:"); Loading Loading @@ -3257,52 +3160,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return true; } case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: // - when an app is whitelisted // - when an app is blacklisted // // Whether the internal listeners (INetworkPolicyListener implementations) or // app broadcast receivers are notified depend on the following rules: // // - App receivers are only notified when the app status changed (msg.arg2 = 1) // - Listeners are only notified when app was whitelisted (msg.obj is not null), // since blacklist notifications are handled through MSG_RULES_CHANGED). final int uid = msg.arg1; final boolean changed = msg.arg2 == 1; final Boolean whitelisted = (Boolean) msg.obj; final boolean whitelisted = msg.arg2 == 1; final Boolean notifyApp = (Boolean) msg.obj; // First notify internal listeners... if (whitelisted != null) { final boolean whitelistedBool = whitelisted.booleanValue(); dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid, whitelistedBool); whitelisted); final int length = mListeners.beginBroadcast(); for (int i = 0; i < length; i++) { final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); dispatchRestrictBackgroundWhitelistChanged(listener, uid, whitelistedBool); dispatchRestrictBackgroundWhitelistChanged(listener, uid, whitelisted); } mListeners.finishBroadcast(); } final PackageManager pm = mContext.getPackageManager(); final String[] packages = pm.getPackagesForUid(uid); if (changed && packages != null) { // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final Intent intent = new Intent( ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); intent.setPackage(packageName); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); } // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED if (notifyApp.booleanValue()) { broadcastRestrictBackgroundChanged(uid, notifyApp); } return true; } case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: { final int uid = msg.arg1; final boolean blacklisted = msg.arg2 == 1; final Boolean notifyApp = (Boolean) msg.obj; // First notify internal listeners... dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid, blacklisted); final int length = mListeners.beginBroadcast(); Loading @@ -3312,6 +3192,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { blacklisted); } mListeners.finishBroadcast(); // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED if (notifyApp.booleanValue()) { broadcastRestrictBackgroundChanged(uid, notifyApp); } return true; } case MSG_ADVISE_PERSIST_THRESHOLD: { Loading Loading @@ -3342,8 +3226,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } }; private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) { final PackageManager pm = mContext.getPackageManager(); final String[] packages = pm.getPackagesForUid(uid); if (packages != null) { final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final Intent intent = new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); intent.setPackage(packageName); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); } } } private void setInterfaceQuota(String iface, long quotaBytes) { try { mNetworkManager.setInterfaceQuota(iface, quotaBytes); Loading
services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java +35 −37 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.server.net; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.wifi.WifiInfo.removeDoubleQuotes; import static com.android.server.net.NetworkPolicyManagerService.newWifiPolicy; import static com.android.server.net.NetworkPolicyManagerService.TAG; Loading Loading @@ -191,10 +193,10 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return -1; } private int listRestrictBackgroundWhitelist() throws RemoteException { private int listUidPolicies(String msg, int policy) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getRestrictBackgroundWhitelistedUids(); pw.print("Restrict background whitelisted UIDs: "); final int[] uids = mInterface.getUidsWithPolicy(policy); pw.print(msg); pw.print(": "); if (uids.length == 0) { pw.println("none"); } else { Loading @@ -208,22 +210,14 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return 0; } private int listRestrictBackgroundBlacklist() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND); pw.print("Restrict background blacklisted UIDs: "); if (uids.length == 0) { pw.println("none"); } else { for (int i = 0; i < uids.length; i++) { int uid = uids[i]; pw.print(uid); pw.print(' '); } private int listRestrictBackgroundWhitelist() throws RemoteException { return listUidPolicies("Restrict background whitelisted UIDs", POLICY_ALLOW_METERED_BACKGROUND); } pw.println(); return 0; private int listRestrictBackgroundBlacklist() throws RemoteException { return listUidPolicies("Restrict background blacklisted UIDs", POLICY_REJECT_METERED_BACKGROUND); } private int getRestrictBackground() throws RemoteException { Loading @@ -242,40 +236,44 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return 0; } private int addRestrictBackgroundWhitelist() throws RemoteException { private int setUidPolicy(int policy) throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.addRestrictBackgroundWhitelistedUid(uid); mInterface.setUidPolicy(uid, policy); return 0; } private int removeRestrictBackgroundWhitelist() throws RemoteException { private int resetUidPolicy(String errorMessage, int expectedPolicy) throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.removeRestrictBackgroundWhitelistedUid(uid); int actualPolicy = mInterface.getUidPolicy(uid); if (actualPolicy != expectedPolicy) { final PrintWriter pw = getOutPrintWriter(); pw.print("Error: UID "); pw.print(uid); pw.print(' '); pw.println(errorMessage); return -1; } mInterface.setUidPolicy(uid, POLICY_NONE); return 0; } private int addRestrictBackgroundBlacklist() throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; private int addRestrictBackgroundWhitelist() throws RemoteException { return setUidPolicy(POLICY_ALLOW_METERED_BACKGROUND); } mInterface.setUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND); return 0; private int removeRestrictBackgroundWhitelist() throws RemoteException { return resetUidPolicy("not whitelisted", POLICY_ALLOW_METERED_BACKGROUND); } private int removeRestrictBackgroundBlacklist() throws RemoteException { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; private int addRestrictBackgroundBlacklist() throws RemoteException { return setUidPolicy(POLICY_REJECT_METERED_BACKGROUND); } mInterface.setUidPolicy(uid, POLICY_NONE); return 0; private int removeRestrictBackgroundBlacklist() throws RemoteException { return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND); } private int listWifiNetworks() throws RemoteException { Loading
services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +31 −12 Original line number Diff line number Diff line Loading @@ -339,13 +339,17 @@ public class NetworkPolicyManagerServiceTest { } private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { assertWhitelistUids(); // Sanity check. // Sanity checks. assertWhitelistUids(); assertUidPolicy(UID_A, POLICY_NONE); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); mService.addRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); assertWhitelistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, true); mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, true); if (expectIntent) { Loading Loading @@ -376,13 +380,17 @@ public class NetworkPolicyManagerServiceTest { } private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { assertWhitelistUids(UID_A); // Sanity check. // Sanity checks. assertWhitelistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onRestrictBackgroundWhitelistChanged(anyInt(), anyBoolean()); mService.removeRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_NONE); assertWhitelistUids(); assertUidPolicy(UID_A, POLICY_NONE); mPolicyListener.waitAndVerify().onRestrictBackgroundWhitelistChanged(APP_ID_A, false); mPolicyListener.verifyNotCalled().onRestrictBackgroundBlacklistChanged(APP_ID_A, false); if (expectIntent) { Loading @@ -393,13 +401,13 @@ public class NetworkPolicyManagerServiceTest { } /** * Adds blacklist when restrict background is on - app should receive an intent. * Adds blacklist when restrict background is on - app should not receive an intent. */ @Test @NetPolicyXml("restrict-background-on.xml") public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. addRestrictBackgroundBlacklist(true); addRestrictBackgroundBlacklist(false); } /** Loading Loading @@ -429,13 +437,13 @@ public class NetworkPolicyManagerServiceTest { } /** * Removes blacklist when restrict background is on - app should receive an intent. * Removes blacklist when restrict background is on - app should not receive an intent. */ @Test @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. removeRestrictBackgroundBlacklist(true); removeRestrictBackgroundBlacklist(false); } /** Loading Loading @@ -489,6 +497,17 @@ public class NetworkPolicyManagerServiceTest { futureIntent.assertNotReceived(); } @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { // Sanity checks. assertRestrictBackgroundOn(); assertWhitelistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); } @Test @NetPolicyXml("restrict-background-lists-whitelist-format.xml") public void testRestrictBackgroundLists_whitelistFormat() throws Exception { Loading Loading @@ -516,12 +535,12 @@ public class NetworkPolicyManagerServiceTest { assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE // Remove whitelist. mService.removeRestrictBackgroundWhitelistedUid(UID_A); mService.setUidPolicy(UID_A, POLICY_NONE); assertUidPolicy(UID_A, POLICY_NONE); assertWhitelistUids(UID_B, UID_C); // Add whitelist when blacklisted. mService.addRestrictBackgroundWhitelistedUid(UID_E); mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); assertWhitelistUids(UID_B, UID_C, UID_E); Loading @@ -539,7 +558,7 @@ public class NetworkPolicyManagerServiceTest { public void testRestrictBackgroundLists_mixedFormat() throws Exception { assertWhitelistUids(UID_A, UID_C, UID_D); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails. assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2)); assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND); } Loading Loading @@ -1054,7 +1073,7 @@ public class NetworkPolicyManagerServiceTest { } private void assertWhitelistUids(int... uids) { assertContainsInAnyOrder(mService.getRestrictBackgroundWhitelistedUids(), uids); assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids); } private void assertRestrictBackgroundOn() throws Exception { Loading