Loading core/java/android/net/INetworkPolicyManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,11 @@ interface INetworkPolicyManager { void setRestrictBackground(boolean restrictBackground); boolean getRestrictBackground(); /** Control which applications can be exempt from background data restrictions */ void addRestrictBackgroundWhitelistedUid(int uid); void removeRestrictBackgroundWhitelistedUid(int uid); int[] getRestrictBackgroundWhitelistedUids(); void setDeviceIdleMode(boolean enabled); NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state); Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +121 −3 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; Loading Loading @@ -153,6 +154,7 @@ import libcore.io.IoUtils; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -213,6 +215,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String TAG_NETWORK_POLICY = "network-policy"; private static final String TAG_UID_POLICY = "uid-policy"; private static final String TAG_APP_POLICY = "app-policy"; private static final String TAG_WHITELIST = "whitelist"; private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; private static final String ATTR_VERSION = "version"; private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; Loading Loading @@ -304,6 +308,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been white-listed to avoid restricted background. */ private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray(); /** Set of ifaces that are metered. */ private ArraySet<String> mMeteredIfaces = new ArraySet<>(); /** Set of over-limit templates that have been notified. */ Loading @@ -324,6 +333,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final AppOpsManager mAppOps; private final MyPackageMonitor mPackageMonitor; // TODO: keep whitelist of system-critical services that should never have // rules enforced, such as system, phone, and radio UIDs. Loading Loading @@ -363,6 +374,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); mAppOps = context.getSystemService(AppOpsManager.class); mPackageMonitor = new MyPackageMonitor(); } public void bindConnectivityManager(IConnectivityManager connManager) { Loading Loading @@ -431,6 +444,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); synchronized (mRulesLock) { updatePowerSaveWhitelistLocked(); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); Loading Loading @@ -1127,7 +1142,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // If we are in restrict power mode, we want to treat all interfaces // as metered, to restrict access to the network by uid. However, we // will not have a bandwidth limit. Also only do this if restrict // background data use is *not* enabled, since that takes precendence // background data use is *not* enabled, since that takes precedence // use over those networks can have a cost associated with it). final boolean powerSave = mRestrictPower && !mRestrictBackground; Loading Loading @@ -1339,6 +1354,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { int type; int version = VERSION_INIT; boolean insideWhitelist = false; while ((type = in.next()) != END_DOCUMENT) { final String tag = in.getName(); if (type == START_TAG) { Loading Loading @@ -1431,7 +1447,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else { Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); } } else if (TAG_WHITELIST.equals(tag)) { insideWhitelist = true; } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); mRestrictBackgroundWhitelistUids.put(uid, true); } } else if (type == END_TAG) { if (TAG_WHITELIST.equals(tag)) { insideWhitelist = false; } } } Loading Loading @@ -1519,6 +1545,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } out.endTag(null, TAG_POLICY_LIST); // write all whitelists out.startTag(null, TAG_WHITELIST); // restrict background whitelist final int size = mRestrictBackgroundWhitelistUids.size(); for (int i = 0; i < size; i++) { final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); out.startTag(null, TAG_RESTRICT_BACKGROUND); writeIntAttribute(out, ATTR_UID, uid); out.endTag(null, TAG_RESTRICT_BACKGROUND); } out.endTag(null, TAG_WHITELIST); out.endDocument(); mPolicyFile.finishWrite(fos); Loading Loading @@ -1788,6 +1829,49 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .sendToTarget(); } @Override public void addRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); synchronized (mRulesLock) { mRestrictBackgroundWhitelistUids.append(uid, true); writePolicyLocked(); // TODO: call other update methods like updateNetworkRulesLocked? } } @Override public void removeRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } private void removeRestrictBackgroundWhitelistedUidLocked(int uid) { mRestrictBackgroundWhitelistUids.delete(uid); writePolicyLocked(); // TODO: call other update methods like updateNetworkRulesLocked? } @Override public int[] getRestrictBackgroundWhitelistedUids() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); synchronized (mRulesLock) { final int size = mRestrictBackgroundWhitelistUids.size(); final int[] whitelist = new int[size]; for (int i = 0; i < size; i++) { whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); } if (LOGV) { Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " + mRestrictBackgroundWhitelistUids); } return whitelist; } } @Override public boolean getRestrictBackground() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Loading Loading @@ -1978,6 +2062,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } size = mRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Restrict background whitelist uids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); fout.println(); } fout.decreaseIndent(); } final SparseBooleanArray knownUids = new SparseBooleanArray(); collectKeys(mUidState, knownUids); collectKeys(mUidRules, knownUids); Loading Loading @@ -2279,9 +2375,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { uidRules = RULE_REJECT_METERED; } else if (mRestrictBackground) { if (!uidForeground) { // uid in background, and global background disabled // uid in background, global background disabled, and this uid is not on the white // list of those allowed background access while global background is disabled if (!mRestrictBackgroundWhitelistUids.get(uid)) { uidRules = RULE_REJECT_METERED; } } } else if (mRestrictPower) { final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId) || mPowerSaveTempWhitelistAppIds.get(appId); Loading Loading @@ -2642,4 +2741,23 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } private class MyPackageMonitor extends PackageMonitor { @Override public void onPackageRemoved(String packageName, int uid) { if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } @Override public void onPackageRemovedAllUsers(String packageName, int uid) { if (LOGV) Slog.v(TAG, "onPackageRemovedAllUsers: " + packageName + " ->" + uid); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } } } Loading
core/java/android/net/INetworkPolicyManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,11 @@ interface INetworkPolicyManager { void setRestrictBackground(boolean restrictBackground); boolean getRestrictBackground(); /** Control which applications can be exempt from background data restrictions */ void addRestrictBackgroundWhitelistedUid(int uid); void removeRestrictBackgroundWhitelistedUid(int uid); int[] getRestrictBackgroundWhitelistedUids(); void setDeviceIdleMode(boolean enabled); NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state); Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +121 −3 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; Loading Loading @@ -153,6 +154,7 @@ import libcore.io.IoUtils; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -213,6 +215,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String TAG_NETWORK_POLICY = "network-policy"; private static final String TAG_UID_POLICY = "uid-policy"; private static final String TAG_APP_POLICY = "app-policy"; private static final String TAG_WHITELIST = "whitelist"; private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; private static final String ATTR_VERSION = "version"; private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; Loading Loading @@ -304,6 +308,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); /** * UIDs that have been white-listed to avoid restricted background. */ private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray(); /** Set of ifaces that are metered. */ private ArraySet<String> mMeteredIfaces = new ArraySet<>(); /** Set of over-limit templates that have been notified. */ Loading @@ -324,6 +333,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final AppOpsManager mAppOps; private final MyPackageMonitor mPackageMonitor; // TODO: keep whitelist of system-critical services that should never have // rules enforced, such as system, phone, and radio UIDs. Loading Loading @@ -363,6 +374,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); mAppOps = context.getSystemService(AppOpsManager.class); mPackageMonitor = new MyPackageMonitor(); } public void bindConnectivityManager(IConnectivityManager connManager) { Loading Loading @@ -431,6 +444,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); synchronized (mRulesLock) { updatePowerSaveWhitelistLocked(); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); Loading Loading @@ -1127,7 +1142,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // If we are in restrict power mode, we want to treat all interfaces // as metered, to restrict access to the network by uid. However, we // will not have a bandwidth limit. Also only do this if restrict // background data use is *not* enabled, since that takes precendence // background data use is *not* enabled, since that takes precedence // use over those networks can have a cost associated with it). final boolean powerSave = mRestrictPower && !mRestrictBackground; Loading Loading @@ -1339,6 +1354,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { int type; int version = VERSION_INIT; boolean insideWhitelist = false; while ((type = in.next()) != END_DOCUMENT) { final String tag = in.getName(); if (type == START_TAG) { Loading Loading @@ -1431,7 +1447,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else { Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); } } else if (TAG_WHITELIST.equals(tag)) { insideWhitelist = true; } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); mRestrictBackgroundWhitelistUids.put(uid, true); } } else if (type == END_TAG) { if (TAG_WHITELIST.equals(tag)) { insideWhitelist = false; } } } Loading Loading @@ -1519,6 +1545,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } out.endTag(null, TAG_POLICY_LIST); // write all whitelists out.startTag(null, TAG_WHITELIST); // restrict background whitelist final int size = mRestrictBackgroundWhitelistUids.size(); for (int i = 0; i < size; i++) { final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); out.startTag(null, TAG_RESTRICT_BACKGROUND); writeIntAttribute(out, ATTR_UID, uid); out.endTag(null, TAG_RESTRICT_BACKGROUND); } out.endTag(null, TAG_WHITELIST); out.endDocument(); mPolicyFile.finishWrite(fos); Loading Loading @@ -1788,6 +1829,49 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .sendToTarget(); } @Override public void addRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); synchronized (mRulesLock) { mRestrictBackgroundWhitelistUids.append(uid, true); writePolicyLocked(); // TODO: call other update methods like updateNetworkRulesLocked? } } @Override public void removeRestrictBackgroundWhitelistedUid(int uid) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } private void removeRestrictBackgroundWhitelistedUidLocked(int uid) { mRestrictBackgroundWhitelistUids.delete(uid); writePolicyLocked(); // TODO: call other update methods like updateNetworkRulesLocked? } @Override public int[] getRestrictBackgroundWhitelistedUids() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); synchronized (mRulesLock) { final int size = mRestrictBackgroundWhitelistUids.size(); final int[] whitelist = new int[size]; for (int i = 0; i < size; i++) { whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); } if (LOGV) { Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " + mRestrictBackgroundWhitelistUids); } return whitelist; } } @Override public boolean getRestrictBackground() { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Loading Loading @@ -1978,6 +2062,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } size = mRestrictBackgroundWhitelistUids.size(); if (size > 0) { fout.println("Restrict background whitelist uids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); fout.println(); } fout.decreaseIndent(); } final SparseBooleanArray knownUids = new SparseBooleanArray(); collectKeys(mUidState, knownUids); collectKeys(mUidRules, knownUids); Loading Loading @@ -2279,9 +2375,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { uidRules = RULE_REJECT_METERED; } else if (mRestrictBackground) { if (!uidForeground) { // uid in background, and global background disabled // uid in background, global background disabled, and this uid is not on the white // list of those allowed background access while global background is disabled if (!mRestrictBackgroundWhitelistUids.get(uid)) { uidRules = RULE_REJECT_METERED; } } } else if (mRestrictPower) { final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId) || mPowerSaveTempWhitelistAppIds.get(appId); Loading Loading @@ -2642,4 +2741,23 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } private class MyPackageMonitor extends PackageMonitor { @Override public void onPackageRemoved(String packageName, int uid) { if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } @Override public void onPackageRemovedAllUsers(String packageName, int uid) { if (LOGV) Slog.v(TAG, "onPackageRemovedAllUsers: " + packageName + " ->" + uid); synchronized (mRulesLock) { removeRestrictBackgroundWhitelistedUidLocked(uid); } } } }