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