OSDN Git Service

Add pre-defined apps to the restrict background whitelist.
authorFelipe Leme <felipeal@google.com>
Fri, 26 Feb 2016 18:28:41 +0000 (10:28 -0800)
committerFelipe Leme <felipeal@google.com>
Fri, 26 Feb 2016 21:37:21 +0000 (13:37 -0800)
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
<revoked-restrict-background> 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

services/core/java/com/android/server/SystemConfig.java
services/core/java/com/android/server/net/NetworkPolicyManagerService.java

index 7bdd3e2..1c1784e 100644 (file)
@@ -101,6 +101,10 @@ public class SystemConfig {
     // background while in power save mode, as read from the configuration files.
     final ArraySet<String> 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<String> mAllowInDataUsageSave = new ArraySet<>();
+
     // These are the app package names that should not allow IME switching.
     final ArraySet<String> mFixedImeApps = new ArraySet<>();
 
@@ -151,6 +155,10 @@ public class SystemConfig {
         return mAllowInPowerSave;
     }
 
+    public ArraySet<String> getAllowInDataUsageSave() {
+        return mAllowInDataUsageSave;
+    }
+
     public ArraySet<String> 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, "<allow-in-data-usage-save> 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) {
index fc40f9f..09b7a18 100644 (file)
@@ -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<String> 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<UserInfo> users = mUserManager.getUsers();
+        final int numberUsers = users.size();
+
+        final ArraySet<String> 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);