Loading services/core/java/com/android/server/net/NetworkPolicyLogger.java +25 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class NetworkPolicyLogger { private static final int EVENT_UID_FIREWALL_RULE_CHANGED = 11; private static final int EVENT_FIREWALL_CHAIN_ENABLED = 12; private static final int EVENT_UPDATE_METERED_RESTRICTED_PKGS = 13; private static final int EVENT_APP_IDLE_WL_CHANGED = 14; static final int NTWK_BLOCKED_POWER = 0; static final int NTWK_ALLOWED_NON_METERED = 1; Loading Loading @@ -145,6 +146,13 @@ public class NetworkPolicyLogger { } } void appIdleWlChanged(int uid, boolean isWhitelisted) { synchronized (mLock) { if (LOGD) Slog.d(TAG, getAppIdleWlChangedLog(uid, isWhitelisted)); mEventsBuffer.appIdleWlChanged(uid, isWhitelisted); } } void paroleStateChanged(boolean paroleOn) { synchronized (mLock) { if (LOGD) Slog.d(TAG, getParoleStateChanged(paroleOn)); Loading Loading @@ -259,6 +267,10 @@ public class NetworkPolicyLogger { return "App idle state of uid " + uid + ": " + idle; } private static String getAppIdleWlChangedLog(int uid, boolean isWhitelisted) { return "App idle whitelist state of uid " + uid + ": " + isWhitelisted; } private static String getParoleStateChanged(boolean paroleOn) { return "Parole state: " + paroleOn; } Loading Loading @@ -409,6 +421,17 @@ public class NetworkPolicyLogger { data.timeStamp = System.currentTimeMillis(); } public void appIdleWlChanged(int uid, boolean isWhitelisted) { final Data data = getNextSlot(); if (data == null) return; data.reset(); data.type = EVENT_APP_IDLE_WL_CHANGED; data.ifield1 = uid; data.bfield1 = isWhitelisted; data.timeStamp = System.currentTimeMillis(); } public void paroleStateChanged(boolean paroleOn) { final Data data = getNextSlot(); if (data == null) return; Loading Loading @@ -487,6 +510,8 @@ public class NetworkPolicyLogger { return getDeviceIdleModeEnabled(data.bfield1); case EVENT_APP_IDLE_STATE_CHANGED: return getAppIdleChangedLog(data.ifield1, data.bfield1); case EVENT_APP_IDLE_WL_CHANGED: return getAppIdleWlChangedLog(data.ifield1, data.bfield1); case EVENT_PAROLE_STATE_CHANGED: return getParoleStateChanged(data.bfield1); case EVENT_TEMP_POWER_SAVE_WL_CHANGED: Loading services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ public abstract class NetworkPolicyManagerInternal { */ public abstract void onAdminDataAvailable(); /** * Control if a UID should be whitelisted even if it's in app idle mode. Other restrictions may * still be in effect. */ public abstract void setAppIdleWhitelist(int uid, boolean shouldWhitelist); /** * Sets a list of packages which are restricted by admin from accessing metered data. * Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +93 −5 Original line number Diff line number Diff line Loading @@ -464,6 +464,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); // "Power save mode" is the concept used in the DeviceIdleController that includes various // features including Doze and Battery Saver. It include Battery Saver, but "power save mode" // and "battery saver" are not equivalent. /** * UIDs that have been white-listed to always be able to have network access * in power save mode, except device idle (doze) still applies. Loading @@ -483,6 +487,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been white-listed temporarily to be able to have network access despite being * idle. Other power saving restrictions still apply. */ @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been initially white-listed by system to avoid restricted background. */ Loading Loading @@ -3372,6 +3383,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } size = mAppIdleTempWhitelistAppIds.size(); if (size > 0) { fout.println("App idle whitelist app ids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(mAppIdleTempWhitelistAppIds.keyAt(i)); fout.print(": "); fout.print(mAppIdleTempWhitelistAppIds.valueAt(i)); fout.println(); } fout.decreaseIndent(); } size = mDefaultRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Default restrict background whitelist uids:"); Loading Loading @@ -3640,12 +3665,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** * Returns whether a uid is whitelisted from power saving restrictions (eg: Battery Saver, Doze * mode, and app idle). * * @param deviceIdleMode if true then we don't consider * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is * whitelisted. */ @GuardedBy("mUidRulesFirstLock") private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) { private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) { final int appId = UserHandle.getAppId(uid); boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); Loading @@ -3660,7 +3688,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) { if (enabled) { final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, chain == FIREWALL_CHAIN_DOZABLE); if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) { setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); Loading Loading @@ -3712,8 +3740,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) && !isUidForegroundOnRestrictPowerUL(uid)) { setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid); } else { setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT"); } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); Loading Loading @@ -3896,7 +3926,59 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return UserHandle.isApp(uid) && hasInternetPermissions(uid); } private boolean isUidIdle(int uid) { /** * Set whether or not an app should be whitelisted for network access while in app idle. Other * power saving restrictions may still apply. */ @VisibleForTesting public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { synchronized (mUidRulesFirstLock) { if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) { // No change. return; } final long token = Binder.clearCallingIdentity(); try { mLogger.appIdleWlChanged(uid, shouldWhitelist); if (shouldWhitelist) { mAppIdleTempWhitelistAppIds.put(uid, true); } else { mAppIdleTempWhitelistAppIds.delete(uid); } updateRuleForAppIdleUL(uid); updateRulesForPowerRestrictionsUL(uid); } finally { Binder.restoreCallingIdentity(token); } } } /** Return the list of UIDs currently in the app idle whitelist. */ @VisibleForTesting public int[] getAppIdleWhitelist() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); synchronized (mUidRulesFirstLock) { final int len = mAppIdleTempWhitelistAppIds.size(); int[] uids = new int[len]; for (int i = 0; i < len; ++i) { uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i); } return uids; } } /** Returns if the UID is currently considered idle. */ @VisibleForTesting public boolean isUidIdle(int uid) { synchronized (mUidRulesFirstLock) { if (mAppIdleTempWhitelistAppIds.get(uid)) { // UID is temporarily whitelisted. return false; } } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); final int userId = UserHandle.getUserId(uid); Loading Loading @@ -3940,6 +4022,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPowerSaveWhitelistExceptIdleAppIds.delete(uid); mPowerSaveWhitelistAppIds.delete(uid); mPowerSaveTempWhitelistAppIds.delete(uid); mAppIdleTempWhitelistAppIds.delete(uid); // ...then update iptables asynchronously. mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget(); Loading Loading @@ -3984,7 +4067,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're * also blacklisted. * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), * no UIDs other those whitelisted will have access. * no UIDs other than those whitelisted will have access. * <ul> * * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the Loading Loading @@ -4194,7 +4277,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid); final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode); final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode); final int oldRule = oldUidRules & MASK_ALL_NETWORKS; int newRule = RULE_NONE; Loading Loading @@ -5022,6 +5105,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mAdminDataAvailableLatch.countDown(); } @Override public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist); } @Override public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) { setMeteredRestrictedPackagesInternal(packageNames, userId); Loading services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java +38 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { pw.println(" Adds a UID to the whitelist for restrict background usage."); pw.println(" add restrict-background-blacklist UID"); pw.println(" Adds a UID to the blacklist for restrict background usage."); pw.println(" add app-idle-whitelist UID"); pw.println(" Adds a UID to the temporary app idle whitelist."); pw.println(" get restrict-background"); pw.println(" Gets the global restrict background usage status."); pw.println(" list wifi-networks [true|false]"); Loading @@ -92,6 +94,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { pw.println(" Removes a UID from the whitelist for restrict background usage."); pw.println(" remove restrict-background-blacklist UID"); pw.println(" Removes a UID from the blacklist for restrict background usage."); pw.println(" remove app-idle-whitelist UID"); pw.println(" Removes a UID from the temporary app idle whitelist."); pw.println(" set metered-network ID [undefined|true|false]"); pw.println(" Toggles whether the given wi-fi network is metered."); pw.println(" set restrict-background BOOLEAN"); Loading Loading @@ -142,6 +146,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return -1; } switch(type) { case "app-idle-whitelist": return listAppIdleWhitelist(); case "wifi-networks": return listWifiNetworks(); case "restrict-background-whitelist": Loading @@ -165,6 +171,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return addRestrictBackgroundWhitelist(); case "restrict-background-blacklist": return addRestrictBackgroundBlacklist(); case "app-idle-whitelist": return addAppIdleWhitelist(); } pw.println("Error: unknown add type '" + type + "'"); return -1; Loading @@ -182,14 +190,20 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return removeRestrictBackgroundWhitelist(); case "restrict-background-blacklist": return removeRestrictBackgroundBlacklist(); case "app-idle-whitelist": return removeAppIdleWhitelist(); } pw.println("Error: unknown remove type '" + type + "'"); return -1; } private int listUidPolicies(String msg, int policy) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getUidsWithPolicy(policy); return listUidList(msg, uids); } private int listUidList(String msg, int[] uids) { final PrintWriter pw = getOutPrintWriter(); pw.print(msg); pw.print(": "); if (uids.length == 0) { pw.println("none"); Loading @@ -214,6 +228,12 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { POLICY_REJECT_METERED_BACKGROUND); } private int listAppIdleWhitelist() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getAppIdleWhitelist(); return listUidList("App Idle whitelisted UIDs", uids); } private int getRestrictBackground() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); pw.print("Restrict background status: "); Loading Loading @@ -277,6 +297,23 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND); } private int setAppIdleWhitelist(boolean isWhitelisted) { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.setAppIdleWhitelist(uid, isWhitelisted); return 0; } private int addAppIdleWhitelist() throws RemoteException { return setAppIdleWhitelist(true); } private int removeAppIdleWhitelist() throws RemoteException { return setAppIdleWhitelist(false); } private int listWifiNetworks() { final PrintWriter pw = getOutPrintWriter(); final String arg = getNextArg(); Loading services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +15 −3 Original line number Diff line number Diff line Loading @@ -148,6 +148,9 @@ import com.android.server.net.NetworkStatsManagerInternal; import com.google.common.util.concurrent.AbstractFuture; import libcore.io.IoUtils; import libcore.io.Streams; import org.junit.After; import org.junit.Before; import org.junit.Rule; Loading @@ -162,9 +165,6 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import libcore.io.IoUtils; import libcore.io.Streams; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; Loading Loading @@ -843,6 +843,18 @@ public class NetworkPolicyManagerServiceTest { assertTrue(mService.isUidForeground(UID_B)); } @Test public void testAppIdleTempWhitelisting() throws Exception { mService.setAppIdleWhitelist(UID_A, true); mService.setAppIdleWhitelist(UID_B, false); int[] whitelistedIds = mService.getAppIdleWhitelist(); assertTrue(Arrays.binarySearch(whitelistedIds, UID_A) >= 0); assertTrue(Arrays.binarySearch(whitelistedIds, UID_B) < 0); assertFalse(mService.isUidIdle(UID_A)); // Can't currently guarantee UID_B's app idle state. // TODO: expand with multiple app idle states. } private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) { RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime), ZoneId.systemDefault()); Loading Loading
services/core/java/com/android/server/net/NetworkPolicyLogger.java +25 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class NetworkPolicyLogger { private static final int EVENT_UID_FIREWALL_RULE_CHANGED = 11; private static final int EVENT_FIREWALL_CHAIN_ENABLED = 12; private static final int EVENT_UPDATE_METERED_RESTRICTED_PKGS = 13; private static final int EVENT_APP_IDLE_WL_CHANGED = 14; static final int NTWK_BLOCKED_POWER = 0; static final int NTWK_ALLOWED_NON_METERED = 1; Loading Loading @@ -145,6 +146,13 @@ public class NetworkPolicyLogger { } } void appIdleWlChanged(int uid, boolean isWhitelisted) { synchronized (mLock) { if (LOGD) Slog.d(TAG, getAppIdleWlChangedLog(uid, isWhitelisted)); mEventsBuffer.appIdleWlChanged(uid, isWhitelisted); } } void paroleStateChanged(boolean paroleOn) { synchronized (mLock) { if (LOGD) Slog.d(TAG, getParoleStateChanged(paroleOn)); Loading Loading @@ -259,6 +267,10 @@ public class NetworkPolicyLogger { return "App idle state of uid " + uid + ": " + idle; } private static String getAppIdleWlChangedLog(int uid, boolean isWhitelisted) { return "App idle whitelist state of uid " + uid + ": " + isWhitelisted; } private static String getParoleStateChanged(boolean paroleOn) { return "Parole state: " + paroleOn; } Loading Loading @@ -409,6 +421,17 @@ public class NetworkPolicyLogger { data.timeStamp = System.currentTimeMillis(); } public void appIdleWlChanged(int uid, boolean isWhitelisted) { final Data data = getNextSlot(); if (data == null) return; data.reset(); data.type = EVENT_APP_IDLE_WL_CHANGED; data.ifield1 = uid; data.bfield1 = isWhitelisted; data.timeStamp = System.currentTimeMillis(); } public void paroleStateChanged(boolean paroleOn) { final Data data = getNextSlot(); if (data == null) return; Loading Loading @@ -487,6 +510,8 @@ public class NetworkPolicyLogger { return getDeviceIdleModeEnabled(data.bfield1); case EVENT_APP_IDLE_STATE_CHANGED: return getAppIdleChangedLog(data.ifield1, data.bfield1); case EVENT_APP_IDLE_WL_CHANGED: return getAppIdleWlChangedLog(data.ifield1, data.bfield1); case EVENT_PAROLE_STATE_CHANGED: return getParoleStateChanged(data.bfield1); case EVENT_TEMP_POWER_SAVE_WL_CHANGED: Loading
services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ public abstract class NetworkPolicyManagerInternal { */ public abstract void onAdminDataAvailable(); /** * Control if a UID should be whitelisted even if it's in app idle mode. Other restrictions may * still be in effect. */ public abstract void setAppIdleWhitelist(int uid, boolean shouldWhitelist); /** * Sets a list of packages which are restricted by admin from accessing metered data. * Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +93 −5 Original line number Diff line number Diff line Loading @@ -464,6 +464,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); // "Power save mode" is the concept used in the DeviceIdleController that includes various // features including Doze and Battery Saver. It include Battery Saver, but "power save mode" // and "battery saver" are not equivalent. /** * UIDs that have been white-listed to always be able to have network access * in power save mode, except device idle (doze) still applies. Loading @@ -483,6 +487,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been white-listed temporarily to be able to have network access despite being * idle. Other power saving restrictions still apply. */ @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been initially white-listed by system to avoid restricted background. */ Loading Loading @@ -3372,6 +3383,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } size = mAppIdleTempWhitelistAppIds.size(); if (size > 0) { fout.println("App idle whitelist app ids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(mAppIdleTempWhitelistAppIds.keyAt(i)); fout.print(": "); fout.print(mAppIdleTempWhitelistAppIds.valueAt(i)); fout.println(); } fout.decreaseIndent(); } size = mDefaultRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Default restrict background whitelist uids:"); Loading Loading @@ -3640,12 +3665,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** * Returns whether a uid is whitelisted from power saving restrictions (eg: Battery Saver, Doze * mode, and app idle). * * @param deviceIdleMode if true then we don't consider * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is * whitelisted. */ @GuardedBy("mUidRulesFirstLock") private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) { private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) { final int appId = UserHandle.getAppId(uid); boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); Loading @@ -3660,7 +3688,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) { if (enabled) { final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, chain == FIREWALL_CHAIN_DOZABLE); if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) { setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); Loading Loading @@ -3712,8 +3740,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) && !isUidForegroundOnRestrictPowerUL(uid)) { setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid); } else { setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT"); } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); Loading Loading @@ -3896,7 +3926,59 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return UserHandle.isApp(uid) && hasInternetPermissions(uid); } private boolean isUidIdle(int uid) { /** * Set whether or not an app should be whitelisted for network access while in app idle. Other * power saving restrictions may still apply. */ @VisibleForTesting public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { synchronized (mUidRulesFirstLock) { if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) { // No change. return; } final long token = Binder.clearCallingIdentity(); try { mLogger.appIdleWlChanged(uid, shouldWhitelist); if (shouldWhitelist) { mAppIdleTempWhitelistAppIds.put(uid, true); } else { mAppIdleTempWhitelistAppIds.delete(uid); } updateRuleForAppIdleUL(uid); updateRulesForPowerRestrictionsUL(uid); } finally { Binder.restoreCallingIdentity(token); } } } /** Return the list of UIDs currently in the app idle whitelist. */ @VisibleForTesting public int[] getAppIdleWhitelist() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); synchronized (mUidRulesFirstLock) { final int len = mAppIdleTempWhitelistAppIds.size(); int[] uids = new int[len]; for (int i = 0; i < len; ++i) { uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i); } return uids; } } /** Returns if the UID is currently considered idle. */ @VisibleForTesting public boolean isUidIdle(int uid) { synchronized (mUidRulesFirstLock) { if (mAppIdleTempWhitelistAppIds.get(uid)) { // UID is temporarily whitelisted. return false; } } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); final int userId = UserHandle.getUserId(uid); Loading Loading @@ -3940,6 +4022,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPowerSaveWhitelistExceptIdleAppIds.delete(uid); mPowerSaveWhitelistAppIds.delete(uid); mPowerSaveTempWhitelistAppIds.delete(uid); mAppIdleTempWhitelistAppIds.delete(uid); // ...then update iptables asynchronously. mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget(); Loading Loading @@ -3984,7 +4067,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're * also blacklisted. * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), * no UIDs other those whitelisted will have access. * no UIDs other than those whitelisted will have access. * <ul> * * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the Loading Loading @@ -4194,7 +4277,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid); final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode); final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode); final int oldRule = oldUidRules & MASK_ALL_NETWORKS; int newRule = RULE_NONE; Loading Loading @@ -5022,6 +5105,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mAdminDataAvailableLatch.countDown(); } @Override public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist); } @Override public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) { setMeteredRestrictedPackagesInternal(packageNames, userId); Loading
services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java +38 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { pw.println(" Adds a UID to the whitelist for restrict background usage."); pw.println(" add restrict-background-blacklist UID"); pw.println(" Adds a UID to the blacklist for restrict background usage."); pw.println(" add app-idle-whitelist UID"); pw.println(" Adds a UID to the temporary app idle whitelist."); pw.println(" get restrict-background"); pw.println(" Gets the global restrict background usage status."); pw.println(" list wifi-networks [true|false]"); Loading @@ -92,6 +94,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { pw.println(" Removes a UID from the whitelist for restrict background usage."); pw.println(" remove restrict-background-blacklist UID"); pw.println(" Removes a UID from the blacklist for restrict background usage."); pw.println(" remove app-idle-whitelist UID"); pw.println(" Removes a UID from the temporary app idle whitelist."); pw.println(" set metered-network ID [undefined|true|false]"); pw.println(" Toggles whether the given wi-fi network is metered."); pw.println(" set restrict-background BOOLEAN"); Loading Loading @@ -142,6 +146,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return -1; } switch(type) { case "app-idle-whitelist": return listAppIdleWhitelist(); case "wifi-networks": return listWifiNetworks(); case "restrict-background-whitelist": Loading @@ -165,6 +171,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return addRestrictBackgroundWhitelist(); case "restrict-background-blacklist": return addRestrictBackgroundBlacklist(); case "app-idle-whitelist": return addAppIdleWhitelist(); } pw.println("Error: unknown add type '" + type + "'"); return -1; Loading @@ -182,14 +190,20 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return removeRestrictBackgroundWhitelist(); case "restrict-background-blacklist": return removeRestrictBackgroundBlacklist(); case "app-idle-whitelist": return removeAppIdleWhitelist(); } pw.println("Error: unknown remove type '" + type + "'"); return -1; } private int listUidPolicies(String msg, int policy) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getUidsWithPolicy(policy); return listUidList(msg, uids); } private int listUidList(String msg, int[] uids) { final PrintWriter pw = getOutPrintWriter(); pw.print(msg); pw.print(": "); if (uids.length == 0) { pw.println("none"); Loading @@ -214,6 +228,12 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { POLICY_REJECT_METERED_BACKGROUND); } private int listAppIdleWhitelist() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); final int[] uids = mInterface.getAppIdleWhitelist(); return listUidList("App Idle whitelisted UIDs", uids); } private int getRestrictBackground() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); pw.print("Restrict background status: "); Loading Loading @@ -277,6 +297,23 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND); } private int setAppIdleWhitelist(boolean isWhitelisted) { final int uid = getUidFromNextArg(); if (uid < 0) { return uid; } mInterface.setAppIdleWhitelist(uid, isWhitelisted); return 0; } private int addAppIdleWhitelist() throws RemoteException { return setAppIdleWhitelist(true); } private int removeAppIdleWhitelist() throws RemoteException { return setAppIdleWhitelist(false); } private int listWifiNetworks() { final PrintWriter pw = getOutPrintWriter(); final String arg = getNextArg(); Loading
services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +15 −3 Original line number Diff line number Diff line Loading @@ -148,6 +148,9 @@ import com.android.server.net.NetworkStatsManagerInternal; import com.google.common.util.concurrent.AbstractFuture; import libcore.io.IoUtils; import libcore.io.Streams; import org.junit.After; import org.junit.Before; import org.junit.Rule; Loading @@ -162,9 +165,6 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import libcore.io.IoUtils; import libcore.io.Streams; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; Loading Loading @@ -843,6 +843,18 @@ public class NetworkPolicyManagerServiceTest { assertTrue(mService.isUidForeground(UID_B)); } @Test public void testAppIdleTempWhitelisting() throws Exception { mService.setAppIdleWhitelist(UID_A, true); mService.setAppIdleWhitelist(UID_B, false); int[] whitelistedIds = mService.getAppIdleWhitelist(); assertTrue(Arrays.binarySearch(whitelistedIds, UID_A) >= 0); assertTrue(Arrays.binarySearch(whitelistedIds, UID_B) < 0); assertFalse(mService.isUidIdle(UID_A)); // Can't currently guarantee UID_B's app idle state. // TODO: expand with multiple app idle states. } private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) { RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime), ZoneId.systemDefault()); Loading