Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.net;
     18 
     19 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
     20 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
     21 import static android.Manifest.permission.DUMP;
     22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
     23 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
     24 import static android.Manifest.permission.READ_PHONE_STATE;
     25 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
     26 import static android.content.Intent.ACTION_PACKAGE_ADDED;
     27 import static android.content.Intent.ACTION_UID_REMOVED;
     28 import static android.content.Intent.ACTION_USER_ADDED;
     29 import static android.content.Intent.ACTION_USER_REMOVED;
     30 import static android.content.Intent.EXTRA_UID;
     31 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
     32 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
     33 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
     34 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
     35 import static android.net.ConnectivityManager.TYPE_MOBILE;
     36 import static android.net.ConnectivityManager.TYPE_WIMAX;
     37 import static android.net.ConnectivityManager.isNetworkTypeMobile;
     38 import static android.net.NetworkPolicy.CYCLE_NONE;
     39 import static android.net.NetworkPolicy.LIMIT_DISABLED;
     40 import static android.net.NetworkPolicy.SNOOZE_NEVER;
     41 import static android.net.NetworkPolicy.WARNING_DISABLED;
     42 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
     43 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
     44 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE;
     45 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
     46 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
     47 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
     48 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
     49 import static android.net.NetworkPolicyManager.POLICY_NONE;
     50 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
     51 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
     52 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
     53 import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
     54 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
     55 import static android.net.NetworkPolicyManager.RULE_NONE;
     56 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
     57 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
     58 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
     59 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
     60 import static android.net.NetworkPolicyManager.uidRulesToString;
     61 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
     62 import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
     63 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
     64 import static android.net.NetworkTemplate.MATCH_WIFI;
     65 import static android.net.NetworkTemplate.buildTemplateMobileAll;
     66 import static android.net.TrafficStats.MB_IN_BYTES;
     67 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
     68 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
     69 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
     70 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
     71 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
     72 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
     73 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
     74 import static android.text.format.DateUtils.DAY_IN_MILLIS;
     75 
     76 import static com.android.internal.util.ArrayUtils.appendInt;
     77 import static com.android.internal.util.Preconditions.checkNotNull;
     78 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
     79 import static com.android.internal.util.XmlUtils.readIntAttribute;
     80 import static com.android.internal.util.XmlUtils.readLongAttribute;
     81 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
     82 import static com.android.internal.util.XmlUtils.writeIntAttribute;
     83 import static com.android.internal.util.XmlUtils.writeLongAttribute;
     84 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
     85 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
     86 
     87 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     88 import static org.xmlpull.v1.XmlPullParser.END_TAG;
     89 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     90 
     91 import android.Manifest;
     92 import android.annotation.IntDef;
     93 import android.annotation.Nullable;
     94 import android.app.ActivityManager;
     95 import android.app.AppGlobals;
     96 import android.app.AppOpsManager;
     97 import android.app.IActivityManager;
     98 import android.app.INotificationManager;
     99 import android.app.IUidObserver;
    100 import android.app.Notification;
    101 import android.app.PendingIntent;
    102 import android.app.usage.UsageStatsManagerInternal;
    103 import android.content.BroadcastReceiver;
    104 import android.content.ComponentName;
    105 import android.content.Context;
    106 import android.content.Intent;
    107 import android.content.IntentFilter;
    108 import android.content.pm.ApplicationInfo;
    109 import android.content.pm.IPackageManager;
    110 import android.content.pm.PackageManager;
    111 import android.content.pm.PackageManager.NameNotFoundException;
    112 import android.content.pm.UserInfo;
    113 import android.content.res.Resources;
    114 import android.net.ConnectivityManager;
    115 import android.net.IConnectivityManager;
    116 import android.net.INetworkManagementEventObserver;
    117 import android.net.INetworkPolicyListener;
    118 import android.net.INetworkPolicyManager;
    119 import android.net.INetworkStatsService;
    120 import android.net.LinkProperties;
    121 import android.net.NetworkIdentity;
    122 import android.net.NetworkInfo;
    123 import android.net.NetworkPolicy;
    124 import android.net.NetworkPolicyManager;
    125 import android.net.NetworkQuotaInfo;
    126 import android.net.NetworkState;
    127 import android.net.NetworkTemplate;
    128 import android.net.wifi.WifiConfiguration;
    129 import android.net.wifi.WifiInfo;
    130 import android.net.wifi.WifiManager;
    131 import android.os.Binder;
    132 import android.os.Environment;
    133 import android.os.Handler;
    134 import android.os.HandlerThread;
    135 import android.os.IDeviceIdleController;
    136 import android.os.INetworkManagementService;
    137 import android.os.Message;
    138 import android.os.MessageQueue.IdleHandler;
    139 import android.os.PowerManager;
    140 import android.os.PowerManagerInternal;
    141 import android.os.RemoteCallbackList;
    142 import android.os.RemoteException;
    143 import android.os.ResultReceiver;
    144 import android.os.ServiceManager;
    145 import android.os.Trace;
    146 import android.os.UserHandle;
    147 import android.os.UserManager;
    148 import android.provider.Settings;
    149 import android.telephony.SubscriptionManager;
    150 import android.telephony.TelephonyManager;
    151 import android.text.format.Formatter;
    152 import android.text.format.Time;
    153 import android.util.ArrayMap;
    154 import android.util.ArraySet;
    155 import android.util.AtomicFile;
    156 import android.util.DebugUtils;
    157 import android.util.Log;
    158 import android.util.NtpTrustedTime;
    159 import android.util.Pair;
    160 import android.util.Slog;
    161 import android.util.SparseBooleanArray;
    162 import android.util.SparseIntArray;
    163 import android.util.TrustedTime;
    164 import android.util.Xml;
    165 
    166 import com.android.internal.R;
    167 import com.android.internal.annotations.GuardedBy;
    168 import com.android.internal.annotations.VisibleForTesting;
    169 import com.android.internal.util.ArrayUtils;
    170 import com.android.internal.util.FastXmlSerializer;
    171 import com.android.internal.util.IndentingPrintWriter;
    172 import com.android.server.DeviceIdleController;
    173 import com.android.server.EventLogTags;
    174 import com.android.server.LocalServices;
    175 import com.android.server.SystemConfig;
    176 
    177 import libcore.io.IoUtils;
    178 
    179 import com.google.android.collect.Lists;
    180 
    181 import org.xmlpull.v1.XmlPullParser;
    182 import org.xmlpull.v1.XmlPullParserException;
    183 import org.xmlpull.v1.XmlSerializer;
    184 
    185 import java.io.File;
    186 import java.io.FileDescriptor;
    187 import java.io.FileInputStream;
    188 import java.io.FileNotFoundException;
    189 import java.io.FileOutputStream;
    190 import java.io.IOException;
    191 import java.io.PrintWriter;
    192 import java.lang.annotation.Retention;
    193 import java.lang.annotation.RetentionPolicy;
    194 import java.nio.charset.StandardCharsets;
    195 import java.util.ArrayList;
    196 import java.util.Arrays;
    197 import java.util.List;
    198 
    199 /**
    200  * Service that maintains low-level network policy rules, using
    201  * {@link NetworkStatsService} statistics to drive those rules.
    202  * <p>
    203  * Derives active rules by combining a given policy with other system status,
    204  * and delivers to listeners, such as {@link ConnectivityManager}, for
    205  * enforcement.
    206  *
    207  * <p>
    208  * This class uses 2-3 locks to synchronize state:
    209  * <ul>
    210  * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
    211  * rules).
    212  * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
    213  * as network policies).
    214  * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks
    215  * must be held.
    216  * </ul>
    217  *
    218  * <p>
    219  * As such, methods that require synchronization have the following prefixes:
    220  * <ul>
    221  * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
    222  * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
    223  * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
    224  * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
    225  * </ul>
    226  */
    227 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    228     static final String TAG = "NetworkPolicy";
    229     private static final boolean LOGD = false;
    230     private static final boolean LOGV = false;
    231 
    232     private static final int VERSION_INIT = 1;
    233     private static final int VERSION_ADDED_SNOOZE = 2;
    234     private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
    235     private static final int VERSION_ADDED_METERED = 4;
    236     private static final int VERSION_SPLIT_SNOOZE = 5;
    237     private static final int VERSION_ADDED_TIMEZONE = 6;
    238     private static final int VERSION_ADDED_INFERRED = 7;
    239     private static final int VERSION_SWITCH_APP_ID = 8;
    240     private static final int VERSION_ADDED_NETWORK_ID = 9;
    241     private static final int VERSION_SWITCH_UID = 10;
    242     private static final int VERSION_LATEST = VERSION_SWITCH_UID;
    243 
    244     @VisibleForTesting
    245     public static final int TYPE_WARNING = 0x1;
    246     @VisibleForTesting
    247     public static final int TYPE_LIMIT = 0x2;
    248     @VisibleForTesting
    249     public static final int TYPE_LIMIT_SNOOZED = 0x3;
    250 
    251     private static final String TAG_POLICY_LIST = "policy-list";
    252     private static final String TAG_NETWORK_POLICY = "network-policy";
    253     private static final String TAG_UID_POLICY = "uid-policy";
    254     private static final String TAG_APP_POLICY = "app-policy";
    255     private static final String TAG_WHITELIST = "whitelist";
    256     private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
    257     private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
    258 
    259     private static final String ATTR_VERSION = "version";
    260     private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
    261     private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
    262     private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
    263     private static final String ATTR_NETWORK_ID = "networkId";
    264     private static final String ATTR_CYCLE_DAY = "cycleDay";
    265     private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
    266     private static final String ATTR_WARNING_BYTES = "warningBytes";
    267     private static final String ATTR_LIMIT_BYTES = "limitBytes";
    268     private static final String ATTR_LAST_SNOOZE = "lastSnooze";
    269     private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
    270     private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
    271     private static final String ATTR_METERED = "metered";
    272     private static final String ATTR_INFERRED = "inferred";
    273     private static final String ATTR_UID = "uid";
    274     private static final String ATTR_APP_ID = "appId";
    275     private static final String ATTR_POLICY = "policy";
    276 
    277     private static final String ACTION_ALLOW_BACKGROUND =
    278             "com.android.server.net.action.ALLOW_BACKGROUND";
    279     private static final String ACTION_SNOOZE_WARNING =
    280             "com.android.server.net.action.SNOOZE_WARNING";
    281 
    282     private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
    283 
    284     private static final int MSG_RULES_CHANGED = 1;
    285     private static final int MSG_METERED_IFACES_CHANGED = 2;
    286     private static final int MSG_LIMIT_REACHED = 5;
    287     private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
    288     private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
    289     private static final int MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED = 9;
    290     private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
    291     private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
    292     private static final int MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED = 12;
    293     private static final int MSG_SET_FIREWALL_RULES = 13;
    294 
    295     private final Context mContext;
    296     private final IActivityManager mActivityManager;
    297     private final INetworkStatsService mNetworkStats;
    298     private final INetworkManagementService mNetworkManager;
    299     private UsageStatsManagerInternal mUsageStats;
    300     private final TrustedTime mTime;
    301     private final UserManager mUserManager;
    302 
    303     private IConnectivityManager mConnManager;
    304     private INotificationManager mNotifManager;
    305     private PowerManagerInternal mPowerManagerInternal;
    306     private IDeviceIdleController mDeviceIdleController;
    307 
    308     // See main javadoc for instructions on how to use these locks.
    309     final Object mUidRulesFirstLock = new Object();
    310     final Object mNetworkPoliciesSecondLock = new Object();
    311 
    312     @GuardedBy("allLocks") volatile boolean mSystemReady;
    313 
    314     @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
    315     @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
    316     @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
    317 
    318     private final boolean mSuppressDefaultPolicy;
    319 
    320     /** Defined network policies. */
    321     final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
    322     /** Currently active network rules for ifaces. */
    323     final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
    324 
    325     /** Defined UID policies. */
    326     @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
    327     /** Currently derived rules for each UID. */
    328     @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
    329 
    330     @GuardedBy("mUidRulesFirstLock")
    331     final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
    332     @GuardedBy("mUidRulesFirstLock")
    333     final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
    334     @GuardedBy("mUidRulesFirstLock")
    335     final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
    336 
    337     /** Set of states for the child firewall chains. True if the chain is active. */
    338     @GuardedBy("mUidRulesFirstLock")
    339     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
    340 
    341     /**
    342      * UIDs that have been white-listed to always be able to have network access
    343      * in power save mode, except device idle (doze) still applies.
    344      * TODO: An int array might be sufficient
    345      */
    346     @GuardedBy("mUidRulesFirstLock")
    347     private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
    348 
    349     /**
    350      * UIDs that have been white-listed to always be able to have network access
    351      * in power save mode.
    352      * TODO: An int array might be sufficient
    353      */
    354     @GuardedBy("mUidRulesFirstLock")
    355     private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
    356 
    357     @GuardedBy("mUidRulesFirstLock")
    358     private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
    359 
    360     /**
    361      * UIDs that have been white-listed to avoid restricted background.
    362      */
    363     @GuardedBy("mUidRulesFirstLock")
    364     private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray();
    365 
    366     /**
    367      * UIDs that have been initially white-listed by system to avoid restricted background.
    368      */
    369     @GuardedBy("mUidRulesFirstLock")
    370     private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
    371             new SparseBooleanArray();
    372 
    373     /**
    374      * UIDs that have been initially white-listed by system to avoid restricted background,
    375      * but later revoked by user.
    376      */
    377     @GuardedBy("mUidRulesFirstLock")
    378     private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
    379             new SparseBooleanArray();
    380 
    381     /** Set of ifaces that are metered. */
    382     @GuardedBy("mNetworkPoliciesSecondLock")
    383     private ArraySet<String> mMeteredIfaces = new ArraySet<>();
    384     /** Set of over-limit templates that have been notified. */
    385     @GuardedBy("mNetworkPoliciesSecondLock")
    386     private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
    387 
    388     /** Set of currently active {@link Notification} tags. */
    389     @GuardedBy("mNetworkPoliciesSecondLock")
    390     private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
    391 
    392     /** Foreground at UID granularity. */
    393     @GuardedBy("mUidRulesFirstLock")
    394     final SparseIntArray mUidState = new SparseIntArray();
    395 
    396     /** Higher priority listener before general event dispatch */
    397     private INetworkPolicyListener mConnectivityListener;
    398 
    399     private final RemoteCallbackList<INetworkPolicyListener>
    400             mListeners = new RemoteCallbackList<>();
    401 
    402     final Handler mHandler;
    403 
    404     @GuardedBy("allLocks")
    405     private final AtomicFile mPolicyFile;
    406 
    407     private final AppOpsManager mAppOps;
    408 
    409     private final IPackageManager mIPm;
    410 
    411 
    412     // TODO: keep whitelist of system-critical services that should never have
    413     // rules enforced, such as system, phone, and radio UIDs.
    414 
    415     // TODO: migrate notifications to SystemUI
    416 
    417     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
    418             INetworkStatsService networkStats, INetworkManagementService networkManagement) {
    419         this(context, activityManager, networkStats, networkManagement,
    420                 NtpTrustedTime.getInstance(context), getSystemDir(), false);
    421     }
    422 
    423     private static File getSystemDir() {
    424         return new File(Environment.getDataDirectory(), "system");
    425     }
    426 
    427     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
    428             INetworkStatsService networkStats, INetworkManagementService networkManagement,
    429             TrustedTime time, File systemDir, boolean suppressDefaultPolicy) {
    430         mContext = checkNotNull(context, "missing context");
    431         mActivityManager = checkNotNull(activityManager, "missing activityManager");
    432         mNetworkStats = checkNotNull(networkStats, "missing networkStats");
    433         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
    434         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
    435                 Context.DEVICE_IDLE_CONTROLLER));
    436         mTime = checkNotNull(time, "missing TrustedTime");
    437         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    438         mIPm = AppGlobals.getPackageManager();
    439 
    440         HandlerThread thread = new HandlerThread(TAG);
    441         thread.start();
    442         mHandler = new Handler(thread.getLooper(), mHandlerCallback);
    443 
    444         mSuppressDefaultPolicy = suppressDefaultPolicy;
    445 
    446         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
    447 
    448         mAppOps = context.getSystemService(AppOpsManager.class);
    449 
    450         // Expose private service for system components to use.
    451         LocalServices.addService(NetworkPolicyManagerInternal.class,
    452                 new NetworkPolicyManagerInternalImpl());
    453     }
    454 
    455     public void bindConnectivityManager(IConnectivityManager connManager) {
    456         mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
    457     }
    458 
    459     public void bindNotificationManager(INotificationManager notifManager) {
    460         mNotifManager = checkNotNull(notifManager, "missing INotificationManager");
    461     }
    462 
    463     void updatePowerSaveWhitelistUL() {
    464         try {
    465             int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
    466             mPowerSaveWhitelistExceptIdleAppIds.clear();
    467             if (whitelist != null) {
    468                 for (int uid : whitelist) {
    469                     mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
    470                 }
    471             }
    472             whitelist = mDeviceIdleController.getAppIdWhitelist();
    473             mPowerSaveWhitelistAppIds.clear();
    474             if (whitelist != null) {
    475                 for (int uid : whitelist) {
    476                     mPowerSaveWhitelistAppIds.put(uid, true);
    477                 }
    478             }
    479         } catch (RemoteException e) {
    480         }
    481     }
    482 
    483     /**
    484      * Whitelists pre-defined apps for restrict background, but only if the user didn't already
    485      * revoke the whitelist.
    486      *
    487      * @return whether any uid has been added to {@link #mRestrictBackgroundWhitelistUids}.
    488      */
    489     boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
    490         final List<UserInfo> users = mUserManager.getUsers();
    491         final int numberUsers = users.size();
    492 
    493         boolean changed = false;
    494         for (int i = 0; i < numberUsers; i++) {
    495             final UserInfo user = users.get(i);
    496             changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
    497         }
    498         return changed;
    499     }
    500 
    501     private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
    502         final SystemConfig sysConfig = SystemConfig.getInstance();
    503         final PackageManager pm = mContext.getPackageManager();
    504         final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
    505         boolean changed = false;
    506         for (int i = 0; i < allowDataUsage.size(); i++) {
    507             final String pkg = allowDataUsage.valueAt(i);
    508             if (LOGD)
    509                 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
    510                         + " and user " + userId);
    511             final ApplicationInfo app;
    512             try {
    513                 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
    514             } catch (PackageManager.NameNotFoundException e) {
    515                 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
    516                 // Ignore it - some apps on allow-in-data-usage-save are optional.
    517                 continue;
    518             }
    519             if (!app.isPrivilegedApp()) {
    520                 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
    521                         + "skipping non-privileged app  " + pkg);
    522                 continue;
    523             }
    524             final int uid = UserHandle.getUid(userId, app.uid);
    525             mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
    526             if (LOGD)
    527                 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
    528                         + "background whitelist. Revoked status: "
    529                         + mRestrictBackgroundWhitelistRevokedUids.get(uid));
    530             if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
    531                 if (LOGD)
    532                     Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
    533                             + userId + ") to restrict background whitelist");
    534                 mRestrictBackgroundWhitelistUids.append(uid, true);
    535                 changed = true;
    536             }
    537         }
    538         return changed;
    539     }
    540 
    541     void updatePowerSaveTempWhitelistUL() {
    542         try {
    543             // Clear the states of the current whitelist
    544             final int N = mPowerSaveTempWhitelistAppIds.size();
    545             for (int i = 0; i < N; i++) {
    546                 mPowerSaveTempWhitelistAppIds.setValueAt(i, false);
    547             }
    548             // Update the states with the new whitelist
    549             final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist();
    550             if (whitelist != null) {
    551                 for (int uid : whitelist) {
    552                     mPowerSaveTempWhitelistAppIds.put(uid, true);
    553                 }
    554             }
    555         } catch (RemoteException e) {
    556         }
    557     }
    558 
    559     /**
    560      * Remove unnecessary entries in the temp whitelist
    561      */
    562     void purgePowerSaveTempWhitelistUL() {
    563         final int N = mPowerSaveTempWhitelistAppIds.size();
    564         for (int i = N - 1; i >= 0; i--) {
    565             if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) {
    566                 mPowerSaveTempWhitelistAppIds.removeAt(i);
    567             }
    568         }
    569     }
    570 
    571     public void systemReady() {
    572         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
    573         try {
    574             if (!isBandwidthControlEnabled()) {
    575                 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
    576                 return;
    577             }
    578 
    579             mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
    580 
    581             synchronized (mUidRulesFirstLock) {
    582                 synchronized (mNetworkPoliciesSecondLock) {
    583                     updatePowerSaveWhitelistUL();
    584                     mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
    585                     mPowerManagerInternal.registerLowPowerModeObserver(
    586                             new PowerManagerInternal.LowPowerModeListener() {
    587                         @Override
    588                         public void onLowPowerModeChanged(boolean enabled) {
    589                             if (LOGD) Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
    590                             synchronized (mUidRulesFirstLock) {
    591                                 if (mRestrictPower != enabled) {
    592                                     mRestrictPower = enabled;
    593                                     updateRulesForRestrictPowerUL();
    594                                 }
    595                             }
    596                         }
    597                     });
    598                     mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
    599 
    600                     mSystemReady = true;
    601 
    602                     // read policy from disk
    603                     readPolicyAL();
    604 
    605                     if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
    606                         writePolicyAL();
    607                     }
    608 
    609                     setRestrictBackgroundUL(mRestrictBackground);
    610                     updateRulesForGlobalChangeAL(false);
    611                     updateNotificationsNL();
    612                 }
    613             }
    614 
    615             try {
    616                 mActivityManager.registerUidObserver(mUidObserver,
    617                         ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE);
    618                 mNetworkManager.registerObserver(mAlertObserver);
    619             } catch (RemoteException e) {
    620                 // ignored; both services live in system_server
    621             }
    622 
    623             // listen for changes to power save whitelist
    624             final IntentFilter whitelistFilter = new IntentFilter(
    625                     PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
    626             mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
    627 
    628             DeviceIdleController.LocalService deviceIdleService
    629                     = LocalServices.getService(DeviceIdleController.LocalService.class);
    630             deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
    631 
    632             // watch for network interfaces to be claimed
    633             final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
    634             mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
    635 
    636             // listen for package changes to update policy
    637             final IntentFilter packageFilter = new IntentFilter();
    638             packageFilter.addAction(ACTION_PACKAGE_ADDED);
    639             packageFilter.addDataScheme("package");
    640             mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
    641 
    642             // listen for UID changes to update policy
    643             mContext.registerReceiver(
    644                     mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
    645 
    646             // listen for user changes to update policy
    647             final IntentFilter userFilter = new IntentFilter();
    648             userFilter.addAction(ACTION_USER_ADDED);
    649             userFilter.addAction(ACTION_USER_REMOVED);
    650             mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
    651 
    652             // listen for stats update events
    653             final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
    654             mContext.registerReceiver(
    655                     mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
    656 
    657             // listen for restrict background changes from notifications
    658             final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
    659             mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
    660 
    661             // listen for snooze warning from notifications
    662             final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING);
    663             mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
    664                     MANAGE_NETWORK_POLICY, mHandler);
    665 
    666             // listen for configured wifi networks to be removed
    667             final IntentFilter wifiConfigFilter =
    668                     new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
    669             mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
    670 
    671             // listen for wifi state changes to catch metered hint
    672             final IntentFilter wifiStateFilter = new IntentFilter(
    673                     WifiManager.NETWORK_STATE_CHANGED_ACTION);
    674             mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
    675 
    676             mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
    677         } finally {
    678             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
    679         }
    680     }
    681 
    682     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
    683         @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
    684             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
    685             try {
    686                 synchronized (mUidRulesFirstLock) {
    687                     updateUidStateUL(uid, procState);
    688                 }
    689             } finally {
    690                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
    691             }
    692         }
    693 
    694         @Override public void onUidGone(int uid) throws RemoteException {
    695             synchronized (mUidRulesFirstLock) {
    696                 removeUidStateUL(uid);
    697             }
    698         }
    699 
    700         @Override public void onUidActive(int uid) throws RemoteException {
    701         }
    702 
    703         @Override public void onUidIdle(int uid) throws RemoteException {
    704         }
    705     };
    706 
    707     final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
    708         @Override
    709         public void onReceive(Context context, Intent intent) {
    710             // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
    711             synchronized (mUidRulesFirstLock) {
    712                 updatePowerSaveWhitelistUL();
    713                 updateRulesForRestrictPowerUL();
    714                 updateRulesForAppIdleUL();
    715             }
    716         }
    717     };
    718 
    719     final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
    720         @Override
    721         public void run() {
    722             synchronized (mUidRulesFirstLock) {
    723                 updatePowerSaveTempWhitelistUL();
    724                 updateRulesForTempWhitelistChangeUL();
    725                 purgePowerSaveTempWhitelistUL();
    726             }
    727         }
    728     };
    729 
    730     final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
    731         @Override
    732         public void onReceive(Context context, Intent intent) {
    733             // on background handler thread, and PACKAGE_ADDED is protected
    734 
    735             final String action = intent.getAction();
    736             final int uid = intent.getIntExtra(EXTRA_UID, -1);
    737             if (uid == -1) return;
    738 
    739             if (ACTION_PACKAGE_ADDED.equals(action)) {
    740                 // update rules for UID, since it might be subject to
    741                 // global background data policy
    742                 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
    743                 synchronized (mUidRulesFirstLock) {
    744                     updateRestrictionRulesForUidUL(uid);
    745                 }
    746             }
    747         }
    748     };
    749 
    750     final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
    751         @Override
    752         public void onReceive(Context context, Intent intent) {
    753             // on background handler thread, and UID_REMOVED is protected
    754 
    755             final int uid = intent.getIntExtra(EXTRA_UID, -1);
    756             if (uid == -1) return;
    757 
    758             // remove any policy and update rules to clean up
    759             if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
    760             synchronized (mUidRulesFirstLock) {
    761                 mUidPolicy.delete(uid);
    762                 removeRestrictBackgroundWhitelistedUidUL(uid, true, true);
    763                 updateRestrictionRulesForUidUL(uid);
    764                 synchronized (mNetworkPoliciesSecondLock) {
    765                     writePolicyAL();
    766                 }
    767             }
    768         }
    769     };
    770 
    771     final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
    772         @Override
    773         public void onReceive(Context context, Intent intent) {
    774             // on background handler thread, and USER_ADDED and USER_REMOVED
    775             // broadcasts are protected
    776 
    777             final String action = intent.getAction();
    778             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
    779             if (userId == -1) return;
    780 
    781             switch (action) {
    782                 case ACTION_USER_REMOVED:
    783                 case ACTION_USER_ADDED:
    784                     synchronized (mUidRulesFirstLock) {
    785                         // Remove any persistable state for the given user; both cleaning up after a
    786                         // USER_REMOVED, and one last sanity check during USER_ADDED
    787                         removeUserStateUL(userId, true);
    788                         if (action == ACTION_USER_ADDED) {
    789                             // Add apps that are whitelisted by default.
    790                             addDefaultRestrictBackgroundWhitelistUidsUL(userId);
    791                         }
    792                         // Update global restrict for that user
    793                         synchronized (mNetworkPoliciesSecondLock) {
    794                             updateRulesForGlobalChangeAL(true);
    795                         }
    796                     }
    797                     break;
    798             }
    799         }
    800     };
    801 
    802     /**
    803      * Receiver that watches for {@link INetworkStatsService} updates, which we
    804      * use to check against {@link NetworkPolicy#warningBytes}.
    805      */
    806     final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
    807         @Override
    808         public void onReceive(Context context, Intent intent) {
    809             // on background handler thread, and verified
    810             // READ_NETWORK_USAGE_HISTORY permission above.
    811 
    812             maybeRefreshTrustedTime();
    813             synchronized (mNetworkPoliciesSecondLock) {
    814                 updateNetworkEnabledNL();
    815                 updateNotificationsNL();
    816             }
    817         }
    818     };
    819 
    820     /**
    821      * Receiver that watches for {@link Notification} control of
    822      * {@link #mRestrictBackground}.
    823      */
    824     final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
    825         @Override
    826         public void onReceive(Context context, Intent intent) {
    827             // on background handler thread, and verified MANAGE_NETWORK_POLICY
    828             // permission above.
    829 
    830             setRestrictBackground(false);
    831         }
    832     };
    833 
    834     /**
    835      * Receiver that watches for {@link Notification} control of
    836      * {@link NetworkPolicy#lastWarningSnooze}.
    837      */
    838     final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
    839         @Override
    840         public void onReceive(Context context, Intent intent) {
    841             // on background handler thread, and verified MANAGE_NETWORK_POLICY
    842             // permission above.
    843 
    844             final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
    845             performSnooze(template, TYPE_WARNING);
    846         }
    847     };
    848 
    849     /**
    850      * Receiver that watches for {@link WifiConfiguration} to be changed.
    851      */
    852     final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
    853         @Override
    854         public void onReceive(Context context, Intent intent) {
    855             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    856             // permission above.
    857 
    858             final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED);
    859             if (reason == CHANGE_REASON_REMOVED) {
    860                 final WifiConfiguration config = intent.getParcelableExtra(
    861                         EXTRA_WIFI_CONFIGURATION);
    862                 if (config.SSID != null) {
    863                     final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID);
    864                     synchronized (mUidRulesFirstLock) {
    865                         synchronized (mNetworkPoliciesSecondLock) {
    866                             if (mNetworkPolicy.containsKey(template)) {
    867                                 mNetworkPolicy.remove(template);
    868                                 writePolicyAL();
    869                             }
    870                         }
    871                     }
    872                 }
    873             }
    874         }
    875     };
    876 
    877     /**
    878      * Receiver that watches {@link WifiInfo} state changes to infer metered
    879      * state. Ignores hints when policy is user-defined.
    880      */
    881     final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
    882         @Override
    883         public void onReceive(Context context, Intent intent) {
    884             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    885             // permission above.
    886 
    887             // ignore when not connected
    888             final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
    889             if (!netInfo.isConnected()) return;
    890 
    891             final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO);
    892             final boolean meteredHint = info.getMeteredHint();
    893 
    894             final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID());
    895             synchronized (mNetworkPoliciesSecondLock) {
    896                 NetworkPolicy policy = mNetworkPolicy.get(template);
    897                 if (policy == null && meteredHint) {
    898                     // policy doesn't exist, and AP is hinting that it's
    899                     // metered: create an inferred policy.
    900                     policy = newWifiPolicy(template, meteredHint);
    901                     addNetworkPolicyNL(policy);
    902 
    903                 } else if (policy != null && policy.inferred) {
    904                     // policy exists, and was inferred: update its current
    905                     // metered state.
    906                     policy.metered = meteredHint;
    907 
    908                     // since this is inferred for each wifi session, just update
    909                     // rules without persisting.
    910                     updateNetworkRulesNL();
    911                 }
    912             }
    913         }
    914     };
    915 
    916     static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) {
    917         return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
    918                 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
    919                 metered, true);
    920     }
    921 
    922     /**
    923      * Observer that watches for {@link INetworkManagementService} alerts.
    924      */
    925     final private INetworkManagementEventObserver mAlertObserver
    926             = new BaseNetworkObserver() {
    927         @Override
    928         public void limitReached(String limitName, String iface) {
    929             // only someone like NMS should be calling us
    930             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
    931 
    932             if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
    933                 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
    934             }
    935         }
    936     };
    937 
    938     /**
    939      * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
    940      * to show visible notifications as needed.
    941      */
    942     void updateNotificationsNL() {
    943         if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
    944 
    945         // keep track of previously active notifications
    946         final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
    947         mActiveNotifs.clear();
    948 
    949         // TODO: when switching to kernel notifications, compute next future
    950         // cycle boundary to recompute notifications.
    951 
    952         // examine stats for each active policy
    953         final long currentTime = currentTimeMillis();
    954         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
    955             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
    956             // ignore policies that aren't relevant to user
    957             if (!isTemplateRelevant(policy.template)) continue;
    958             if (!policy.hasCycle()) continue;
    959 
    960             final long start = computeLastCycleBoundary(currentTime, policy);
    961             final long end = currentTime;
    962             final long totalBytes = getTotalBytes(policy.template, start, end);
    963 
    964             if (policy.isOverLimit(totalBytes)) {
    965                 if (policy.lastLimitSnooze >= start) {
    966                     enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
    967                 } else {
    968                     enqueueNotification(policy, TYPE_LIMIT, totalBytes);
    969                     notifyOverLimitNL(policy.template);
    970                 }
    971 
    972             } else {
    973                 notifyUnderLimitNL(policy.template);
    974 
    975                 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
    976                     enqueueNotification(policy, TYPE_WARNING, totalBytes);
    977                 }
    978             }
    979         }
    980 
    981         // cancel stale notifications that we didn't renew above
    982         for (int i = beforeNotifs.size()-1; i >= 0; i--) {
    983             final String tag = beforeNotifs.valueAt(i);
    984             if (!mActiveNotifs.contains(tag)) {
    985                 cancelNotification(tag);
    986             }
    987         }
    988     }
    989 
    990     /**
    991      * Test if given {@link NetworkTemplate} is relevant to user based on
    992      * current device state, such as when
    993      * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
    994      * data connection status.
    995      */
    996     private boolean isTemplateRelevant(NetworkTemplate template) {
    997         if (template.isMatchRuleMobile()) {
    998             final TelephonyManager tele = TelephonyManager.from(mContext);
    999             final SubscriptionManager sub = SubscriptionManager.from(mContext);
   1000 
   1001             // Mobile template is relevant when any active subscriber matches
   1002             final int[] subIds = sub.getActiveSubscriptionIdList();
   1003             for (int subId : subIds) {
   1004                 final String subscriberId = tele.getSubscriberId(subId);
   1005                 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
   1006                         TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
   1007                 if (template.matches(probeIdent)) {
   1008                     return true;
   1009                 }
   1010             }
   1011             return false;
   1012         } else {
   1013             return true;
   1014         }
   1015     }
   1016 
   1017     /**
   1018      * Notify that given {@link NetworkTemplate} is over
   1019      * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
   1020      */
   1021     private void notifyOverLimitNL(NetworkTemplate template) {
   1022         if (!mOverLimitNotified.contains(template)) {
   1023             mContext.startActivity(buildNetworkOverLimitIntent(template));
   1024             mOverLimitNotified.add(template);
   1025         }
   1026     }
   1027 
   1028     private void notifyUnderLimitNL(NetworkTemplate template) {
   1029         mOverLimitNotified.remove(template);
   1030     }
   1031 
   1032     /**
   1033      * Build unique tag that identifies an active {@link NetworkPolicy}
   1034      * notification of a specific type, like {@link #TYPE_LIMIT}.
   1035      */
   1036     private String buildNotificationTag(NetworkPolicy policy, int type) {
   1037         return TAG + ":" + policy.template.hashCode() + ":" + type;
   1038     }
   1039 
   1040     /**
   1041      * Show notification for combined {@link NetworkPolicy} and specific type,
   1042      * like {@link #TYPE_LIMIT}. Okay to call multiple times.
   1043      */
   1044     private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
   1045         final String tag = buildNotificationTag(policy, type);
   1046         final Notification.Builder builder = new Notification.Builder(mContext);
   1047         builder.setOnlyAlertOnce(true);
   1048         builder.setWhen(0L);
   1049         builder.setColor(mContext.getColor(
   1050                 com.android.internal.R.color.system_notification_accent_color));
   1051 
   1052         final Resources res = mContext.getResources();
   1053         switch (type) {
   1054             case TYPE_WARNING: {
   1055                 final CharSequence title = res.getText(R.string.data_usage_warning_title);
   1056                 final CharSequence body = res.getString(R.string.data_usage_warning_body);
   1057 
   1058                 builder.setSmallIcon(R.drawable.stat_notify_error);
   1059                 builder.setTicker(title);
   1060                 builder.setContentTitle(title);
   1061                 builder.setContentText(body);
   1062                 builder.setDefaults(Notification.DEFAULT_ALL);
   1063                 builder.setPriority(Notification.PRIORITY_HIGH);
   1064 
   1065                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
   1066                 builder.setDeleteIntent(PendingIntent.getBroadcast(
   1067                         mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
   1068 
   1069                 final Intent viewIntent = buildViewDataUsageIntent(policy.template);
   1070                 builder.setContentIntent(PendingIntent.getActivity(
   1071                         mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
   1072 
   1073                 break;
   1074             }
   1075             case TYPE_LIMIT: {
   1076                 final CharSequence body = res.getText(R.string.data_usage_limit_body);
   1077 
   1078                 final CharSequence title;
   1079                 int icon = R.drawable.stat_notify_disabled_data;
   1080                 switch (policy.template.getMatchRule()) {
   1081                     case MATCH_MOBILE_3G_LOWER:
   1082                         title = res.getText(R.string.data_usage_3g_limit_title);
   1083                         break;
   1084                     case MATCH_MOBILE_4G:
   1085                         title = res.getText(R.string.data_usage_4g_limit_title);
   1086                         break;
   1087                     case MATCH_MOBILE_ALL:
   1088                         title = res.getText(R.string.data_usage_mobile_limit_title);
   1089                         break;
   1090                     case MATCH_WIFI:
   1091                         title = res.getText(R.string.data_usage_wifi_limit_title);
   1092                         icon = R.drawable.stat_notify_error;
   1093                         break;
   1094                     default:
   1095                         title = null;
   1096                         break;
   1097                 }
   1098 
   1099                 builder.setOngoing(true);
   1100                 builder.setSmallIcon(icon);
   1101                 builder.setTicker(title);
   1102                 builder.setContentTitle(title);
   1103                 builder.setContentText(body);
   1104 
   1105                 final Intent intent = buildNetworkOverLimitIntent(policy.template);
   1106                 builder.setContentIntent(PendingIntent.getActivity(
   1107                         mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
   1108                 break;
   1109             }
   1110             case TYPE_LIMIT_SNOOZED: {
   1111                 final long overBytes = totalBytes - policy.limitBytes;
   1112                 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body,
   1113                         Formatter.formatFileSize(mContext, overBytes));
   1114 
   1115                 final CharSequence title;
   1116                 switch (policy.template.getMatchRule()) {
   1117                     case MATCH_MOBILE_3G_LOWER:
   1118                         title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
   1119                         break;
   1120                     case MATCH_MOBILE_4G:
   1121                         title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
   1122                         break;
   1123                     case MATCH_MOBILE_ALL:
   1124                         title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
   1125                         break;
   1126                     case MATCH_WIFI:
   1127                         title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
   1128                         break;
   1129                     default:
   1130                         title = null;
   1131                         break;
   1132                 }
   1133 
   1134                 builder.setOngoing(true);
   1135                 builder.setSmallIcon(R.drawable.stat_notify_error);
   1136                 builder.setTicker(title);
   1137                 builder.setContentTitle(title);
   1138                 builder.setContentText(body);
   1139 
   1140                 final Intent intent = buildViewDataUsageIntent(policy.template);
   1141                 builder.setContentIntent(PendingIntent.getActivity(
   1142                         mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
   1143                 break;
   1144             }
   1145         }
   1146 
   1147         // TODO: move to NotificationManager once we can mock it
   1148         try {
   1149             final String packageName = mContext.getPackageName();
   1150             final int[] idReceived = new int[1];
   1151             mNotifManager.enqueueNotificationWithTag(
   1152                     packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
   1153                     UserHandle.USER_ALL);
   1154             mActiveNotifs.add(tag);
   1155         } catch (RemoteException e) {
   1156             // ignored; service lives in system_server
   1157         }
   1158     }
   1159 
   1160     private void cancelNotification(String tag) {
   1161         // TODO: move to NotificationManager once we can mock it
   1162         try {
   1163             final String packageName = mContext.getPackageName();
   1164             mNotifManager.cancelNotificationWithTag(
   1165                     packageName, tag, 0x0, UserHandle.USER_ALL);
   1166         } catch (RemoteException e) {
   1167             // ignored; service lives in system_server
   1168         }
   1169     }
   1170 
   1171     /**
   1172      * Receiver that watches for {@link IConnectivityManager} to claim network
   1173      * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
   1174      */
   1175     private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
   1176         @Override
   1177         public void onReceive(Context context, Intent intent) {
   1178             // on background handler thread, and verified CONNECTIVITY_INTERNAL
   1179             // permission above.
   1180 
   1181             maybeRefreshTrustedTime();
   1182             synchronized (mNetworkPoliciesSecondLock) {
   1183                 ensureActiveMobilePolicyNL();
   1184                 normalizePoliciesNL();
   1185                 updateNetworkEnabledNL();
   1186                 updateNetworkRulesNL();
   1187                 updateNotificationsNL();
   1188             }
   1189         }
   1190     };
   1191 
   1192     /**
   1193      * Proactively control network data connections when they exceed
   1194      * {@link NetworkPolicy#limitBytes}.
   1195      */
   1196     void updateNetworkEnabledNL() {
   1197         if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
   1198 
   1199         // TODO: reset any policy-disabled networks when any policy is removed
   1200         // completely, which is currently rare case.
   1201 
   1202         final long currentTime = currentTimeMillis();
   1203         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   1204             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1205             // shortcut when policy has no limit
   1206             if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
   1207                 setNetworkTemplateEnabled(policy.template, true);
   1208                 continue;
   1209             }
   1210 
   1211             final long start = computeLastCycleBoundary(currentTime, policy);
   1212             final long end = currentTime;
   1213             final long totalBytes = getTotalBytes(policy.template, start, end);
   1214 
   1215             // disable data connection when over limit and not snoozed
   1216             final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
   1217                     && policy.lastLimitSnooze < start;
   1218             final boolean networkEnabled = !overLimitWithoutSnooze;
   1219 
   1220             setNetworkTemplateEnabled(policy.template, networkEnabled);
   1221         }
   1222     }
   1223 
   1224     /**
   1225      * Proactively disable networks that match the given
   1226      * {@link NetworkTemplate}.
   1227      */
   1228     private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
   1229         // TODO: reach into ConnectivityManager to proactively disable bringing
   1230         // up this network, since we know that traffic will be blocked.
   1231 
   1232         if (template.getMatchRule() == MATCH_MOBILE_ALL) {
   1233             // If mobile data usage hits the limit or if the user resumes the data, we need to
   1234             // notify telephony.
   1235             final SubscriptionManager sm = SubscriptionManager.from(mContext);
   1236             final TelephonyManager tm = TelephonyManager.from(mContext);
   1237 
   1238             final int[] subIds = sm.getActiveSubscriptionIdList();
   1239             for (int subId : subIds) {
   1240                 final String subscriberId = tm.getSubscriberId(subId);
   1241                 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
   1242                         TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
   1243                 // Template is matched when subscriber id matches.
   1244                 if (template.matches(probeIdent)) {
   1245                     tm.setPolicyDataEnabled(enabled, subId);
   1246                 }
   1247             }
   1248         }
   1249     }
   1250 
   1251     /**
   1252      * Examine all connected {@link NetworkState}, looking for
   1253      * {@link NetworkPolicy} that need to be enforced. When matches found, set
   1254      * remaining quota based on usage cycle and historical stats.
   1255      */
   1256     void updateNetworkRulesNL() {
   1257         if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
   1258 
   1259         final NetworkState[] states;
   1260         try {
   1261             states = mConnManager.getAllNetworkState();
   1262         } catch (RemoteException e) {
   1263             // ignored; service lives in system_server
   1264             return;
   1265         }
   1266 
   1267         // First, generate identities of all connected networks so we can
   1268         // quickly compare them against all defined policies below.
   1269         final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length);
   1270         final ArraySet<String> connIfaces = new ArraySet<String>(states.length);
   1271         for (NetworkState state : states) {
   1272             if (state.networkInfo != null && state.networkInfo.isConnected()) {
   1273                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   1274 
   1275                 final String baseIface = state.linkProperties.getInterfaceName();
   1276                 if (baseIface != null) {
   1277                     connIdents.add(Pair.create(baseIface, ident));
   1278                 }
   1279 
   1280                 // Stacked interfaces are considered to have same identity as
   1281                 // their parent network.
   1282                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
   1283                 for (LinkProperties stackedLink : stackedLinks) {
   1284                     final String stackedIface = stackedLink.getInterfaceName();
   1285                     if (stackedIface != null) {
   1286                         connIdents.add(Pair.create(stackedIface, ident));
   1287                     }
   1288                 }
   1289             }
   1290         }
   1291 
   1292         // Apply policies against all connected interfaces found above
   1293         mNetworkRules.clear();
   1294         final ArrayList<String> ifaceList = Lists.newArrayList();
   1295         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
   1296             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1297 
   1298             ifaceList.clear();
   1299             for (int j = connIdents.size() - 1; j >= 0; j--) {
   1300                 final Pair<String, NetworkIdentity> ident = connIdents.get(j);
   1301                 if (policy.template.matches(ident.second)) {
   1302                     ifaceList.add(ident.first);
   1303                 }
   1304             }
   1305 
   1306             if (ifaceList.size() > 0) {
   1307                 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]);
   1308                 mNetworkRules.put(policy, ifaces);
   1309             }
   1310         }
   1311 
   1312         long lowestRule = Long.MAX_VALUE;
   1313         final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length);
   1314 
   1315         // apply each policy that we found ifaces for; compute remaining data
   1316         // based on current cycle and historical stats, and push to kernel.
   1317         final long currentTime = currentTimeMillis();
   1318         for (int i = mNetworkRules.size()-1; i >= 0; i--) {
   1319             final NetworkPolicy policy = mNetworkRules.keyAt(i);
   1320             final String[] ifaces = mNetworkRules.valueAt(i);
   1321 
   1322             final long start;
   1323             final long totalBytes;
   1324             if (policy.hasCycle()) {
   1325                 start = computeLastCycleBoundary(currentTime, policy);
   1326                 totalBytes = getTotalBytes(policy.template, start, currentTime);
   1327             } else {
   1328                 start = Long.MAX_VALUE;
   1329                 totalBytes = 0;
   1330             }
   1331 
   1332             if (LOGD) {
   1333                 Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces));
   1334             }
   1335 
   1336             final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
   1337             final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
   1338             if (hasLimit || policy.metered) {
   1339                 final long quotaBytes;
   1340                 if (!hasLimit) {
   1341                     // metered network, but no policy limit; we still need to
   1342                     // restrict apps, so push really high quota.
   1343                     quotaBytes = Long.MAX_VALUE;
   1344                 } else if (policy.lastLimitSnooze >= start) {
   1345                     // snoozing past quota, but we still need to restrict apps,
   1346                     // so push really high quota.
   1347                     quotaBytes = Long.MAX_VALUE;
   1348                 } else {
   1349                     // remaining "quota" bytes are based on total usage in
   1350                     // current cycle. kernel doesn't like 0-byte rules, so we
   1351                     // set 1-byte quota and disable the radio later.
   1352                     quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
   1353                 }
   1354 
   1355                 if (ifaces.length > 1) {
   1356                     // TODO: switch to shared quota once NMS supports
   1357                     Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
   1358                 }
   1359 
   1360                 for (String iface : ifaces) {
   1361                     // long quotaBytes split up into two ints to fit in message
   1362                     mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
   1363                             (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface)
   1364                             .sendToTarget();
   1365                     newMeteredIfaces.add(iface);
   1366                 }
   1367             }
   1368 
   1369             // keep track of lowest warning or limit of active policies
   1370             if (hasWarning && policy.warningBytes < lowestRule) {
   1371                 lowestRule = policy.warningBytes;
   1372             }
   1373             if (hasLimit && policy.limitBytes < lowestRule) {
   1374                 lowestRule = policy.limitBytes;
   1375             }
   1376         }
   1377 
   1378         for (int i = connIfaces.size()-1; i >= 0; i--) {
   1379             String iface = connIfaces.valueAt(i);
   1380             // long quotaBytes split up into two ints to fit in message
   1381             mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
   1382                     (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface)
   1383                     .sendToTarget();
   1384             newMeteredIfaces.add(iface);
   1385         }
   1386 
   1387         mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
   1388 
   1389         // remove quota on any trailing interfaces
   1390         for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
   1391             final String iface = mMeteredIfaces.valueAt(i);
   1392             if (!newMeteredIfaces.contains(iface)) {
   1393                 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface)
   1394                         .sendToTarget();
   1395             }
   1396         }
   1397         mMeteredIfaces = newMeteredIfaces;
   1398 
   1399         final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
   1400         mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
   1401     }
   1402 
   1403     /**
   1404      * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
   1405      * have at least a default mobile policy defined.
   1406      */
   1407     private void ensureActiveMobilePolicyNL() {
   1408         if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyNL()");
   1409         if (mSuppressDefaultPolicy) return;
   1410 
   1411         final TelephonyManager tele = TelephonyManager.from(mContext);
   1412         final SubscriptionManager sub = SubscriptionManager.from(mContext);
   1413 
   1414         final int[] subIds = sub.getActiveSubscriptionIdList();
   1415         for (int subId : subIds) {
   1416             final String subscriberId = tele.getSubscriberId(subId);
   1417             ensureActiveMobilePolicyNL(subscriberId);
   1418         }
   1419     }
   1420 
   1421     private void ensureActiveMobilePolicyNL(String subscriberId) {
   1422         // Poke around to see if we already have a policy
   1423         final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
   1424                 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
   1425         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
   1426             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
   1427             if (template.matches(probeIdent)) {
   1428                 if (LOGD) {
   1429                     Slog.d(TAG, "Found template " + template + " which matches subscriber "
   1430                             + NetworkIdentity.scrubSubscriberId(subscriberId));
   1431                 }
   1432                 return;
   1433             }
   1434         }
   1435 
   1436         Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
   1437                 + "; generating default policy");
   1438 
   1439         // Build default mobile policy, and assume usage cycle starts today
   1440         final int dataWarningConfig = mContext.getResources().getInteger(
   1441                 com.android.internal.R.integer.config_networkPolicyDefaultWarning);
   1442         final long warningBytes;
   1443         if (dataWarningConfig == WARNING_DISABLED) {
   1444             warningBytes = WARNING_DISABLED;
   1445         } else {
   1446             warningBytes = dataWarningConfig * MB_IN_BYTES;
   1447         }
   1448 
   1449         final Time time = new Time();
   1450         time.setToNow();
   1451 
   1452         final int cycleDay = time.monthDay;
   1453         final String cycleTimezone = time.timezone;
   1454 
   1455         final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
   1456         final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
   1457                 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
   1458         addNetworkPolicyNL(policy);
   1459     }
   1460 
   1461     private void readPolicyAL() {
   1462         if (LOGV) Slog.v(TAG, "readPolicyAL()");
   1463 
   1464         // clear any existing policy and read from disk
   1465         mNetworkPolicy.clear();
   1466         mUidPolicy.clear();
   1467 
   1468         FileInputStream fis = null;
   1469         try {
   1470             fis = mPolicyFile.openRead();
   1471             final XmlPullParser in = Xml.newPullParser();
   1472             in.setInput(fis, StandardCharsets.UTF_8.name());
   1473 
   1474             int type;
   1475             int version = VERSION_INIT;
   1476             boolean insideWhitelist = false;
   1477             while ((type = in.next()) != END_DOCUMENT) {
   1478                 final String tag = in.getName();
   1479                 if (type == START_TAG) {
   1480                     if (TAG_POLICY_LIST.equals(tag)) {
   1481                         final boolean oldValue = mRestrictBackground;
   1482                         version = readIntAttribute(in, ATTR_VERSION);
   1483                         if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
   1484                             mRestrictBackground = readBooleanAttribute(
   1485                                     in, ATTR_RESTRICT_BACKGROUND);
   1486                         } else {
   1487                             mRestrictBackground = false;
   1488                         }
   1489                         if (mRestrictBackground != oldValue) {
   1490                             // Some early services may have read the default value,
   1491                             // so notify them that it's changed
   1492                             mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
   1493                                     mRestrictBackground ? 1 : 0, 0).sendToTarget();
   1494                         }
   1495 
   1496                     } else if (TAG_NETWORK_POLICY.equals(tag)) {
   1497                         final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
   1498                         final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
   1499                         final String networkId;
   1500                         if (version >= VERSION_ADDED_NETWORK_ID) {
   1501                             networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
   1502                         } else {
   1503                             networkId = null;
   1504                         }
   1505                         final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
   1506                         final String cycleTimezone;
   1507                         if (version >= VERSION_ADDED_TIMEZONE) {
   1508                             cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
   1509                         } else {
   1510                             cycleTimezone = Time.TIMEZONE_UTC;
   1511                         }
   1512                         final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
   1513                         final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
   1514                         final long lastLimitSnooze;
   1515                         if (version >= VERSION_SPLIT_SNOOZE) {
   1516                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
   1517                         } else if (version >= VERSION_ADDED_SNOOZE) {
   1518                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
   1519                         } else {
   1520                             lastLimitSnooze = SNOOZE_NEVER;
   1521                         }
   1522                         final boolean metered;
   1523                         if (version >= VERSION_ADDED_METERED) {
   1524                             metered = readBooleanAttribute(in, ATTR_METERED);
   1525                         } else {
   1526                             switch (networkTemplate) {
   1527                                 case MATCH_MOBILE_3G_LOWER:
   1528                                 case MATCH_MOBILE_4G:
   1529                                 case MATCH_MOBILE_ALL:
   1530                                     metered = true;
   1531                                     break;
   1532                                 default:
   1533                                     metered = false;
   1534                             }
   1535                         }
   1536                         final long lastWarningSnooze;
   1537                         if (version >= VERSION_SPLIT_SNOOZE) {
   1538                             lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
   1539                         } else {
   1540                             lastWarningSnooze = SNOOZE_NEVER;
   1541                         }
   1542                         final boolean inferred;
   1543                         if (version >= VERSION_ADDED_INFERRED) {
   1544                             inferred = readBooleanAttribute(in, ATTR_INFERRED);
   1545                         } else {
   1546                             inferred = false;
   1547                         }
   1548 
   1549                         final NetworkTemplate template = new NetworkTemplate(networkTemplate,
   1550                                 subscriberId, networkId);
   1551                         if (template.isPersistable()) {
   1552                             mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
   1553                                     cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
   1554                                     lastLimitSnooze, metered, inferred));
   1555                         }
   1556 
   1557                     } else if (TAG_UID_POLICY.equals(tag)) {
   1558                         final int uid = readIntAttribute(in, ATTR_UID);
   1559                         final int policy = readIntAttribute(in, ATTR_POLICY);
   1560 
   1561                         if (UserHandle.isApp(uid)) {
   1562                             setUidPolicyUncheckedUL(uid, policy, false);
   1563                         } else {
   1564                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
   1565                         }
   1566                     } else if (TAG_APP_POLICY.equals(tag)) {
   1567                         final int appId = readIntAttribute(in, ATTR_APP_ID);
   1568                         final int policy = readIntAttribute(in, ATTR_POLICY);
   1569 
   1570                         // TODO: set for other users during upgrade
   1571                         // app policy is deprecated so this is only used in pre system user split.
   1572                         final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
   1573                         if (UserHandle.isApp(uid)) {
   1574                             setUidPolicyUncheckedUL(uid, policy, false);
   1575                         } else {
   1576                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
   1577                         }
   1578                     } else if (TAG_WHITELIST.equals(tag)) {
   1579                         insideWhitelist = true;
   1580                     } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
   1581                         final int uid = readIntAttribute(in, ATTR_UID);
   1582                         mRestrictBackgroundWhitelistUids.put(uid, true);
   1583                     } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
   1584                         final int uid = readIntAttribute(in, ATTR_UID);
   1585                         mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
   1586                     }
   1587                 } else if (type == END_TAG) {
   1588                     if (TAG_WHITELIST.equals(tag)) {
   1589                         insideWhitelist = false;
   1590                     }
   1591 
   1592                 }
   1593             }
   1594 
   1595         } catch (FileNotFoundException e) {
   1596             // missing policy is okay, probably first boot
   1597             upgradeLegacyBackgroundDataUL();
   1598         } catch (IOException e) {
   1599             Log.wtf(TAG, "problem reading network policy", e);
   1600         } catch (XmlPullParserException e) {
   1601             Log.wtf(TAG, "problem reading network policy", e);
   1602         } finally {
   1603             IoUtils.closeQuietly(fis);
   1604         }
   1605     }
   1606 
   1607     /**
   1608      * Upgrade legacy background data flags, notifying listeners of one last
   1609      * change to always-true.
   1610      */
   1611     private void upgradeLegacyBackgroundDataUL() {
   1612         mRestrictBackground = Settings.Secure.getInt(
   1613                 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
   1614 
   1615         // kick off one last broadcast if restricted
   1616         if (mRestrictBackground) {
   1617             final Intent broadcast = new Intent(
   1618                     ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
   1619             mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL);
   1620         }
   1621     }
   1622 
   1623     void writePolicyAL() {
   1624         if (LOGV) Slog.v(TAG, "writePolicyAL()");
   1625 
   1626         FileOutputStream fos = null;
   1627         try {
   1628             fos = mPolicyFile.startWrite();
   1629 
   1630             XmlSerializer out = new FastXmlSerializer();
   1631             out.setOutput(fos, StandardCharsets.UTF_8.name());
   1632             out.startDocument(null, true);
   1633 
   1634             out.startTag(null, TAG_POLICY_LIST);
   1635             writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
   1636             writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
   1637 
   1638             // write all known network policies
   1639             for (int i = 0; i < mNetworkPolicy.size(); i++) {
   1640                 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1641                 final NetworkTemplate template = policy.template;
   1642                 if (!template.isPersistable()) continue;
   1643 
   1644                 out.startTag(null, TAG_NETWORK_POLICY);
   1645                 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
   1646                 final String subscriberId = template.getSubscriberId();
   1647                 if (subscriberId != null) {
   1648                     out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
   1649                 }
   1650                 final String networkId = template.getNetworkId();
   1651                 if (networkId != null) {
   1652                     out.attribute(null, ATTR_NETWORK_ID, networkId);
   1653                 }
   1654                 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
   1655                 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
   1656                 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
   1657                 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
   1658                 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
   1659                 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
   1660                 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
   1661                 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
   1662                 out.endTag(null, TAG_NETWORK_POLICY);
   1663             }
   1664 
   1665             // write all known uid policies
   1666             for (int i = 0; i < mUidPolicy.size(); i++) {
   1667                 final int uid = mUidPolicy.keyAt(i);
   1668                 final int policy = mUidPolicy.valueAt(i);
   1669 
   1670                 // skip writing empty policies
   1671                 if (policy == POLICY_NONE) continue;
   1672 
   1673                 out.startTag(null, TAG_UID_POLICY);
   1674                 writeIntAttribute(out, ATTR_UID, uid);
   1675                 writeIntAttribute(out, ATTR_POLICY, policy);
   1676                 out.endTag(null, TAG_UID_POLICY);
   1677             }
   1678 
   1679             out.endTag(null, TAG_POLICY_LIST);
   1680 
   1681             // write all whitelists
   1682             out.startTag(null, TAG_WHITELIST);
   1683 
   1684             // restrict background whitelist
   1685             int size = mRestrictBackgroundWhitelistUids.size();
   1686             for (int i = 0; i < size; i++) {
   1687                 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i);
   1688                 out.startTag(null, TAG_RESTRICT_BACKGROUND);
   1689                 writeIntAttribute(out, ATTR_UID, uid);
   1690                 out.endTag(null, TAG_RESTRICT_BACKGROUND);
   1691             }
   1692 
   1693             // revoked restrict background whitelist
   1694             size = mRestrictBackgroundWhitelistRevokedUids.size();
   1695             for (int i = 0; i < size; i++) {
   1696                 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
   1697                 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
   1698                 writeIntAttribute(out, ATTR_UID, uid);
   1699                 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
   1700             }
   1701 
   1702             out.endTag(null, TAG_WHITELIST);
   1703 
   1704             out.endDocument();
   1705 
   1706             mPolicyFile.finishWrite(fos);
   1707         } catch (IOException e) {
   1708             if (fos != null) {
   1709                 mPolicyFile.failWrite(fos);
   1710             }
   1711         }
   1712     }
   1713 
   1714     @Override
   1715     public void setUidPolicy(int uid, int policy) {
   1716         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1717 
   1718         if (!UserHandle.isApp(uid)) {
   1719             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1720         }
   1721         synchronized (mUidRulesFirstLock) {
   1722             final long token = Binder.clearCallingIdentity();
   1723             try {
   1724                 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1725                 if (oldPolicy != policy) {
   1726                     setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
   1727                 }
   1728             } finally {
   1729                 Binder.restoreCallingIdentity(token);
   1730             }
   1731         }
   1732     }
   1733 
   1734     @Override
   1735     public void addUidPolicy(int uid, int policy) {
   1736         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1737 
   1738         if (!UserHandle.isApp(uid)) {
   1739             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1740         }
   1741 
   1742         synchronized (mUidRulesFirstLock) {
   1743             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1744             policy |= oldPolicy;
   1745             if (oldPolicy != policy) {
   1746                 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
   1747             }
   1748         }
   1749     }
   1750 
   1751     @Override
   1752     public void removeUidPolicy(int uid, int policy) {
   1753         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1754 
   1755         if (!UserHandle.isApp(uid)) {
   1756             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1757         }
   1758 
   1759         synchronized (mUidRulesFirstLock) {
   1760             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1761             policy = oldPolicy & ~policy;
   1762             if (oldPolicy != policy) {
   1763                 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
   1764             }
   1765         }
   1766     }
   1767 
   1768     private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
   1769         setUidPolicyUncheckedUL(uid, policy, persist);
   1770 
   1771         final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
   1772         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED, uid,
   1773                 isBlacklisted ? 1 : 0).sendToTarget();
   1774 
   1775         final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
   1776         // Checks if app was added or removed to the blacklist.
   1777         if ((oldPolicy == POLICY_NONE && isBlacklisted)
   1778                 || (wasBlacklisted && policy == POLICY_NONE)) {
   1779             mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null)
   1780                     .sendToTarget();
   1781         }
   1782     }
   1783 
   1784     private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
   1785         mUidPolicy.put(uid, policy);
   1786 
   1787         // uid policy changed, recompute rules and persist policy.
   1788         updateRulesForDataUsageRestrictionsUL(uid);
   1789         if (persist) {
   1790             synchronized (mNetworkPoliciesSecondLock) {
   1791                 writePolicyAL();
   1792             }
   1793         }
   1794     }
   1795 
   1796     @Override
   1797     public int getUidPolicy(int uid) {
   1798         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1799 
   1800         synchronized (mUidRulesFirstLock) {
   1801             return mUidPolicy.get(uid, POLICY_NONE);
   1802         }
   1803     }
   1804 
   1805     @Override
   1806     public int[] getUidsWithPolicy(int policy) {
   1807         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1808 
   1809         int[] uids = new int[0];
   1810         synchronized (mUidRulesFirstLock) {
   1811             for (int i = 0; i < mUidPolicy.size(); i++) {
   1812                 final int uid = mUidPolicy.keyAt(i);
   1813                 final int uidPolicy = mUidPolicy.valueAt(i);
   1814                 if (uidPolicy == policy) {
   1815                     uids = appendInt(uids, uid);
   1816                 }
   1817             }
   1818         }
   1819         return uids;
   1820     }
   1821 
   1822     /**
   1823      * Removes any persistable state associated with given {@link UserHandle}, persisting
   1824      * if any changes that are made.
   1825      */
   1826     boolean removeUserStateUL(int userId, boolean writePolicy) {
   1827 
   1828         if (LOGV) Slog.v(TAG, "removeUserStateUL()");
   1829         boolean changed = false;
   1830 
   1831         // Remove entries from restricted background UID whitelist
   1832         int[] wlUids = new int[0];
   1833         for (int i = 0; i < mRestrictBackgroundWhitelistUids.size(); i++) {
   1834             final int uid = mRestrictBackgroundWhitelistUids.keyAt(i);
   1835             if (UserHandle.getUserId(uid) == userId) {
   1836                 wlUids = appendInt(wlUids, uid);
   1837             }
   1838         }
   1839 
   1840         if (wlUids.length > 0) {
   1841             for (int uid : wlUids) {
   1842                 removeRestrictBackgroundWhitelistedUidUL(uid, false, false);
   1843             }
   1844             changed = true;
   1845         }
   1846 
   1847         // Remove entries from revoked default restricted background UID whitelist
   1848         for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
   1849             final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
   1850             if (UserHandle.getUserId(uid) == userId) {
   1851                 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
   1852                 changed = true;
   1853             }
   1854         }
   1855 
   1856         // Remove associated UID policies
   1857         int[] uids = new int[0];
   1858         for (int i = 0; i < mUidPolicy.size(); i++) {
   1859             final int uid = mUidPolicy.keyAt(i);
   1860             if (UserHandle.getUserId(uid) == userId) {
   1861                 uids = appendInt(uids, uid);
   1862             }
   1863         }
   1864 
   1865         if (uids.length > 0) {
   1866             for (int uid : uids) {
   1867                 mUidPolicy.delete(uid);
   1868             }
   1869             changed = true;
   1870         }
   1871         synchronized (mNetworkPoliciesSecondLock) {
   1872             updateRulesForGlobalChangeAL(true);
   1873             if (writePolicy && changed) {
   1874                 writePolicyAL();
   1875             }
   1876         }
   1877         return changed;
   1878     }
   1879 
   1880     @Override
   1881     public void setConnectivityListener(INetworkPolicyListener listener) {
   1882         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1883         if (mConnectivityListener != null) {
   1884             throw new IllegalStateException("Connectivity listener already registered");
   1885         }
   1886         mConnectivityListener = listener;
   1887     }
   1888 
   1889     @Override
   1890     public void registerListener(INetworkPolicyListener listener) {
   1891         // TODO: create permission for observing network policy
   1892         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1893         mListeners.register(listener);
   1894     }
   1895 
   1896     @Override
   1897     public void unregisterListener(INetworkPolicyListener listener) {
   1898         // TODO: create permission for observing network policy
   1899         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1900         mListeners.unregister(listener);
   1901     }
   1902 
   1903     @Override
   1904     public void setNetworkPolicies(NetworkPolicy[] policies) {
   1905         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1906 
   1907         final long token = Binder.clearCallingIdentity();
   1908         try {
   1909             maybeRefreshTrustedTime();
   1910             synchronized (mUidRulesFirstLock) {
   1911                 synchronized (mNetworkPoliciesSecondLock) {
   1912                     normalizePoliciesNL(policies);
   1913                     updateNetworkEnabledNL();
   1914                     updateNetworkRulesNL();
   1915                     updateNotificationsNL();
   1916                     writePolicyAL();
   1917                 }
   1918             }
   1919         } finally {
   1920             Binder.restoreCallingIdentity(token);
   1921         }
   1922     }
   1923 
   1924     void addNetworkPolicyNL(NetworkPolicy policy) {
   1925         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
   1926         policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
   1927         setNetworkPolicies(policies);
   1928     }
   1929 
   1930     @Override
   1931     public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
   1932         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1933         try {
   1934             mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
   1935             // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
   1936             // permission
   1937         } catch (SecurityException e) {
   1938             mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
   1939 
   1940             if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
   1941                     callingPackage) != AppOpsManager.MODE_ALLOWED) {
   1942                 return new NetworkPolicy[0];
   1943             }
   1944         }
   1945 
   1946         synchronized (mNetworkPoliciesSecondLock) {
   1947             final int size = mNetworkPolicy.size();
   1948             final NetworkPolicy[] policies = new NetworkPolicy[size];
   1949             for (int i = 0; i < size; i++) {
   1950                 policies[i] = mNetworkPolicy.valueAt(i);
   1951             }
   1952             return policies;
   1953         }
   1954     }
   1955 
   1956     private void normalizePoliciesNL() {
   1957         normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
   1958     }
   1959 
   1960     private void normalizePoliciesNL(NetworkPolicy[] policies) {
   1961         final TelephonyManager tele = TelephonyManager.from(mContext);
   1962         final String[] merged = tele.getMergedSubscriberIds();
   1963 
   1964         mNetworkPolicy.clear();
   1965         for (NetworkPolicy policy : policies) {
   1966             // When two normalized templates conflict, prefer the most
   1967             // restrictive policy
   1968             policy.template = NetworkTemplate.normalize(policy.template, merged);
   1969             final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
   1970             if (existing == null || existing.compareTo(policy) > 0) {
   1971                 if (existing != null) {
   1972                     Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
   1973                 }
   1974                 mNetworkPolicy.put(policy.template, policy);
   1975             }
   1976         }
   1977     }
   1978 
   1979     @Override
   1980     public void snoozeLimit(NetworkTemplate template) {
   1981         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1982 
   1983         final long token = Binder.clearCallingIdentity();
   1984         try {
   1985             performSnooze(template, TYPE_LIMIT);
   1986         } finally {
   1987             Binder.restoreCallingIdentity(token);
   1988         }
   1989     }
   1990 
   1991     void performSnooze(NetworkTemplate template, int type) {
   1992         maybeRefreshTrustedTime();
   1993         final long currentTime = currentTimeMillis();
   1994         synchronized (mUidRulesFirstLock) {
   1995             synchronized (mNetworkPoliciesSecondLock) {
   1996                 // find and snooze local policy that matches
   1997                 final NetworkPolicy policy = mNetworkPolicy.get(template);
   1998                 if (policy == null) {
   1999                     throw new IllegalArgumentException("unable to find policy for " + template);
   2000                 }
   2001 
   2002                 switch (type) {
   2003                     case TYPE_WARNING:
   2004                         policy.lastWarningSnooze = currentTime;
   2005                         break;
   2006                     case TYPE_LIMIT:
   2007                         policy.lastLimitSnooze = currentTime;
   2008                         break;
   2009                     default:
   2010                         throw new IllegalArgumentException("unexpected type");
   2011                 }
   2012 
   2013                 normalizePoliciesNL();
   2014                 updateNetworkEnabledNL();
   2015                 updateNetworkRulesNL();
   2016                 updateNotificationsNL();
   2017                 writePolicyAL();
   2018             }
   2019         }
   2020     }
   2021 
   2022     @Override
   2023     public void onTetheringChanged(String iface, boolean tethering) {
   2024         // No need to enforce permission because setRestrictBackground() will do it.
   2025         if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")");
   2026         synchronized (mUidRulesFirstLock) {
   2027             if (mRestrictBackground && tethering) {
   2028                 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
   2029                 setRestrictBackground(false);
   2030             }
   2031         }
   2032     }
   2033 
   2034     @Override
   2035     public void setRestrictBackground(boolean restrictBackground) {
   2036         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2037         final long token = Binder.clearCallingIdentity();
   2038         try {
   2039             maybeRefreshTrustedTime();
   2040             synchronized (mUidRulesFirstLock) {
   2041                 if (restrictBackground == mRestrictBackground) {
   2042                     // Ideally, UI should never allow this scenario...
   2043                     Slog.w(TAG, "setRestrictBackground: already " + restrictBackground);
   2044                     return;
   2045                 }
   2046                 setRestrictBackgroundUL(restrictBackground);
   2047             }
   2048 
   2049         } finally {
   2050             Binder.restoreCallingIdentity(token);
   2051         }
   2052 
   2053         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
   2054                 .sendToTarget();
   2055     }
   2056 
   2057     private void setRestrictBackgroundUL(boolean restrictBackground) {
   2058         Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
   2059         final boolean oldRestrictBackground = mRestrictBackground;
   2060         mRestrictBackground = restrictBackground;
   2061         // Must whitelist foreground apps before turning data saver mode on.
   2062         // TODO: there is no need to iterate through all apps here, just those in the foreground,
   2063         // so it could call AM to get the UIDs of such apps, and iterate through them instead.
   2064         updateRulesForRestrictBackgroundUL();
   2065         try {
   2066             if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
   2067                 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
   2068                 mRestrictBackground = oldRestrictBackground;
   2069                 // TODO: if it knew the foreground apps (see TODO above), it could call
   2070                 // updateRulesForRestrictBackgroundUL() again to restore state.
   2071                 return;
   2072             }
   2073         } catch (RemoteException e) {
   2074             // ignored; service lives in system_server
   2075         }
   2076         synchronized (mNetworkPoliciesSecondLock) {
   2077             updateNotificationsNL();
   2078             writePolicyAL();
   2079         }
   2080     }
   2081 
   2082     @Override
   2083     public void addRestrictBackgroundWhitelistedUid(int uid) {
   2084         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2085         final boolean oldStatus;
   2086         final boolean needFirewallRules;
   2087         int changed;
   2088         synchronized (mUidRulesFirstLock) {
   2089             oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
   2090             if (oldStatus) {
   2091                 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted");
   2092                 return;
   2093             }
   2094             needFirewallRules = isUidValidForWhitelistRules(uid);
   2095             Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist");
   2096             mRestrictBackgroundWhitelistUids.append(uid, true);
   2097             if (mDefaultRestrictBackgroundWhitelistUids.get(uid)
   2098                     && mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
   2099                 if (LOGD) Slog.d(TAG, "Removing uid " + uid
   2100                         + " from revoked restrict background whitelist");
   2101                 mRestrictBackgroundWhitelistRevokedUids.delete(uid);
   2102             }
   2103             if (needFirewallRules) {
   2104                 // Only update firewall rules if necessary...
   2105                 updateRulesForDataUsageRestrictionsUL(uid);
   2106             }
   2107             // ...but always persists the whitelist request.
   2108             synchronized (mNetworkPoliciesSecondLock) {
   2109                 writePolicyAL();
   2110             }
   2111             changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0;
   2112         }
   2113         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed,
   2114                 Boolean.TRUE).sendToTarget();
   2115     }
   2116 
   2117     @Override
   2118     public void removeRestrictBackgroundWhitelistedUid(int uid) {
   2119         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2120         final boolean changed;
   2121         synchronized (mUidRulesFirstLock) {
   2122             changed = removeRestrictBackgroundWhitelistedUidUL(uid, false, true);
   2123         }
   2124         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0,
   2125                 Boolean.FALSE).sendToTarget();
   2126     }
   2127 
   2128     /**
   2129      * Removes a uid from the restricted background whitelist, returning whether its current
   2130      * {@link ConnectivityManager.RestrictBackgroundStatus} changed.
   2131      */
   2132     private boolean removeRestrictBackgroundWhitelistedUidUL(int uid, boolean uidDeleted,
   2133             boolean updateNow) {
   2134         final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
   2135         if (!oldStatus && !uidDeleted) {
   2136             if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before");
   2137             return false;
   2138         }
   2139         final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid);
   2140         if (oldStatus) {
   2141             Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist");
   2142             mRestrictBackgroundWhitelistUids.delete(uid);
   2143         }
   2144         if (mDefaultRestrictBackgroundWhitelistUids.get(uid)
   2145                 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
   2146             if (LOGD) Slog.d(TAG, "Adding uid " + uid
   2147                     + " to revoked restrict background whitelist");
   2148             mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
   2149         }
   2150         if (needFirewallRules) {
   2151             // Only update firewall rules if necessary...
   2152             updateRulesForDataUsageRestrictionsUL(uid, uidDeleted);
   2153         }
   2154         if (updateNow) {
   2155             // ...but always persists the whitelist request.
   2156             synchronized (mNetworkPoliciesSecondLock) {
   2157                 writePolicyAL();
   2158             }
   2159         }
   2160         // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the
   2161         // app was whitelisted before).
   2162         return mRestrictBackground && needFirewallRules;
   2163     }
   2164 
   2165     @Override
   2166     public int[] getRestrictBackgroundWhitelistedUids() {
   2167         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2168         synchronized (mUidRulesFirstLock) {
   2169             final int size = mRestrictBackgroundWhitelistUids.size();
   2170             final int[] whitelist = new int[size];
   2171             for (int i = 0; i < size; i++) {
   2172                 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i);
   2173             }
   2174             if (LOGV) {
   2175                 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): "
   2176                         + mRestrictBackgroundWhitelistUids);
   2177             }
   2178             return whitelist;
   2179         }
   2180     }
   2181 
   2182     @Override
   2183     public int getRestrictBackgroundByCaller() {
   2184         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
   2185         final int uid = Binder.getCallingUid();
   2186 
   2187         synchronized (mUidRulesFirstLock) {
   2188             // Must clear identity because getUidPolicy() is restricted to system.
   2189             final long token = Binder.clearCallingIdentity();
   2190             final int policy;
   2191             try {
   2192                 policy = getUidPolicy(uid);
   2193             } finally {
   2194                 Binder.restoreCallingIdentity(token);
   2195             }
   2196             if (policy == POLICY_REJECT_METERED_BACKGROUND) {
   2197                 // App is blacklisted.
   2198                 return RESTRICT_BACKGROUND_STATUS_ENABLED;
   2199             }
   2200             if (!mRestrictBackground) {
   2201                 return RESTRICT_BACKGROUND_STATUS_DISABLED;
   2202             }
   2203             return mRestrictBackgroundWhitelistUids.get(uid)
   2204                     ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
   2205                     : RESTRICT_BACKGROUND_STATUS_ENABLED;
   2206         }
   2207     }
   2208 
   2209     @Override
   2210     public boolean getRestrictBackground() {
   2211         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2212 
   2213         synchronized (mUidRulesFirstLock) {
   2214             return mRestrictBackground;
   2215         }
   2216     }
   2217 
   2218     @Override
   2219     public void setDeviceIdleMode(boolean enabled) {
   2220         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2221         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
   2222         try {
   2223             synchronized (mUidRulesFirstLock) {
   2224                 if (mDeviceIdleMode == enabled) {
   2225                     return;
   2226                 }
   2227                 mDeviceIdleMode = enabled;
   2228                 if (mSystemReady) {
   2229                     // Device idle change means we need to rebuild rules for all
   2230                     // known apps, so do a global refresh.
   2231                     updateRulesForRestrictPowerUL();
   2232                 }
   2233             }
   2234             if (enabled) {
   2235                 EventLogTags.writeDeviceIdleOnPhase("net");
   2236             } else {
   2237                 EventLogTags.writeDeviceIdleOffPhase("net");
   2238             }
   2239         } finally {
   2240             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2241         }
   2242     }
   2243 
   2244     private NetworkPolicy findPolicyForNetworkNL(NetworkIdentity ident) {
   2245         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   2246             NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   2247             if (policy.template.matches(ident)) {
   2248                 return policy;
   2249             }
   2250         }
   2251         return null;
   2252     }
   2253 
   2254     @Override
   2255     public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
   2256         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
   2257 
   2258         // only returns usage summary, so we don't require caller to have
   2259         // READ_NETWORK_USAGE_HISTORY.
   2260         final long token = Binder.clearCallingIdentity();
   2261         try {
   2262             return getNetworkQuotaInfoUnchecked(state);
   2263         } finally {
   2264             Binder.restoreCallingIdentity(token);
   2265         }
   2266     }
   2267 
   2268     private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
   2269         final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   2270 
   2271         final NetworkPolicy policy;
   2272         synchronized (mNetworkPoliciesSecondLock) {
   2273             policy = findPolicyForNetworkNL(ident);
   2274         }
   2275 
   2276         if (policy == null || !policy.hasCycle()) {
   2277             // missing policy means we can't derive useful quota info
   2278             return null;
   2279         }
   2280 
   2281         final long currentTime = currentTimeMillis();
   2282 
   2283         // find total bytes used under policy
   2284         final long start = computeLastCycleBoundary(currentTime, policy);
   2285         final long end = currentTime;
   2286         final long totalBytes = getTotalBytes(policy.template, start, end);
   2287 
   2288         // report soft and hard limits under policy
   2289         final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
   2290                 : NetworkQuotaInfo.NO_LIMIT;
   2291         final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
   2292                 : NetworkQuotaInfo.NO_LIMIT;
   2293 
   2294         return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
   2295     }
   2296 
   2297     @Override
   2298     public boolean isNetworkMetered(NetworkState state) {
   2299         if (state.networkInfo == null) {
   2300             return false;
   2301         }
   2302 
   2303         final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   2304 
   2305         final NetworkPolicy policy;
   2306         synchronized (mNetworkPoliciesSecondLock) {
   2307             policy = findPolicyForNetworkNL(ident);
   2308         }
   2309 
   2310         if (policy != null) {
   2311             return policy.metered;
   2312         } else {
   2313             final int type = state.networkInfo.getType();
   2314             if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) {
   2315                 return true;
   2316             }
   2317             return false;
   2318         }
   2319     }
   2320 
   2321     @Override
   2322     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
   2323         mContext.enforceCallingOrSelfPermission(DUMP, TAG);
   2324 
   2325         final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
   2326 
   2327         final ArraySet<String> argSet = new ArraySet<String>(args.length);
   2328         for (String arg : args) {
   2329             argSet.add(arg);
   2330         }
   2331 
   2332         synchronized (mUidRulesFirstLock) {
   2333             synchronized (mNetworkPoliciesSecondLock) {
   2334                 if (argSet.contains("--unsnooze")) {
   2335                     for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   2336                         mNetworkPolicy.valueAt(i).clearSnooze();
   2337                     }
   2338 
   2339                     normalizePoliciesNL();
   2340                     updateNetworkEnabledNL();
   2341                     updateNetworkRulesNL();
   2342                     updateNotificationsNL();
   2343                     writePolicyAL();
   2344 
   2345                     fout.println("Cleared snooze timestamps");
   2346                     return;
   2347                 }
   2348 
   2349                 fout.print("System ready: "); fout.println(mSystemReady);
   2350                 fout.print("Restrict background: "); fout.println(mRestrictBackground);
   2351                 fout.print("Restrict power: "); fout.println(mRestrictPower);
   2352                 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
   2353                 fout.println("Network policies:");
   2354                 fout.increaseIndent();
   2355                 for (int i = 0; i < mNetworkPolicy.size(); i++) {
   2356                     fout.println(mNetworkPolicy.valueAt(i).toString());
   2357                 }
   2358                 fout.decreaseIndent();
   2359 
   2360                 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
   2361 
   2362                 fout.println("Policy for UIDs:");
   2363                 fout.increaseIndent();
   2364                 int size = mUidPolicy.size();
   2365                 for (int i = 0; i < size; i++) {
   2366                     final int uid = mUidPolicy.keyAt(i);
   2367                     final int policy = mUidPolicy.valueAt(i);
   2368                     fout.print("UID=");
   2369                     fout.print(uid);
   2370                     fout.print(" policy=");
   2371                     fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
   2372                     fout.println();
   2373                 }
   2374                 fout.decreaseIndent();
   2375 
   2376                 size = mPowerSaveWhitelistExceptIdleAppIds.size();
   2377                 if (size > 0) {
   2378                     fout.println("Power save whitelist (except idle) app ids:");
   2379                     fout.increaseIndent();
   2380                     for (int i = 0; i < size; i++) {
   2381                         fout.print("UID=");
   2382                         fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
   2383                         fout.print(": ");
   2384                         fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
   2385                         fout.println();
   2386                     }
   2387                     fout.decreaseIndent();
   2388                 }
   2389 
   2390                 size = mPowerSaveWhitelistAppIds.size();
   2391                 if (size > 0) {
   2392                     fout.println("Power save whitelist app ids:");
   2393                     fout.increaseIndent();
   2394                     for (int i = 0; i < size; i++) {
   2395                         fout.print("UID=");
   2396                         fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
   2397                         fout.print(": ");
   2398                         fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
   2399                         fout.println();
   2400                     }
   2401                     fout.decreaseIndent();
   2402                 }
   2403 
   2404                 size = mRestrictBackgroundWhitelistUids.size();
   2405                 if (size > 0) {
   2406                     fout.println("Restrict background whitelist uids:");
   2407                     fout.increaseIndent();
   2408                     for (int i = 0; i < size; i++) {
   2409                         fout.print("UID=");
   2410                         fout.print(mRestrictBackgroundWhitelistUids.keyAt(i));
   2411                         fout.println();
   2412                     }
   2413                     fout.decreaseIndent();
   2414                 }
   2415 
   2416                 size = mDefaultRestrictBackgroundWhitelistUids.size();
   2417                 if (size > 0) {
   2418                     fout.println("Default restrict background whitelist uids:");
   2419                     fout.increaseIndent();
   2420                     for (int i = 0; i < size; i++) {
   2421                         fout.print("UID=");
   2422                         fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
   2423                         fout.println();
   2424                     }
   2425                     fout.decreaseIndent();
   2426                 }
   2427 
   2428                 size = mRestrictBackgroundWhitelistRevokedUids.size();
   2429                 if (size > 0) {
   2430                     fout.println("Default restrict background whitelist uids revoked by users:");
   2431                     fout.increaseIndent();
   2432                     for (int i = 0; i < size; i++) {
   2433                         fout.print("UID=");
   2434                         fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
   2435                         fout.println();
   2436                     }
   2437                     fout.decreaseIndent();
   2438                 }
   2439 
   2440                 final SparseBooleanArray knownUids = new SparseBooleanArray();
   2441                 collectKeys(mUidState, knownUids);
   2442                 collectKeys(mUidRules, knownUids);
   2443 
   2444                 fout.println("Status for all known UIDs:");
   2445                 fout.increaseIndent();
   2446                 size = knownUids.size();
   2447                 for (int i = 0; i < size; i++) {
   2448                     final int uid = knownUids.keyAt(i);
   2449                     fout.print("UID=");
   2450                     fout.print(uid);
   2451 
   2452                     final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2453                     fout.print(" state=");
   2454                     fout.print(state);
   2455                     if (state <= ActivityManager.PROCESS_STATE_TOP) {
   2456                         fout.print(" (fg)");
   2457                     } else {
   2458                         fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
   2459                                 ? " (fg svc)" : " (bg)");
   2460                     }
   2461 
   2462                     final int uidRules = mUidRules.get(uid, RULE_NONE);
   2463                     fout.print(" rules=");
   2464                     fout.print(uidRulesToString(uidRules));
   2465                     fout.println();
   2466                 }
   2467                 fout.decreaseIndent();
   2468 
   2469                 fout.println("Status for just UIDs with rules:");
   2470                 fout.increaseIndent();
   2471                 size = mUidRules.size();
   2472                 for (int i = 0; i < size; i++) {
   2473                     final int uid = mUidRules.keyAt(i);
   2474                     fout.print("UID=");
   2475                     fout.print(uid);
   2476                     final int uidRules = mUidRules.get(uid, RULE_NONE);
   2477                     fout.print(" rules=");
   2478                     fout.print(uidRulesToString(uidRules));
   2479                     fout.println();
   2480                 }
   2481                 fout.decreaseIndent();
   2482             }
   2483         }
   2484     }
   2485 
   2486     @Override
   2487     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
   2488             String[] args, ResultReceiver resultReceiver) throws RemoteException {
   2489         (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
   2490                 this, in, out, err, args, resultReceiver);
   2491     }
   2492 
   2493     @Override
   2494     public boolean isUidForeground(int uid) {
   2495         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2496 
   2497         synchronized (mUidRulesFirstLock) {
   2498             return isUidForegroundUL(uid);
   2499         }
   2500     }
   2501 
   2502     private boolean isUidForegroundUL(int uid) {
   2503         return isUidStateForegroundUL(
   2504                 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
   2505     }
   2506 
   2507     private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
   2508         final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2509         return isProcStateAllowedWhileOnRestrictBackground(procState);
   2510     }
   2511 
   2512     private boolean isUidForegroundOnRestrictPowerUL(int uid) {
   2513         final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2514         return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
   2515     }
   2516 
   2517     private boolean isUidStateForegroundUL(int state) {
   2518         // only really in foreground when screen is also on
   2519         return state <= ActivityManager.PROCESS_STATE_TOP;
   2520     }
   2521 
   2522     /**
   2523      * Process state of UID changed; if needed, will trigger
   2524      * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
   2525      * {@link #updateRulesForPowerRestrictionsUL(int)}
   2526      */
   2527     private void updateUidStateUL(int uid, int uidState) {
   2528         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
   2529         try {
   2530             final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2531             if (oldUidState != uidState) {
   2532                 // state changed, push updated rules
   2533                 mUidState.put(uid, uidState);
   2534                 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
   2535                 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
   2536                         != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
   2537                     if (isUidIdle(uid)) {
   2538                         updateRuleForAppIdleUL(uid);
   2539                     }
   2540                     if (mDeviceIdleMode) {
   2541                         updateRuleForDeviceIdleUL(uid);
   2542                     }
   2543                     if (mRestrictPower) {
   2544                         updateRuleForRestrictPowerUL(uid);
   2545                     }
   2546                     updateRulesForPowerRestrictionsUL(uid);
   2547                 }
   2548                 updateNetworkStats(uid, isUidStateForegroundUL(uidState));
   2549             }
   2550         } finally {
   2551             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2552         }
   2553     }
   2554 
   2555     private void removeUidStateUL(int uid) {
   2556         final int index = mUidState.indexOfKey(uid);
   2557         if (index >= 0) {
   2558             final int oldUidState = mUidState.valueAt(index);
   2559             mUidState.removeAt(index);
   2560             if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2561                 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
   2562                         ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2563                 if (mDeviceIdleMode) {
   2564                     updateRuleForDeviceIdleUL(uid);
   2565                 }
   2566                 if (mRestrictPower) {
   2567                     updateRuleForRestrictPowerUL(uid);
   2568                 }
   2569                 updateRulesForPowerRestrictionsUL(uid);
   2570                 updateNetworkStats(uid, false);
   2571             }
   2572         }
   2573     }
   2574 
   2575     // adjust stats accounting based on foreground status
   2576     private void updateNetworkStats(int uid, boolean uidForeground) {
   2577         try {
   2578             mNetworkStats.setUidForeground(uid, uidForeground);
   2579         } catch (RemoteException e) {
   2580             // ignored; service lives in system_server
   2581         }
   2582     }
   2583 
   2584     private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
   2585             int newUidState) {
   2586         final boolean oldForeground =
   2587                 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
   2588         final boolean newForeground =
   2589                 isProcStateAllowedWhileOnRestrictBackground(newUidState);
   2590         if (oldForeground != newForeground) {
   2591             updateRulesForDataUsageRestrictionsUL(uid);
   2592         }
   2593     }
   2594 
   2595     static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) {
   2596         return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   2597     }
   2598 
   2599     static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
   2600         return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   2601     }
   2602 
   2603     void updateRulesForPowerSaveUL() {
   2604         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
   2605         try {
   2606             updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
   2607                     mUidFirewallPowerSaveRules);
   2608         } finally {
   2609             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2610         }
   2611     }
   2612 
   2613     void updateRuleForRestrictPowerUL(int uid) {
   2614         updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
   2615     }
   2616 
   2617     void updateRulesForDeviceIdleUL() {
   2618         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
   2619         try {
   2620             updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
   2621                     mUidFirewallDozableRules);
   2622         } finally {
   2623             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2624         }
   2625     }
   2626 
   2627     void updateRuleForDeviceIdleUL(int uid) {
   2628         updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
   2629     }
   2630 
   2631     // NOTE: since both fw_dozable and fw_powersave uses the same map
   2632     // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
   2633     private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
   2634             SparseIntArray rules) {
   2635         if (enabled) {
   2636             // Sync the whitelists before enabling the chain.  We don't care about the rules if
   2637             // we are disabling the chain.
   2638             final SparseIntArray uidRules = rules;
   2639             uidRules.clear();
   2640             final List<UserInfo> users = mUserManager.getUsers();
   2641             for (int ui = users.size() - 1; ui >= 0; ui--) {
   2642                 UserInfo user = users.get(ui);
   2643                 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
   2644                     if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
   2645                         int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
   2646                         int uid = UserHandle.getUid(user.id, appId);
   2647                         uidRules.put(uid, FIREWALL_RULE_ALLOW);
   2648                     }
   2649                 }
   2650                 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
   2651                     int appId = mPowerSaveWhitelistAppIds.keyAt(i);
   2652                     int uid = UserHandle.getUid(user.id, appId);
   2653                     uidRules.put(uid, FIREWALL_RULE_ALLOW);
   2654                 }
   2655             }
   2656             for (int i = mUidState.size() - 1; i >= 0; i--) {
   2657                 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
   2658                     uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
   2659                 }
   2660             }
   2661             setUidFirewallRulesAsync(chain, uidRules, CHAIN_TOGGLE_ENABLE);
   2662         } else {
   2663             setUidFirewallRulesAsync(chain, null, CHAIN_TOGGLE_DISABLE);
   2664         }
   2665     }
   2666 
   2667     private boolean isWhitelistedBatterySaverUL(int uid) {
   2668         final int appId = UserHandle.getAppId(uid);
   2669         return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId);
   2670     }
   2671 
   2672     // NOTE: since both fw_dozable and fw_powersave uses the same map
   2673     // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
   2674     private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
   2675         if (enabled) {
   2676             if (isWhitelistedBatterySaverUL(uid)
   2677                     || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) {
   2678                 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
   2679             } else {
   2680                 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
   2681             }
   2682         }
   2683     }
   2684 
   2685     void updateRulesForAppIdleUL() {
   2686         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
   2687         try {
   2688             final SparseIntArray uidRules = mUidFirewallStandbyRules;
   2689             uidRules.clear();
   2690 
   2691             // Fully update the app idle firewall chain.
   2692             final List<UserInfo> users = mUserManager.getUsers();
   2693             for (int ui = users.size() - 1; ui >= 0; ui--) {
   2694                 UserInfo user = users.get(ui);
   2695                 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
   2696                 for (int uid : idleUids) {
   2697                     if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
   2698                         // quick check: if this uid doesn't have INTERNET permission, it
   2699                         // doesn't have network access anyway, so it is a waste to mess
   2700                         // with it here.
   2701                         if (hasInternetPermissions(uid)) {
   2702                             uidRules.put(uid, FIREWALL_RULE_DENY);
   2703                         }
   2704                     }
   2705                 }
   2706             }
   2707 
   2708             setUidFirewallRulesAsync(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
   2709         } finally {
   2710             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2711         }
   2712     }
   2713 
   2714     void updateRuleForAppIdleUL(int uid) {
   2715         if (!isUidValidForBlacklistRules(uid)) return;
   2716 
   2717         int appId = UserHandle.getAppId(uid);
   2718         if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
   2719                 && !isUidForegroundOnRestrictPowerUL(uid)) {
   2720             setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
   2721         } else {
   2722             setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
   2723         }
   2724     }
   2725 
   2726     /**
   2727      * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
   2728      * changed.
   2729      */
   2730     void updateRulesForAppIdleParoleUL() {
   2731         boolean paroled = mUsageStats.isAppIdleParoleOn();
   2732         boolean enableChain = !paroled;
   2733         enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
   2734 
   2735         int ruleCount = mUidFirewallStandbyRules.size();
   2736         for (int i = 0; i < ruleCount; i++) {
   2737             int uid = mUidFirewallStandbyRules.keyAt(i);
   2738             int oldRules = mUidRules.get(uid);
   2739             if (enableChain) {
   2740                 // Chain wasn't enabled before and the other power-related
   2741                 // chains are whitelists, so we can clear the
   2742                 // MASK_ALL_NETWORKS part of the rules and re-inform listeners if
   2743                 // the effective rules result in blocking network access.
   2744                 oldRules &= MASK_METERED_NETWORKS;
   2745             } else {
   2746                 // Skip if it had no restrictions to begin with
   2747                 if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
   2748             }
   2749             updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
   2750         }
   2751     }
   2752 
   2753     /**
   2754      * Update rules that might be changed by {@link #mRestrictBackground},
   2755      * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
   2756      */
   2757     private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
   2758         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForGlobalChangeAL");
   2759         try {
   2760             updateRulesForAppIdleUL();
   2761             updateRulesForRestrictPowerUL();
   2762             updateRulesForRestrictBackgroundUL();
   2763 
   2764             // If the set of restricted networks may have changed, re-evaluate those.
   2765             if (restrictedNetworksChanged) {
   2766                 normalizePoliciesNL();
   2767                 updateNetworkRulesNL();
   2768             }
   2769         } finally {
   2770             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2771         }
   2772     }
   2773 
   2774     // TODO: rename / document to make it clear these are global (not app-specific) rules
   2775     private void updateRulesForRestrictPowerUL() {
   2776         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
   2777         try {
   2778             updateRulesForDeviceIdleUL();
   2779             updateRulesForPowerSaveUL();
   2780             updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
   2781         } finally {
   2782             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2783         }
   2784     }
   2785 
   2786     private void updateRulesForRestrictBackgroundUL() {
   2787         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
   2788         try {
   2789             updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
   2790         } finally {
   2791             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2792         }
   2793     }
   2794 
   2795     private static final int TYPE_RESTRICT_BACKGROUND = 1;
   2796     private static final int TYPE_RESTRICT_POWER = 2;
   2797     @Retention(RetentionPolicy.SOURCE)
   2798     @IntDef(flag = false, value = {
   2799             TYPE_RESTRICT_BACKGROUND,
   2800             TYPE_RESTRICT_POWER,
   2801     })
   2802     public @interface RestrictType {
   2803     }
   2804 
   2805     // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
   2806     private void updateRulesForAllAppsUL(@RestrictType int type) {
   2807         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
   2808             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
   2809         }
   2810         try {
   2811             final PackageManager pm = mContext.getPackageManager();
   2812 
   2813             // update rules for all installed applications
   2814             final List<UserInfo> users = mUserManager.getUsers();
   2815             final List<ApplicationInfo> apps = pm.getInstalledApplications(
   2816                     PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS
   2817                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
   2818                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
   2819 
   2820             final int usersSize = users.size();
   2821             final int appsSize = apps.size();
   2822             for (int i = 0; i < usersSize; i++) {
   2823                 final UserInfo user = users.get(i);
   2824                 for (int j = 0; j < appsSize; j++) {
   2825                     final ApplicationInfo app = apps.get(j);
   2826                     final int uid = UserHandle.getUid(user.id, app.uid);
   2827                     switch (type) {
   2828                         case TYPE_RESTRICT_BACKGROUND:
   2829                             updateRulesForDataUsageRestrictionsUL(uid);
   2830                             break;
   2831                         case TYPE_RESTRICT_POWER:
   2832                             updateRulesForPowerRestrictionsUL(uid);
   2833                             break;
   2834                         default:
   2835                             Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
   2836                     }
   2837                 }
   2838             }
   2839         } finally {
   2840             if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
   2841                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
   2842             }
   2843         }
   2844     }
   2845 
   2846     private void updateRulesForTempWhitelistChangeUL() {
   2847         final List<UserInfo> users = mUserManager.getUsers();
   2848         for (int i = 0; i < users.size(); i++) {
   2849             final UserInfo user = users.get(i);
   2850             for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) {
   2851                 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j);
   2852                 int uid = UserHandle.getUid(user.id, appId);
   2853                 // Update external firewall rules.
   2854                 updateRuleForAppIdleUL(uid);
   2855                 updateRuleForDeviceIdleUL(uid);
   2856                 updateRuleForRestrictPowerUL(uid);
   2857                 // Update internal rules.
   2858                 updateRulesForPowerRestrictionsUL(uid);
   2859             }
   2860         }
   2861     }
   2862 
   2863     // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
   2864     // methods below could be merged into a isUidValidForRules() method.
   2865     private boolean isUidValidForBlacklistRules(int uid) {
   2866         // allow rules on specific system services, and any apps
   2867         if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
   2868             || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
   2869             return true;
   2870         }
   2871 
   2872         return false;
   2873     }
   2874 
   2875     private boolean isUidValidForWhitelistRules(int uid) {
   2876         return UserHandle.isApp(uid) && hasInternetPermissions(uid);
   2877     }
   2878 
   2879     private boolean isUidIdle(int uid) {
   2880         final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
   2881         final int userId = UserHandle.getUserId(uid);
   2882 
   2883         if (!ArrayUtils.isEmpty(packages)) {
   2884             for (String packageName : packages) {
   2885                 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
   2886                     return false;
   2887                 }
   2888             }
   2889         }
   2890         return true;
   2891     }
   2892 
   2893     /**
   2894      * Checks if an uid has INTERNET permissions.
   2895      * <p>
   2896      * Useful for the cases where the lack of network access can simplify the rules.
   2897      */
   2898     private boolean hasInternetPermissions(int uid) {
   2899         try {
   2900             if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
   2901                     != PackageManager.PERMISSION_GRANTED) {
   2902                 return false;
   2903             }
   2904         } catch (RemoteException e) {
   2905         }
   2906         return true;
   2907     }
   2908 
   2909     /**
   2910      * Applies network rules to bandwidth and firewall controllers based on uid policy.
   2911      *
   2912      * <p>There are currently 4 types of restriction rules:
   2913      * <ul>
   2914      * <li>Doze mode
   2915      * <li>App idle mode
   2916      * <li>Battery Saver Mode (also referred as power save).
   2917      * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
   2918      * </ul>
   2919      *
   2920      * <p>This method changes both the external firewall rules and the internal state.
   2921      */
   2922     private void updateRestrictionRulesForUidUL(int uid) {
   2923         // Methods below only changes the firewall rules for the power-related modes.
   2924         updateRuleForDeviceIdleUL(uid);
   2925         updateRuleForAppIdleUL(uid);
   2926         updateRuleForRestrictPowerUL(uid);
   2927 
   2928         // Update internal state for power-related modes.
   2929         updateRulesForPowerRestrictionsUL(uid);
   2930 
   2931         // Update firewall and internal rules for Data Saver Mode.
   2932         updateRulesForDataUsageRestrictionsUL(uid);
   2933     }
   2934 
   2935     /**
   2936      * Applies network rules to bandwidth controllers based on process state and user-defined
   2937      * restrictions (blacklist / whitelist).
   2938      *
   2939      * <p>
   2940      * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
   2941      * networks:
   2942      * <ul>
   2943      * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
   2944      * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
   2945      *     also blacklisted.
   2946      * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
   2947      *     no UIDs other those whitelisted will have access.
   2948      * <ul>
   2949      *
   2950      * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
   2951      * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
   2952      * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
   2953      * respectively): these methods set the proper internal state (blacklist / whitelist), then call
   2954      * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
   2955      * {@link INetworkManagementService}, but this method should also be called in events (like
   2956      * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
   2957      * following rules should also be applied:
   2958      *
   2959      * <ul>
   2960      * <li>When Data Saver mode is on, the foreground app should be temporarily added to
   2961      *     {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
   2962      * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
   2963      *     {@code bw_penalty_box}.
   2964      * <li>When the app leaves foreground state, the temporary changes above should be reverted.
   2965      * </ul>
   2966      *
   2967      * <p>For optimization, the rules are only applied on user apps that have internet access
   2968      * permission, since there is no need to change the {@code iptables} rule if the app does not
   2969      * have permission to use the internet.
   2970      *
   2971      * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
   2972      *
   2973      */
   2974     private void updateRulesForDataUsageRestrictionsUL(int uid) {
   2975         updateRulesForDataUsageRestrictionsUL(uid, false);
   2976     }
   2977 
   2978     /**
   2979      * Overloaded version of {@link #updateRulesForDataUsageRestrictionsUL(int)} called when an
   2980      * app is removed - it ignores the UID validity check.
   2981      */
   2982     private void updateRulesForDataUsageRestrictionsUL(int uid, boolean uidDeleted) {
   2983         if (!uidDeleted && !isUidValidForWhitelistRules(uid)) {
   2984             if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
   2985             return;
   2986         }
   2987 
   2988         final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
   2989         final int oldUidRules = mUidRules.get(uid, RULE_NONE);
   2990         final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
   2991 
   2992         final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
   2993         final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid);
   2994         final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
   2995         int newRule = RULE_NONE;
   2996 
   2997         // First step: define the new rule based on user restrictions and foreground state.
   2998         if (isForeground) {
   2999             if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
   3000                 newRule = RULE_TEMPORARY_ALLOW_METERED;
   3001             } else if (isWhitelisted) {
   3002                 newRule = RULE_ALLOW_METERED;
   3003             }
   3004         } else {
   3005             if (isBlacklisted) {
   3006                 newRule = RULE_REJECT_METERED;
   3007             } else if (mRestrictBackground && isWhitelisted) {
   3008                 newRule = RULE_ALLOW_METERED;
   3009             }
   3010         }
   3011         final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
   3012 
   3013         if (LOGV) {
   3014             Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
   3015                     + ": isForeground=" +isForeground
   3016                     + ", isBlacklisted=" + isBlacklisted
   3017                     + ", isWhitelisted=" + isWhitelisted
   3018                     + ", oldRule=" + uidRulesToString(oldRule)
   3019                     + ", newRule=" + uidRulesToString(newRule)
   3020                     + ", newUidRules=" + uidRulesToString(newUidRules)
   3021                     + ", oldUidRules=" + uidRulesToString(oldUidRules));
   3022         }
   3023 
   3024         if (newUidRules == RULE_NONE) {
   3025             mUidRules.delete(uid);
   3026         } else {
   3027             mUidRules.put(uid, newUidRules);
   3028         }
   3029 
   3030         // Second step: apply bw changes based on change of state.
   3031         if (newRule != oldRule) {
   3032             if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
   3033                 // Temporarily whitelist foreground app, removing from blacklist if necessary
   3034                 // (since bw_penalty_box prevails over bw_happy_box).
   3035 
   3036                 setMeteredNetworkWhitelist(uid, true);
   3037                 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
   3038                 // but ideally it should be just:
   3039                 //    setMeteredNetworkBlacklist(uid, isBlacklisted);
   3040                 if (isBlacklisted) {
   3041                     setMeteredNetworkBlacklist(uid, false);
   3042                 }
   3043             } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
   3044                 // Remove temporary whitelist from app that is not on foreground anymore.
   3045 
   3046                 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
   3047                 // but ideally they should be just:
   3048                 //    setMeteredNetworkWhitelist(uid, isWhitelisted);
   3049                 //    setMeteredNetworkBlacklist(uid, isBlacklisted);
   3050                 if (!isWhitelisted) {
   3051                     setMeteredNetworkWhitelist(uid, false);
   3052                 }
   3053                 if (isBlacklisted) {
   3054                     setMeteredNetworkBlacklist(uid, true);
   3055                 }
   3056             } else if ((newRule & RULE_REJECT_METERED) != 0
   3057                     || (oldRule & RULE_REJECT_METERED) != 0) {
   3058                 // Flip state because app was explicitly added or removed to blacklist.
   3059                 setMeteredNetworkBlacklist(uid, isBlacklisted);
   3060                 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) {
   3061                     // Since blacklist prevails over whitelist, we need to handle the special case
   3062                     // where app is whitelisted and blacklisted at the same time (although such
   3063                     // scenario should be blocked by the UI), then blacklist is removed.
   3064                     setMeteredNetworkWhitelist(uid, isWhitelisted);
   3065                 }
   3066             } else if ((newRule & RULE_ALLOW_METERED) != 0
   3067                     || (oldRule & RULE_ALLOW_METERED) != 0) {
   3068                 // Flip state because app was explicitly added or removed to whitelist.
   3069                 setMeteredNetworkWhitelist(uid, isWhitelisted);
   3070             } else {
   3071                 // All scenarios should have been covered above.
   3072                 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
   3073                         + ": foreground=" + isForeground
   3074                         + ", whitelisted=" + isWhitelisted
   3075                         + ", blacklisted=" + isBlacklisted
   3076                         + ", newRule=" + uidRulesToString(newUidRules)
   3077                         + ", oldRule=" + uidRulesToString(oldUidRules));
   3078             }
   3079 
   3080             // Dispatch changed rule to existing listeners.
   3081             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
   3082         }
   3083     }
   3084 
   3085     /**
   3086      * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
   3087      * listeners in case of change.
   3088      * <p>
   3089      * There are 3 power-related rules that affects whether an app has background access on
   3090      * non-metered networks, and when the condition applies and the UID is not whitelisted for power
   3091      * restriction, it's added to the equivalent firewall chain:
   3092      * <ul>
   3093      * <li>App is idle: {@code fw_standby} firewall chain.
   3094      * <li>Device is idle: {@code fw_dozable} firewall chain.
   3095      * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
   3096      * </ul>
   3097      * <p>
   3098      * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
   3099      * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
   3100      * <p>
   3101      * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
   3102      */
   3103     private void updateRulesForPowerRestrictionsUL(int uid) {
   3104         final int oldUidRules = mUidRules.get(uid, RULE_NONE);
   3105 
   3106         final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false);
   3107 
   3108         if (newUidRules == RULE_NONE) {
   3109             mUidRules.delete(uid);
   3110         } else {
   3111             mUidRules.put(uid, newUidRules);
   3112         }
   3113     }
   3114 
   3115     /**
   3116      * Similar to above but ignores idle state if app standby is currently disabled by parole.
   3117      *
   3118      * @param uid the uid of the app to update rules for
   3119      * @param oldUidRules the current rules for the uid, in order to determine if there's a change
   3120      * @param paroled whether to ignore idle state of apps and only look at other restrictions.
   3121      *
   3122      * @return the new computed rules for the uid
   3123      */
   3124     private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) {
   3125         if (!isUidValidForBlacklistRules(uid)) {
   3126             if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
   3127             return RULE_NONE;
   3128         }
   3129 
   3130         final boolean isIdle = !paroled && isUidIdle(uid);
   3131         final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
   3132         final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
   3133 
   3134         final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid);
   3135         final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
   3136         int newRule = RULE_NONE;
   3137 
   3138         // First step: define the new rule based on user restrictions and foreground state.
   3139 
   3140         // NOTE: if statements below could be inlined, but it's easier to understand the logic
   3141         // by considering the foreground and non-foreground states.
   3142         if (isForeground) {
   3143             if (restrictMode) {
   3144                 newRule = RULE_ALLOW_ALL;
   3145             }
   3146         } else if (restrictMode) {
   3147             newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
   3148         }
   3149 
   3150         final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
   3151 
   3152         if (LOGV) {
   3153             Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
   3154                     + ", isIdle: " + isIdle
   3155                     + ", mRestrictPower: " + mRestrictPower
   3156                     + ", mDeviceIdleMode: " + mDeviceIdleMode
   3157                     + ", isForeground=" + isForeground
   3158                     + ", isWhitelisted=" + isWhitelisted
   3159                     + ", oldRule=" + uidRulesToString(oldRule)
   3160                     + ", newRule=" + uidRulesToString(newRule)
   3161                     + ", newUidRules=" + uidRulesToString(newUidRules)
   3162                     + ", oldUidRules=" + uidRulesToString(oldUidRules));
   3163         }
   3164 
   3165         // Second step: notify listeners if state changed.
   3166         if (newRule != oldRule) {
   3167             if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) {
   3168                 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
   3169             } else if ((newRule & RULE_REJECT_ALL) != 0) {
   3170                 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
   3171             } else {
   3172                 // All scenarios should have been covered above
   3173                 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
   3174                         + ": foreground=" + isForeground
   3175                         + ", whitelisted=" + isWhitelisted
   3176                         + ", newRule=" + uidRulesToString(newUidRules)
   3177                         + ", oldRule=" + uidRulesToString(oldUidRules));
   3178             }
   3179             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
   3180         }
   3181 
   3182         return newUidRules;
   3183     }
   3184 
   3185     private class AppIdleStateChangeListener
   3186             extends UsageStatsManagerInternal.AppIdleStateChangeListener {
   3187 
   3188         @Override
   3189         public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
   3190             try {
   3191                 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
   3192                         PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
   3193                 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle);
   3194                 synchronized (mUidRulesFirstLock) {
   3195                     updateRuleForAppIdleUL(uid);
   3196                     updateRulesForPowerRestrictionsUL(uid);
   3197                 }
   3198             } catch (NameNotFoundException nnfe) {
   3199             }
   3200         }
   3201 
   3202         @Override
   3203         public void onParoleStateChanged(boolean isParoleOn) {
   3204             synchronized (mUidRulesFirstLock) {
   3205                 updateRulesForAppIdleParoleUL();
   3206             }
   3207         }
   3208     }
   3209 
   3210     private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
   3211         if (listener != null) {
   3212             try {
   3213                 listener.onUidRulesChanged(uid, uidRules);
   3214             } catch (RemoteException ignored) {
   3215             }
   3216         }
   3217     }
   3218 
   3219     private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
   3220             String[] meteredIfaces) {
   3221         if (listener != null) {
   3222             try {
   3223                 listener.onMeteredIfacesChanged(meteredIfaces);
   3224             } catch (RemoteException ignored) {
   3225             }
   3226         }
   3227     }
   3228 
   3229     private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
   3230             boolean restrictBackground) {
   3231         if (listener != null) {
   3232             try {
   3233                 listener.onRestrictBackgroundChanged(restrictBackground);
   3234             } catch (RemoteException ignored) {
   3235             }
   3236         }
   3237     }
   3238 
   3239     private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener,
   3240             int uid, boolean whitelisted) {
   3241         if (listener != null) {
   3242             try {
   3243                 listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted);
   3244             } catch (RemoteException ignored) {
   3245             }
   3246         }
   3247     }
   3248 
   3249     private void dispatchRestrictBackgroundBlacklistChanged(INetworkPolicyListener listener,
   3250             int uid, boolean blacklisted) {
   3251         if (listener != null) {
   3252             try {
   3253                 listener.onRestrictBackgroundBlacklistChanged(uid, blacklisted);
   3254             } catch (RemoteException ignored) {
   3255             }
   3256         }
   3257     }
   3258 
   3259     private Handler.Callback mHandlerCallback = new Handler.Callback() {
   3260         @Override
   3261         public boolean handleMessage(Message msg) {
   3262             switch (msg.what) {
   3263                 case MSG_RULES_CHANGED: {
   3264                     final int uid = msg.arg1;
   3265                     final int uidRules = msg.arg2;
   3266                     dispatchUidRulesChanged(mConnectivityListener, uid, uidRules);
   3267                     final int length = mListeners.beginBroadcast();
   3268                     for (int i = 0; i < length; i++) {
   3269                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   3270                         dispatchUidRulesChanged(listener, uid, uidRules);
   3271                     }
   3272                     mListeners.finishBroadcast();
   3273                     return true;
   3274                 }
   3275                 case MSG_METERED_IFACES_CHANGED: {
   3276                     final String[] meteredIfaces = (String[]) msg.obj;
   3277                     dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces);
   3278                     final int length = mListeners.beginBroadcast();
   3279                     for (int i = 0; i < length; i++) {
   3280                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   3281                         dispatchMeteredIfacesChanged(listener, meteredIfaces);
   3282                     }
   3283                     mListeners.finishBroadcast();
   3284                     return true;
   3285                 }
   3286                 case MSG_LIMIT_REACHED: {
   3287                     final String iface = (String) msg.obj;
   3288 
   3289                     maybeRefreshTrustedTime();
   3290                     synchronized (mNetworkPoliciesSecondLock) {
   3291                         if (mMeteredIfaces.contains(iface)) {
   3292                             try {
   3293                                 // force stats update to make sure we have
   3294                                 // numbers that caused alert to trigger.
   3295                                 mNetworkStats.forceUpdate();
   3296                             } catch (RemoteException e) {
   3297                                 // ignored; service lives in system_server
   3298                             }
   3299 
   3300                             updateNetworkEnabledNL();
   3301                             updateNotificationsNL();
   3302                         }
   3303                     }
   3304                     return true;
   3305                 }
   3306                 case MSG_RESTRICT_BACKGROUND_CHANGED: {
   3307                     final boolean restrictBackground = msg.arg1 != 0;
   3308                     dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground);
   3309                     final int length = mListeners.beginBroadcast();
   3310                     for (int i = 0; i < length; i++) {
   3311                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   3312                         dispatchRestrictBackgroundChanged(listener, restrictBackground);
   3313                     }
   3314                     mListeners.finishBroadcast();
   3315                     final Intent intent =
   3316                             new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
   3317                     intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3318                     mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
   3319                     return true;
   3320                 }
   3321                 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: {
   3322                     // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions:
   3323                     // - when an app is whitelisted
   3324                     // - when an app is blacklisted
   3325                     //
   3326                     // Whether the internal listeners (INetworkPolicyListener implementations) or
   3327                     // app broadcast receivers are notified depend on the following rules:
   3328                     //
   3329                     // - App receivers are only notified when the app status changed (msg.arg2 = 1)
   3330                     // - Listeners are only notified when app was whitelisted (msg.obj is not null),
   3331                     //   since blacklist notifications are handled through MSG_RULES_CHANGED).
   3332                     final int uid = msg.arg1;
   3333                     final boolean changed = msg.arg2 == 1;
   3334                     final Boolean whitelisted = (Boolean) msg.obj;
   3335 
   3336                     // First notify internal listeners...
   3337                     if (whitelisted != null) {
   3338                         final boolean whitelistedBool = whitelisted.booleanValue();
   3339                         dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid,
   3340                                 whitelistedBool);
   3341                         final int length = mListeners.beginBroadcast();
   3342                         for (int i = 0; i < length; i++) {
   3343                             final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   3344                             dispatchRestrictBackgroundWhitelistChanged(listener, uid,
   3345                                     whitelistedBool);
   3346                         }
   3347                         mListeners.finishBroadcast();
   3348                     }
   3349                     final PackageManager pm = mContext.getPackageManager();
   3350                     final String[] packages = pm.getPackagesForUid(uid);
   3351                     if (changed && packages != null) {
   3352                         // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
   3353                         final int userId = UserHandle.getUserId(uid);
   3354                         for (String packageName : packages) {
   3355                             final Intent intent = new Intent(
   3356                                     ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
   3357                             intent.setPackage(packageName);
   3358                             intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3359                             mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
   3360                         }
   3361                     }
   3362                     return true;
   3363                 }
   3364                 case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: {
   3365                     final int uid = msg.arg1;
   3366                     final boolean blacklisted = msg.arg2 == 1;
   3367 
   3368                     dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid,
   3369                             blacklisted);
   3370                     final int length = mListeners.beginBroadcast();
   3371                     for (int i = 0; i < length; i++) {
   3372                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   3373                         dispatchRestrictBackgroundBlacklistChanged(listener, uid,
   3374                                 blacklisted);
   3375                     }
   3376                     mListeners.finishBroadcast();
   3377                     return true;
   3378                 }
   3379                 case MSG_ADVISE_PERSIST_THRESHOLD: {
   3380                     final long lowestRule = (Long) msg.obj;
   3381                     try {
   3382                         // make sure stats are recorded frequently enough; we aim
   3383                         // for 2MB threshold for 2GB/month rules.
   3384                         final long persistThreshold = lowestRule / 1000;
   3385                         mNetworkStats.advisePersistThreshold(persistThreshold);
   3386                     } catch (RemoteException e) {
   3387                         // ignored; service lives in system_server
   3388                     }
   3389                     return true;
   3390                 }
   3391                 case MSG_UPDATE_INTERFACE_QUOTA: {
   3392                     removeInterfaceQuota((String) msg.obj);
   3393                     // int params need to be stitched back into a long
   3394                     setInterfaceQuota((String) msg.obj,
   3395                             ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
   3396                     return true;
   3397                 }
   3398                 case MSG_REMOVE_INTERFACE_QUOTA: {
   3399                     removeInterfaceQuota((String) msg.obj);
   3400                     return true;
   3401                 }
   3402                 case MSG_SET_FIREWALL_RULES: {
   3403                     final int chain = msg.arg1;
   3404                     final int toggle = msg.arg2;
   3405                     final SparseIntArray uidRules = (SparseIntArray) msg.obj;
   3406                     if (uidRules != null) {
   3407                         setUidFirewallRules(chain, uidRules);
   3408                     }
   3409                     if (toggle != CHAIN_TOGGLE_NONE) {
   3410                         enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
   3411                     }
   3412                     return true;
   3413                 }
   3414                 default: {
   3415                     return false;
   3416                 }
   3417             }
   3418         }
   3419     };
   3420 
   3421     private void setInterfaceQuota(String iface, long quotaBytes) {
   3422         try {
   3423             mNetworkManager.setInterfaceQuota(iface, quotaBytes);
   3424         } catch (IllegalStateException e) {
   3425             Log.wtf(TAG, "problem setting interface quota", e);
   3426         } catch (RemoteException e) {
   3427             // ignored; service lives in system_server
   3428         }
   3429     }
   3430 
   3431     private void removeInterfaceQuota(String iface) {
   3432         try {
   3433             mNetworkManager.removeInterfaceQuota(iface);
   3434         } catch (IllegalStateException e) {
   3435             Log.wtf(TAG, "problem removing interface quota", e);
   3436         } catch (RemoteException e) {
   3437             // ignored; service lives in system_server
   3438         }
   3439     }
   3440 
   3441     private void setMeteredNetworkBlacklist(int uid, boolean enable) {
   3442         if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
   3443         try {
   3444             mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
   3445         } catch (IllegalStateException e) {
   3446             Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
   3447         } catch (RemoteException e) {
   3448             // ignored; service lives in system_server
   3449         }
   3450     }
   3451 
   3452     private void setMeteredNetworkWhitelist(int uid, boolean enable) {
   3453         if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
   3454         try {
   3455             mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
   3456         } catch (IllegalStateException e) {
   3457             Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
   3458         } catch (RemoteException e) {
   3459             // ignored; service lives in system_server
   3460         }
   3461     }
   3462 
   3463     private static final int CHAIN_TOGGLE_NONE = 0;
   3464     private static final int CHAIN_TOGGLE_ENABLE = 1;
   3465     private static final int CHAIN_TOGGLE_DISABLE = 2;
   3466     @Retention(RetentionPolicy.SOURCE)
   3467     @IntDef(flag = false, value = {
   3468             CHAIN_TOGGLE_NONE,
   3469             CHAIN_TOGGLE_ENABLE,
   3470             CHAIN_TOGGLE_DISABLE
   3471     })
   3472     public @interface ChainToggleType {
   3473     }
   3474 
   3475     /**
   3476      * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
   3477      * {@link #enableFirewallChainUL(int, boolean)} asynchronously.
   3478      *
   3479      * @param chain firewall chain.
   3480      * @param uidRules new UID rules; if {@code null}, only toggles chain state.
   3481      * @param toggle whether the chain should be enabled, disabled, or not changed.
   3482      */
   3483     private void setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules,
   3484             @ChainToggleType int toggle) {
   3485         mHandler.obtainMessage(MSG_SET_FIREWALL_RULES, chain, toggle, uidRules).sendToTarget();
   3486     }
   3487 
   3488     /**
   3489      * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
   3490      * here to netd.  It will clean up dead rules and make sure the target chain only contains rules
   3491      * specified here.
   3492      */
   3493     private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
   3494         try {
   3495             int size = uidRules.size();
   3496             int[] uids = new int[size];
   3497             int[] rules = new int[size];
   3498             for(int index = size - 1; index >= 0; --index) {
   3499                 uids[index] = uidRules.keyAt(index);
   3500                 rules[index] = uidRules.valueAt(index);
   3501             }
   3502             mNetworkManager.setFirewallUidRules(chain, uids, rules);
   3503         } catch (IllegalStateException e) {
   3504             Log.wtf(TAG, "problem setting firewall uid rules", e);
   3505         } catch (RemoteException e) {
   3506             // ignored; service lives in system_server
   3507         }
   3508     }
   3509 
   3510     /**
   3511      * Add or remove a uid to the firewall blacklist for all network ifaces.
   3512      */
   3513     private void setUidFirewallRule(int chain, int uid, int rule) {
   3514         if (chain == FIREWALL_CHAIN_DOZABLE) {
   3515             mUidFirewallDozableRules.put(uid, rule);
   3516         } else if (chain == FIREWALL_CHAIN_STANDBY) {
   3517             mUidFirewallStandbyRules.put(uid, rule);
   3518         } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
   3519             mUidFirewallPowerSaveRules.put(uid, rule);
   3520         }
   3521 
   3522         try {
   3523             mNetworkManager.setFirewallUidRule(chain, uid, rule);
   3524         } catch (IllegalStateException e) {
   3525             Log.wtf(TAG, "problem setting firewall uid rules", e);
   3526         } catch (RemoteException e) {
   3527             // ignored; service lives in system_server
   3528         }
   3529     }
   3530 
   3531     /**
   3532      * Add or remove a uid to the firewall blacklist for all network ifaces.
   3533      */
   3534     private void enableFirewallChainUL(int chain, boolean enable) {
   3535         if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
   3536                 mFirewallChainStates.get(chain) == enable) {
   3537             // All is the same, nothing to do.
   3538             return;
   3539         }
   3540         mFirewallChainStates.put(chain, enable);
   3541         try {
   3542             mNetworkManager.setFirewallChainEnabled(chain, enable);
   3543         } catch (IllegalStateException e) {
   3544             Log.wtf(TAG, "problem enable firewall chain", e);
   3545         } catch (RemoteException e) {
   3546             // ignored; service lives in system_server
   3547         }
   3548     }
   3549 
   3550     private long getTotalBytes(NetworkTemplate template, long start, long end) {
   3551         try {
   3552             return mNetworkStats.getNetworkTotalBytes(template, start, end);
   3553         } catch (RuntimeException e) {
   3554             Slog.w(TAG, "problem reading network stats: " + e);
   3555             return 0;
   3556         } catch (RemoteException e) {
   3557             // ignored; service lives in system_server
   3558             return 0;
   3559         }
   3560     }
   3561 
   3562     private boolean isBandwidthControlEnabled() {
   3563         final long token = Binder.clearCallingIdentity();
   3564         try {
   3565             return mNetworkManager.isBandwidthControlEnabled();
   3566         } catch (RemoteException e) {
   3567             // ignored; service lives in system_server
   3568             return false;
   3569         } finally {
   3570             Binder.restoreCallingIdentity(token);
   3571         }
   3572     }
   3573 
   3574     /**
   3575      * Try refreshing {@link #mTime} when stale.
   3576      */
   3577     void maybeRefreshTrustedTime() {
   3578         if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
   3579             mTime.forceRefresh();
   3580         }
   3581     }
   3582 
   3583     private long currentTimeMillis() {
   3584         return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
   3585     }
   3586 
   3587     private static Intent buildAllowBackgroundDataIntent() {
   3588         return new Intent(ACTION_ALLOW_BACKGROUND);
   3589     }
   3590 
   3591     private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
   3592         final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
   3593         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   3594         return intent;
   3595     }
   3596 
   3597     private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
   3598         final Intent intent = new Intent();
   3599         intent.setComponent(new ComponentName(
   3600                 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity"));
   3601         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3602         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   3603         return intent;
   3604     }
   3605 
   3606     private static Intent buildViewDataUsageIntent(NetworkTemplate template) {
   3607         final Intent intent = new Intent();
   3608         intent.setComponent(new ComponentName(
   3609                 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
   3610         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3611         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   3612         return intent;
   3613     }
   3614 
   3615     @VisibleForTesting
   3616     public void addIdleHandler(IdleHandler handler) {
   3617         mHandler.getLooper().getQueue().addIdleHandler(handler);
   3618     }
   3619 
   3620     private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
   3621         final int size = source.size();
   3622         for (int i = 0; i < size; i++) {
   3623             target.put(source.keyAt(i), true);
   3624         }
   3625     }
   3626 
   3627     @Override
   3628     public void factoryReset(String subscriber) {
   3629         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   3630 
   3631         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
   3632             return;
   3633         }
   3634 
   3635         // Turn mobile data limit off
   3636         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
   3637         NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
   3638         for (NetworkPolicy policy : policies) {
   3639             if (policy.template.equals(template)) {
   3640                 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
   3641                 policy.inferred = false;
   3642                 policy.clearSnooze();
   3643             }
   3644         }
   3645         setNetworkPolicies(policies);
   3646 
   3647         // Turn restrict background data off
   3648         setRestrictBackground(false);
   3649 
   3650         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
   3651             // Remove app's "restrict background data" flag
   3652             for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
   3653                 setUidPolicy(uid, POLICY_NONE);
   3654             }
   3655         }
   3656     }
   3657 
   3658     private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
   3659 
   3660         @Override
   3661         public void resetUserState(int userId) {
   3662             synchronized (mUidRulesFirstLock) {
   3663                 boolean changed = removeUserStateUL(userId, false);
   3664                 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
   3665                 if (changed) {
   3666                     synchronized (mNetworkPoliciesSecondLock) {
   3667                         writePolicyAL();
   3668                     }
   3669                 }
   3670             }
   3671         }
   3672     }
   3673 }
   3674