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