Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b23389f authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Added API to whitelist apps for background restriction."

parents 076de3c5 b85a637e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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);
+121 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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";
@@ -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. */
@@ -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.

@@ -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) {
@@ -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);
@@ -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;

@@ -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) {
@@ -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;
                    }

                }
            }

@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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);
            }
        }
    }
}