From a9505cc39b770a1ee4524d05efb859a9500d892f Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 26 Feb 2016 10:28:41 -0800 Subject: [PATCH] Add pre-defined apps to the restrict background whitelist. System config can defined apps to be automatically whitelisted for restricted background data, but the user can remove the whitelist. Implementation-wise, NPMS now keeps a list of UIDs in the netpolicy.xml file, and when it starts it compares the UIDs returned by SystemConfig against this list, and only whitelist them if they are not revoked. The revoked-restrict-background is then updated as users change the whitelist status of UIDs. BUG: 27366993 Change-Id: I427024fd058924fc9831e409da6636e1bf8e4219 --- .../core/java/com/android/server/SystemConfig.java | 19 ++++ .../server/net/NetworkPolicyManagerService.java | 117 ++++++++++++++++++++- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index 7bdd3e2c6e05..1c1784ec3668 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -101,6 +101,10 @@ public class SystemConfig { // background while in power save mode, as read from the configuration files. final ArraySet mAllowInPowerSave = new ArraySet<>(); + // These are the packages that are white-listed to be able to run in the + // background while in data-usage save mode, as read from the configuration files. + final ArraySet mAllowInDataUsageSave = new ArraySet<>(); + // These are the app package names that should not allow IME switching. final ArraySet mFixedImeApps = new ArraySet<>(); @@ -151,6 +155,10 @@ public class SystemConfig { return mAllowInPowerSave; } + public ArraySet getAllowInDataUsageSave() { + return mAllowInDataUsageSave; + } + public ArraySet getFixedImeApps() { return mFixedImeApps; } @@ -392,6 +400,17 @@ public class SystemConfig { XmlUtils.skipCurrentTag(parser); continue; + } else if ("allow-in-data-usage-save".equals(name) && allowAll) { + String pkgname = parser.getAttributeValue(null, "package"); + if (pkgname == null) { + Slog.w(TAG, " without package in " + permFile + + " at " + parser.getPositionDescription()); + } else { + mAllowInDataUsageSave.add(pkgname); + } + XmlUtils.skipCurrentTag(parser); + continue; + } else if ("fixed-ime-app".equals(name) && allowAll) { String pkgname = parser.getAttributeValue(null, "package"); if (pkgname == null) { diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index fc40f9f9a7de..09b7a18af40f 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -28,6 +28,7 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_ADDED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; + import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIMAX; @@ -165,6 +166,7 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.server.DeviceIdleController; import com.android.server.EventLogTags; import com.android.server.LocalServices; +import com.android.server.SystemConfig; import com.google.android.collect.Lists; import org.xmlpull.v1.XmlPullParser; @@ -221,6 +223,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background"; private static final String ATTR_VERSION = "version"; private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; @@ -316,6 +319,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray(); + /** + * UIDs that have been initially white-listed by system to avoid restricted background. + */ + private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids = + new SparseBooleanArray(); + + /** + * UIDs that have been initially white-listed by system to avoid restricted background, + * but later revoked by user. + */ + private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids = + new SparseBooleanArray(); + /** Set of ifaces that are metered. */ private ArraySet mMeteredIfaces = new ArraySet<>(); /** Set of over-limit templates that have been notified. */ @@ -412,6 +428,53 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + /** + * Whitelists pre-defined apps for restrict background, but only if the user didn't already + * revoke the whitelist. + * + * @return whether any uid has been added to {@link #mRestrictBackgroundWhitelistUids}. + */ + boolean addDefaultRestrictBackgroundWhitelistUids() { + final SystemConfig sysConfig = SystemConfig.getInstance(); + final PackageManager pm = mContext.getPackageManager(); + final List users = mUserManager.getUsers(); + final int numberUsers = users.size(); + + final ArraySet allowDataUsage = sysConfig.getAllowInDataUsageSave(); + boolean changed = false; + for (int i = 0; i < allowDataUsage.size(); i++) { + final String pkg = allowDataUsage.valueAt(i); + if (LOGD) + Slog.d(TAG, "checking restricted background whitelisting for package " + pkg); + final ApplicationInfo app; + try { + app = pm.getApplicationInfo(pkg, PackageManager.MATCH_SYSTEM_ONLY); + } catch (PackageManager.NameNotFoundException e) { + // Should not happen + Slog.wtf(TAG, "No ApplicationInfo for package " + pkg); + continue; + } + if (!app.isPrivilegedApp()) { + Slog.w(TAG, "getAllowInDataUsageSave() returned non-privileged app: " + pkg); + continue; + } + for (int j = 0; j < numberUsers; j++) { + final UserInfo user = users.get(i); + final int uid = UserHandle.getUid(user.id, app.uid); + mDefaultRestrictBackgroundWhitelistUids.append(uid, true); + if (LOGD) Slog.d(TAG, "revoked whistelist status for uid " + uid + ": " + + mRestrictBackgroundWhitelistRevokedUids.get(uid)); + if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) { + Slog.i(TAG, "adding default package " + pkg + " (uid " + uid + " for user " + + user.id + ") to restrict background whitelist"); + mRestrictBackgroundWhitelistUids.append(uid, true); + changed = true; + } + } + } + return changed; + } + void updatePowerSaveTempWhitelistLocked() { try { // Clear the states of the current whitelist @@ -473,6 +536,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // read policy from disk readPolicyLocked(); + if (addDefaultRestrictBackgroundWhitelistUids()) { + writePolicyLocked(); + } + updateRulesForGlobalChangeLocked(false); updateNotificationsLocked(); } @@ -1421,6 +1488,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { final int uid = readIntAttribute(in, ATTR_UID); mRestrictBackgroundWhitelistUids.put(uid, true); + } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { + final int uid = readIntAttribute(in, ATTR_UID); + mRestrictBackgroundWhitelistRevokedUids.put(uid, true); } } else if (type == END_TAG) { if (TAG_WHITELIST.equals(tag)) { @@ -1519,7 +1589,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { out.startTag(null, TAG_WHITELIST); // restrict background whitelist - final int size = mRestrictBackgroundWhitelistUids.size(); + int size = mRestrictBackgroundWhitelistUids.size(); for (int i = 0; i < size; i++) { final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); out.startTag(null, TAG_RESTRICT_BACKGROUND); @@ -1527,6 +1597,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { out.endTag(null, TAG_RESTRICT_BACKGROUND); } + // revoked restrict background whitelist + size = mRestrictBackgroundWhitelistRevokedUids.size(); + for (int i = 0; i < size; i++) { + final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); + out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); + writeIntAttribute(out, ATTR_UID, uid); + out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); + } + out.endTag(null, TAG_WHITELIST); out.endDocument(); @@ -1844,6 +1923,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); mRestrictBackgroundWhitelistUids.append(uid, true); + if (mDefaultRestrictBackgroundWhitelistUids.get(uid) + && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { + if (LOGD) Slog.d(TAG, "Removing uid " + uid + + " from revoked restrict background whitelist"); + mRestrictBackgroundWhitelistRevokedUids.delete(uid); + } changed = mRestrictBackground && !oldStatus; if (changed && hasInternetPermissions(uid)) { setUidNetworkRules(uid, false); @@ -1879,6 +1964,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); final boolean changed = mRestrictBackground && oldStatus; mRestrictBackgroundWhitelistUids.delete(uid); + if (mDefaultRestrictBackgroundWhitelistUids.get(uid) + && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { + if (LOGD) Slog.d(TAG, "Adding uid " + uid + + " to revoked restrict background whitelist"); + mRestrictBackgroundWhitelistRevokedUids.append(uid, true); + } if (updateNow) { if (changed && hasInternetPermissions(uid)) { setUidNetworkRules(uid, true); @@ -2125,6 +2216,30 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } + size = mDefaultRestrictBackgroundWhitelistUids.size(); + if (size > 0) { + fout.println("Default restrict background whitelist uids:"); + fout.increaseIndent(); + for (int i = 0; i < size; i++) { + fout.print("UID="); + fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); + fout.println(); + } + fout.decreaseIndent(); + } + + size = mRestrictBackgroundWhitelistRevokedUids.size(); + if (size > 0) { + fout.println("Default restrict background whitelist uids revoked by users:"); + fout.increaseIndent(); + for (int i = 0; i < size; i++) { + fout.print("UID="); + fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); + fout.println(); + } + fout.decreaseIndent(); + } + final SparseBooleanArray knownUids = new SparseBooleanArray(); collectKeys(mUidState, knownUids); collectKeys(mUidRules, knownUids); -- 2.11.0