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.TYPE_MOBILE;
     33 import static android.net.ConnectivityManager.TYPE_WIMAX;
     34 import static android.net.ConnectivityManager.isNetworkTypeMobile;
     35 import static android.net.NetworkPolicy.CYCLE_NONE;
     36 import static android.net.NetworkPolicy.LIMIT_DISABLED;
     37 import static android.net.NetworkPolicy.SNOOZE_NEVER;
     38 import static android.net.NetworkPolicy.WARNING_DISABLED;
     39 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
     40 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
     41 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
     42 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
     43 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
     44 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
     45 import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
     46 import static android.net.NetworkPolicyManager.POLICY_NONE;
     47 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
     48 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
     49 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
     50 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
     51 import static android.net.NetworkPolicyManager.dumpPolicy;
     52 import static android.net.NetworkPolicyManager.dumpRules;
     53 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
     54 import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
     55 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
     56 import static android.net.NetworkTemplate.MATCH_WIFI;
     57 import static android.net.NetworkTemplate.buildTemplateMobileAll;
     58 import static android.net.TrafficStats.MB_IN_BYTES;
     59 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
     60 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
     61 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
     62 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
     63 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
     64 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
     65 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
     66 import static android.text.format.DateUtils.DAY_IN_MILLIS;
     67 import static com.android.internal.util.ArrayUtils.appendInt;
     68 import static com.android.internal.util.Preconditions.checkNotNull;
     69 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
     70 import static com.android.internal.util.XmlUtils.readIntAttribute;
     71 import static com.android.internal.util.XmlUtils.readLongAttribute;
     72 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
     73 import static com.android.internal.util.XmlUtils.writeIntAttribute;
     74 import static com.android.internal.util.XmlUtils.writeLongAttribute;
     75 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
     76 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
     77 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     78 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     79 
     80 import android.Manifest;
     81 import android.app.ActivityManager;
     82 import android.app.AppGlobals;
     83 import android.app.AppOpsManager;
     84 import android.app.IActivityManager;
     85 import android.app.INotificationManager;
     86 import android.app.IUidObserver;
     87 import android.app.Notification;
     88 import android.app.PendingIntent;
     89 import android.app.usage.UsageStatsManagerInternal;
     90 import android.content.BroadcastReceiver;
     91 import android.content.ComponentName;
     92 import android.content.Context;
     93 import android.content.Intent;
     94 import android.content.IntentFilter;
     95 import android.content.pm.ApplicationInfo;
     96 import android.content.pm.IPackageManager;
     97 import android.content.pm.PackageManager;
     98 import android.content.pm.PackageManager.NameNotFoundException;
     99 import android.content.pm.UserInfo;
    100 import android.content.res.Resources;
    101 import android.net.ConnectivityManager;
    102 import android.net.IConnectivityManager;
    103 import android.net.INetworkManagementEventObserver;
    104 import android.net.INetworkPolicyListener;
    105 import android.net.INetworkPolicyManager;
    106 import android.net.INetworkStatsService;
    107 import android.net.LinkProperties;
    108 import android.net.NetworkIdentity;
    109 import android.net.NetworkInfo;
    110 import android.net.NetworkPolicy;
    111 import android.net.NetworkQuotaInfo;
    112 import android.net.NetworkState;
    113 import android.net.NetworkTemplate;
    114 import android.net.wifi.WifiConfiguration;
    115 import android.net.wifi.WifiInfo;
    116 import android.net.wifi.WifiManager;
    117 import android.os.Binder;
    118 import android.os.Environment;
    119 import android.os.Handler;
    120 import android.os.HandlerThread;
    121 import android.os.IDeviceIdleController;
    122 import android.os.INetworkManagementService;
    123 import android.os.IPowerManager;
    124 import android.os.Message;
    125 import android.os.MessageQueue.IdleHandler;
    126 import android.os.PowerManager;
    127 import android.os.PowerManagerInternal;
    128 import android.os.RemoteCallbackList;
    129 import android.os.RemoteException;
    130 import android.os.ServiceManager;
    131 import android.os.UserHandle;
    132 import android.os.UserManager;
    133 import android.provider.Settings;
    134 import android.telephony.SubscriptionManager;
    135 import android.telephony.TelephonyManager;
    136 import android.text.format.Formatter;
    137 import android.text.format.Time;
    138 import android.util.ArrayMap;
    139 import android.util.ArraySet;
    140 import android.util.AtomicFile;
    141 import android.util.Log;
    142 import android.util.NtpTrustedTime;
    143 import android.util.Pair;
    144 import android.util.Slog;
    145 import android.util.SparseBooleanArray;
    146 import android.util.SparseIntArray;
    147 import android.util.TrustedTime;
    148 import android.util.Xml;
    149 
    150 import com.android.server.DeviceIdleController;
    151 import com.android.server.EventLogTags;
    152 import libcore.io.IoUtils;
    153 
    154 import com.android.internal.R;
    155 import com.android.internal.annotations.VisibleForTesting;
    156 import com.android.internal.util.ArrayUtils;
    157 import com.android.internal.util.FastXmlSerializer;
    158 import com.android.internal.util.IndentingPrintWriter;
    159 import com.android.server.LocalServices;
    160 import com.google.android.collect.Lists;
    161 
    162 import org.xmlpull.v1.XmlPullParser;
    163 import org.xmlpull.v1.XmlPullParserException;
    164 import org.xmlpull.v1.XmlSerializer;
    165 
    166 import java.io.File;
    167 import java.io.FileDescriptor;
    168 import java.io.FileInputStream;
    169 import java.io.FileNotFoundException;
    170 import java.io.FileOutputStream;
    171 import java.io.IOException;
    172 import java.io.PrintWriter;
    173 import java.nio.charset.StandardCharsets;
    174 import java.util.ArrayList;
    175 import java.util.Arrays;
    176 import java.util.List;
    177 
    178 /**
    179  * Service that maintains low-level network policy rules, using
    180  * {@link NetworkStatsService} statistics to drive those rules.
    181  * <p>
    182  * Derives active rules by combining a given policy with other system status,
    183  * and delivers to listeners, such as {@link ConnectivityManager}, for
    184  * enforcement.
    185  */
    186 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    187     private static final String TAG = "NetworkPolicy";
    188     private static final boolean LOGD = false;
    189     private static final boolean LOGV = false;
    190 
    191     private static final int VERSION_INIT = 1;
    192     private static final int VERSION_ADDED_SNOOZE = 2;
    193     private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
    194     private static final int VERSION_ADDED_METERED = 4;
    195     private static final int VERSION_SPLIT_SNOOZE = 5;
    196     private static final int VERSION_ADDED_TIMEZONE = 6;
    197     private static final int VERSION_ADDED_INFERRED = 7;
    198     private static final int VERSION_SWITCH_APP_ID = 8;
    199     private static final int VERSION_ADDED_NETWORK_ID = 9;
    200     private static final int VERSION_SWITCH_UID = 10;
    201     private static final int VERSION_LATEST = VERSION_SWITCH_UID;
    202 
    203     @VisibleForTesting
    204     public static final int TYPE_WARNING = 0x1;
    205     @VisibleForTesting
    206     public static final int TYPE_LIMIT = 0x2;
    207     @VisibleForTesting
    208     public static final int TYPE_LIMIT_SNOOZED = 0x3;
    209 
    210     private static final String TAG_POLICY_LIST = "policy-list";
    211     private static final String TAG_NETWORK_POLICY = "network-policy";
    212     private static final String TAG_UID_POLICY = "uid-policy";
    213     private static final String TAG_APP_POLICY = "app-policy";
    214 
    215     private static final String ATTR_VERSION = "version";
    216     private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
    217     private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
    218     private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
    219     private static final String ATTR_NETWORK_ID = "networkId";
    220     private static final String ATTR_CYCLE_DAY = "cycleDay";
    221     private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
    222     private static final String ATTR_WARNING_BYTES = "warningBytes";
    223     private static final String ATTR_LIMIT_BYTES = "limitBytes";
    224     private static final String ATTR_LAST_SNOOZE = "lastSnooze";
    225     private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
    226     private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
    227     private static final String ATTR_METERED = "metered";
    228     private static final String ATTR_INFERRED = "inferred";
    229     private static final String ATTR_UID = "uid";
    230     private static final String ATTR_APP_ID = "appId";
    231     private static final String ATTR_POLICY = "policy";
    232 
    233     private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground";
    234 
    235     private static final String ACTION_ALLOW_BACKGROUND =
    236             "com.android.server.net.action.ALLOW_BACKGROUND";
    237     private static final String ACTION_SNOOZE_WARNING =
    238             "com.android.server.net.action.SNOOZE_WARNING";
    239 
    240     private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
    241 
    242     private static final int MSG_RULES_CHANGED = 1;
    243     private static final int MSG_METERED_IFACES_CHANGED = 2;
    244     private static final int MSG_LIMIT_REACHED = 5;
    245     private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
    246     private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
    247     private static final int MSG_SCREEN_ON_CHANGED = 8;
    248 
    249     private final Context mContext;
    250     private final IActivityManager mActivityManager;
    251     private final IPowerManager mPowerManager;
    252     private final INetworkStatsService mNetworkStats;
    253     private final INetworkManagementService mNetworkManager;
    254     private UsageStatsManagerInternal mUsageStats;
    255     private final TrustedTime mTime;
    256     private final UserManager mUserManager;
    257 
    258     private IConnectivityManager mConnManager;
    259     private INotificationManager mNotifManager;
    260     private PowerManagerInternal mPowerManagerInternal;
    261     private IDeviceIdleController mDeviceIdleController;
    262 
    263     final Object mRulesLock = new Object();
    264 
    265     volatile boolean mSystemReady;
    266     volatile boolean mScreenOn;
    267     volatile boolean mRestrictBackground;
    268     volatile boolean mRestrictPower;
    269     volatile boolean mDeviceIdleMode;
    270 
    271     private final boolean mSuppressDefaultPolicy;
    272 
    273     /** Defined network policies. */
    274     final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
    275     /** Currently active network rules for ifaces. */
    276     final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
    277 
    278     /** Defined UID policies. */
    279     final SparseIntArray mUidPolicy = new SparseIntArray();
    280     /** Currently derived rules for each UID. */
    281     final SparseIntArray mUidRules = new SparseIntArray();
    282     /** Set of states for the child firewall chains. True if the chain is active. */
    283     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
    284 
    285     /**
    286      * UIDs that have been white-listed to always be able to have network access
    287      * in power save mode, except device idle (doze) still applies.
    288      * TODO: An int array might be sufficient
    289      */
    290     private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
    291 
    292     /**
    293      * UIDs that have been white-listed to always be able to have network access
    294      * in power save mode.
    295      * TODO: An int array might be sufficient
    296      */
    297     private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
    298 
    299     private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
    300 
    301     /** Set of ifaces that are metered. */
    302     private ArraySet<String> mMeteredIfaces = new ArraySet<>();
    303     /** Set of over-limit templates that have been notified. */
    304     private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
    305 
    306     /** Set of currently active {@link Notification} tags. */
    307     private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
    308 
    309     /** Foreground at UID granularity. */
    310     final SparseIntArray mUidState = new SparseIntArray();
    311 
    312     private final RemoteCallbackList<INetworkPolicyListener>
    313             mListeners = new RemoteCallbackList<>();
    314 
    315     final Handler mHandler;
    316 
    317     private final AtomicFile mPolicyFile;
    318 
    319     private final AppOpsManager mAppOps;
    320 
    321     // TODO: keep whitelist of system-critical services that should never have
    322     // rules enforced, such as system, phone, and radio UIDs.
    323 
    324     // TODO: migrate notifications to SystemUI
    325 
    326     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
    327             IPowerManager powerManager, INetworkStatsService networkStats,
    328             INetworkManagementService networkManagement) {
    329         this(context, activityManager, powerManager, networkStats, networkManagement,
    330                 NtpTrustedTime.getInstance(context), getSystemDir(), false);
    331     }
    332 
    333     private static File getSystemDir() {
    334         return new File(Environment.getDataDirectory(), "system");
    335     }
    336 
    337     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
    338             IPowerManager powerManager, INetworkStatsService networkStats,
    339             INetworkManagementService networkManagement, TrustedTime time, File systemDir,
    340             boolean suppressDefaultPolicy) {
    341         mContext = checkNotNull(context, "missing context");
    342         mActivityManager = checkNotNull(activityManager, "missing activityManager");
    343         mPowerManager = checkNotNull(powerManager, "missing powerManager");
    344         mNetworkStats = checkNotNull(networkStats, "missing networkStats");
    345         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
    346         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
    347                 Context.DEVICE_IDLE_CONTROLLER));
    348         mTime = checkNotNull(time, "missing TrustedTime");
    349         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    350 
    351         HandlerThread thread = new HandlerThread(TAG);
    352         thread.start();
    353         mHandler = new Handler(thread.getLooper(), mHandlerCallback);
    354 
    355         mSuppressDefaultPolicy = suppressDefaultPolicy;
    356 
    357         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
    358 
    359         mAppOps = context.getSystemService(AppOpsManager.class);
    360     }
    361 
    362     public void bindConnectivityManager(IConnectivityManager connManager) {
    363         mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
    364     }
    365 
    366     public void bindNotificationManager(INotificationManager notifManager) {
    367         mNotifManager = checkNotNull(notifManager, "missing INotificationManager");
    368     }
    369 
    370     void updatePowerSaveWhitelistLocked() {
    371         try {
    372             int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
    373             mPowerSaveWhitelistExceptIdleAppIds.clear();
    374             if (whitelist != null) {
    375                 for (int uid : whitelist) {
    376                     mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
    377                 }
    378             }
    379             whitelist = mDeviceIdleController.getAppIdWhitelist();
    380             mPowerSaveWhitelistAppIds.clear();
    381             if (whitelist != null) {
    382                 for (int uid : whitelist) {
    383                     mPowerSaveWhitelistAppIds.put(uid, true);
    384                 }
    385             }
    386         } catch (RemoteException e) {
    387         }
    388     }
    389 
    390     void updatePowerSaveTempWhitelistLocked() {
    391         try {
    392             // Clear the states of the current whitelist
    393             final int N = mPowerSaveTempWhitelistAppIds.size();
    394             for (int i = 0; i < N; i++) {
    395                 mPowerSaveTempWhitelistAppIds.setValueAt(i, false);
    396             }
    397             // Update the states with the new whitelist
    398             final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist();
    399             if (whitelist != null) {
    400                 for (int uid : whitelist) {
    401                     mPowerSaveTempWhitelistAppIds.put(uid, true);
    402                 }
    403             }
    404         } catch (RemoteException e) {
    405         }
    406     }
    407 
    408     /**
    409      * Remove unnecessary entries in the temp whitelist
    410      */
    411     void purgePowerSaveTempWhitelistLocked() {
    412         final int N = mPowerSaveTempWhitelistAppIds.size();
    413         for (int i = N - 1; i >= 0; i--) {
    414             if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) {
    415                 mPowerSaveTempWhitelistAppIds.removeAt(i);
    416             }
    417         }
    418     }
    419 
    420     public void systemReady() {
    421         if (!isBandwidthControlEnabled()) {
    422             Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
    423             return;
    424         }
    425 
    426         mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
    427 
    428         synchronized (mRulesLock) {
    429             updatePowerSaveWhitelistLocked();
    430             mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
    431             mPowerManagerInternal.registerLowPowerModeObserver(
    432                     new PowerManagerInternal.LowPowerModeListener() {
    433                 @Override
    434                 public void onLowPowerModeChanged(boolean enabled) {
    435                     synchronized (mRulesLock) {
    436                         if (mRestrictPower != enabled) {
    437                             mRestrictPower = enabled;
    438                             updateRulesForGlobalChangeLocked(true);
    439                         }
    440                     }
    441                 }
    442             });
    443             mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
    444             mSystemReady = true;
    445 
    446             // read policy from disk
    447             readPolicyLocked();
    448 
    449             if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
    450                 updateRulesForGlobalChangeLocked(false);
    451                 updateNotificationsLocked();
    452             } else {
    453                 // If we are not in any special mode, we just need to make sure the current
    454                 // app idle state is updated.
    455                 updateRulesForAppIdleLocked();
    456             }
    457         }
    458 
    459         updateScreenOn();
    460 
    461         try {
    462             mActivityManager.registerUidObserver(mUidObserver);
    463             mNetworkManager.registerObserver(mAlertObserver);
    464         } catch (RemoteException e) {
    465             // ignored; both services live in system_server
    466         }
    467 
    468         // TODO: traverse existing processes to know foreground state, or have
    469         // activitymanager dispatch current state when new observer attached.
    470 
    471         final IntentFilter screenFilter = new IntentFilter();
    472         screenFilter.addAction(Intent.ACTION_SCREEN_ON);
    473         screenFilter.addAction(Intent.ACTION_SCREEN_OFF);
    474         mContext.registerReceiver(mScreenReceiver, screenFilter);
    475 
    476         // listen for changes to power save whitelist
    477         final IntentFilter whitelistFilter = new IntentFilter(
    478                 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
    479         mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
    480 
    481         DeviceIdleController.LocalService deviceIdleService
    482                 = LocalServices.getService(DeviceIdleController.LocalService.class);
    483         deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
    484 
    485         // watch for network interfaces to be claimed
    486         final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
    487         mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
    488 
    489         // listen for package changes to update policy
    490         final IntentFilter packageFilter = new IntentFilter();
    491         packageFilter.addAction(ACTION_PACKAGE_ADDED);
    492         packageFilter.addDataScheme("package");
    493         mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
    494 
    495         // listen for UID changes to update policy
    496         mContext.registerReceiver(
    497                 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
    498 
    499         // listen for user changes to update policy
    500         final IntentFilter userFilter = new IntentFilter();
    501         userFilter.addAction(ACTION_USER_ADDED);
    502         userFilter.addAction(ACTION_USER_REMOVED);
    503         mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
    504 
    505         // listen for stats update events
    506         final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
    507         mContext.registerReceiver(
    508                 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
    509 
    510         // listen for restrict background changes from notifications
    511         final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
    512         mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
    513 
    514         // listen for snooze warning from notifications
    515         final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING);
    516         mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
    517                 MANAGE_NETWORK_POLICY, mHandler);
    518 
    519         // listen for configured wifi networks to be removed
    520         final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
    521         mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
    522 
    523         // listen for wifi state changes to catch metered hint
    524         final IntentFilter wifiStateFilter = new IntentFilter(
    525                 WifiManager.NETWORK_STATE_CHANGED_ACTION);
    526         mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
    527 
    528         mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
    529 
    530     }
    531 
    532     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
    533         @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
    534             synchronized (mRulesLock) {
    535                 updateUidStateLocked(uid, procState);
    536             }
    537         }
    538 
    539         @Override public void onUidGone(int uid) throws RemoteException {
    540             synchronized (mRulesLock) {
    541                 removeUidStateLocked(uid);
    542             }
    543         }
    544     };
    545 
    546     final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
    547         @Override
    548         public void onReceive(Context context, Intent intent) {
    549             // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
    550             synchronized (mRulesLock) {
    551                 updatePowerSaveWhitelistLocked();
    552                 updateRulesForGlobalChangeLocked(false);
    553             }
    554         }
    555     };
    556 
    557     final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
    558         @Override
    559         public void run() {
    560             synchronized (mRulesLock) {
    561                 updatePowerSaveTempWhitelistLocked();
    562                 updateRulesForTempWhitelistChangeLocked();
    563                 purgePowerSaveTempWhitelistLocked();
    564             }
    565         }
    566     };
    567 
    568     final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
    569         @Override
    570         public void onReceive(Context context, Intent intent) {
    571             // screen-related broadcasts are protected by system, no need
    572             // for permissions check.
    573             mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget();
    574         }
    575     };
    576 
    577     final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
    578         @Override
    579         public void onReceive(Context context, Intent intent) {
    580             // on background handler thread, and PACKAGE_ADDED is protected
    581 
    582             final String action = intent.getAction();
    583             final int uid = intent.getIntExtra(EXTRA_UID, -1);
    584             if (uid == -1) return;
    585 
    586             if (ACTION_PACKAGE_ADDED.equals(action)) {
    587                 // update rules for UID, since it might be subject to
    588                 // global background data policy
    589                 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
    590                 synchronized (mRulesLock) {
    591                     updateRulesForUidLocked(uid);
    592                 }
    593             }
    594         }
    595     };
    596 
    597     final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
    598         @Override
    599         public void onReceive(Context context, Intent intent) {
    600             // on background handler thread, and UID_REMOVED is protected
    601 
    602             final int uid = intent.getIntExtra(EXTRA_UID, -1);
    603             if (uid == -1) return;
    604 
    605             // remove any policy and update rules to clean up
    606             if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
    607             synchronized (mRulesLock) {
    608                 mUidPolicy.delete(uid);
    609                 updateRulesForUidLocked(uid);
    610                 writePolicyLocked();
    611             }
    612         }
    613     };
    614 
    615     final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
    616         @Override
    617         public void onReceive(Context context, Intent intent) {
    618             // on background handler thread, and USER_ADDED and USER_REMOVED
    619             // broadcasts are protected
    620 
    621             final String action = intent.getAction();
    622             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
    623             if (userId == -1) return;
    624 
    625             switch (action) {
    626                 case ACTION_USER_REMOVED:
    627                 case ACTION_USER_ADDED:
    628                     synchronized (mRulesLock) {
    629                         // Remove any policies for given user; both cleaning up after a
    630                         // USER_REMOVED, and one last sanity check during USER_ADDED
    631                         removePoliciesForUserLocked(userId);
    632                         // Update global restrict for new user
    633                         updateRulesForGlobalChangeLocked(true);
    634                     }
    635                     break;
    636             }
    637         }
    638     };
    639 
    640     /**
    641      * Receiver that watches for {@link INetworkStatsService} updates, which we
    642      * use to check against {@link NetworkPolicy#warningBytes}.
    643      */
    644     final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
    645         @Override
    646         public void onReceive(Context context, Intent intent) {
    647             // on background handler thread, and verified
    648             // READ_NETWORK_USAGE_HISTORY permission above.
    649 
    650             maybeRefreshTrustedTime();
    651             synchronized (mRulesLock) {
    652                 updateNetworkEnabledLocked();
    653                 updateNotificationsLocked();
    654             }
    655         }
    656     };
    657 
    658     /**
    659      * Receiver that watches for {@link Notification} control of
    660      * {@link #mRestrictBackground}.
    661      */
    662     final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
    663         @Override
    664         public void onReceive(Context context, Intent intent) {
    665             // on background handler thread, and verified MANAGE_NETWORK_POLICY
    666             // permission above.
    667 
    668             setRestrictBackground(false);
    669         }
    670     };
    671 
    672     /**
    673      * Receiver that watches for {@link Notification} control of
    674      * {@link NetworkPolicy#lastWarningSnooze}.
    675      */
    676     final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
    677         @Override
    678         public void onReceive(Context context, Intent intent) {
    679             // on background handler thread, and verified MANAGE_NETWORK_POLICY
    680             // permission above.
    681 
    682             final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
    683             performSnooze(template, TYPE_WARNING);
    684         }
    685     };
    686 
    687     /**
    688      * Receiver that watches for {@link WifiConfiguration} to be changed.
    689      */
    690     final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
    691         @Override
    692         public void onReceive(Context context, Intent intent) {
    693             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    694             // permission above.
    695 
    696             final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED);
    697             if (reason == CHANGE_REASON_REMOVED) {
    698                 final WifiConfiguration config = intent.getParcelableExtra(
    699                         EXTRA_WIFI_CONFIGURATION);
    700                 if (config.SSID != null) {
    701                     final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID);
    702                     synchronized (mRulesLock) {
    703                         if (mNetworkPolicy.containsKey(template)) {
    704                             mNetworkPolicy.remove(template);
    705                             writePolicyLocked();
    706                         }
    707                     }
    708                 }
    709             }
    710         }
    711     };
    712 
    713     /**
    714      * Receiver that watches {@link WifiInfo} state changes to infer metered
    715      * state. Ignores hints when policy is user-defined.
    716      */
    717     final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
    718         @Override
    719         public void onReceive(Context context, Intent intent) {
    720             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    721             // permission above.
    722 
    723             // ignore when not connected
    724             final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
    725             if (!netInfo.isConnected()) return;
    726 
    727             final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO);
    728             final boolean meteredHint = info.getMeteredHint();
    729 
    730             final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID());
    731             synchronized (mRulesLock) {
    732                 NetworkPolicy policy = mNetworkPolicy.get(template);
    733                 if (policy == null && meteredHint) {
    734                     // policy doesn't exist, and AP is hinting that it's
    735                     // metered: create an inferred policy.
    736                     policy = new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
    737                             WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
    738                             meteredHint, true);
    739                     addNetworkPolicyLocked(policy);
    740 
    741                 } else if (policy != null && policy.inferred) {
    742                     // policy exists, and was inferred: update its current
    743                     // metered state.
    744                     policy.metered = meteredHint;
    745 
    746                     // since this is inferred for each wifi session, just update
    747                     // rules without persisting.
    748                     updateNetworkRulesLocked();
    749                 }
    750             }
    751         }
    752     };
    753 
    754     /**
    755      * Observer that watches for {@link INetworkManagementService} alerts.
    756      */
    757     final private INetworkManagementEventObserver mAlertObserver
    758             = new BaseNetworkObserver() {
    759         @Override
    760         public void limitReached(String limitName, String iface) {
    761             // only someone like NMS should be calling us
    762             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
    763 
    764             if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
    765                 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
    766             }
    767         }
    768     };
    769 
    770     /**
    771      * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
    772      * to show visible notifications as needed.
    773      */
    774     void updateNotificationsLocked() {
    775         if (LOGV) Slog.v(TAG, "updateNotificationsLocked()");
    776 
    777         // keep track of previously active notifications
    778         final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
    779         mActiveNotifs.clear();
    780 
    781         // TODO: when switching to kernel notifications, compute next future
    782         // cycle boundary to recompute notifications.
    783 
    784         // examine stats for each active policy
    785         final long currentTime = currentTimeMillis();
    786         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
    787             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
    788             // ignore policies that aren't relevant to user
    789             if (!isTemplateRelevant(policy.template)) continue;
    790             if (!policy.hasCycle()) continue;
    791 
    792             final long start = computeLastCycleBoundary(currentTime, policy);
    793             final long end = currentTime;
    794             final long totalBytes = getTotalBytes(policy.template, start, end);
    795 
    796             if (policy.isOverLimit(totalBytes)) {
    797                 if (policy.lastLimitSnooze >= start) {
    798                     enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
    799                 } else {
    800                     enqueueNotification(policy, TYPE_LIMIT, totalBytes);
    801                     notifyOverLimitLocked(policy.template);
    802                 }
    803 
    804             } else {
    805                 notifyUnderLimitLocked(policy.template);
    806 
    807                 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
    808                     enqueueNotification(policy, TYPE_WARNING, totalBytes);
    809                 }
    810             }
    811         }
    812 
    813         // ongoing notification when restricting background data
    814         if (mRestrictBackground) {
    815             enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
    816         }
    817 
    818         // cancel stale notifications that we didn't renew above
    819         for (int i = beforeNotifs.size()-1; i >= 0; i--) {
    820             final String tag = beforeNotifs.valueAt(i);
    821             if (!mActiveNotifs.contains(tag)) {
    822                 cancelNotification(tag);
    823             }
    824         }
    825     }
    826 
    827     /**
    828      * Test if given {@link NetworkTemplate} is relevant to user based on
    829      * current device state, such as when
    830      * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
    831      * data connection status.
    832      */
    833     private boolean isTemplateRelevant(NetworkTemplate template) {
    834         if (template.isMatchRuleMobile()) {
    835             final TelephonyManager tele = TelephonyManager.from(mContext);
    836             final SubscriptionManager sub = SubscriptionManager.from(mContext);
    837 
    838             // Mobile template is relevant when any active subscriber matches
    839             final int[] subIds = sub.getActiveSubscriptionIdList();
    840             for (int subId : subIds) {
    841                 final String subscriberId = tele.getSubscriberId(subId);
    842                 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
    843                         TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
    844                 if (template.matches(probeIdent)) {
    845                     return true;
    846                 }
    847             }
    848             return false;
    849         } else {
    850             return true;
    851         }
    852     }
    853 
    854     /**
    855      * Notify that given {@link NetworkTemplate} is over
    856      * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
    857      */
    858     private void notifyOverLimitLocked(NetworkTemplate template) {
    859         if (!mOverLimitNotified.contains(template)) {
    860             mContext.startActivity(buildNetworkOverLimitIntent(template));
    861             mOverLimitNotified.add(template);
    862         }
    863     }
    864 
    865     private void notifyUnderLimitLocked(NetworkTemplate template) {
    866         mOverLimitNotified.remove(template);
    867     }
    868 
    869     /**
    870      * Build unique tag that identifies an active {@link NetworkPolicy}
    871      * notification of a specific type, like {@link #TYPE_LIMIT}.
    872      */
    873     private String buildNotificationTag(NetworkPolicy policy, int type) {
    874         return TAG + ":" + policy.template.hashCode() + ":" + type;
    875     }
    876 
    877     /**
    878      * Show notification for combined {@link NetworkPolicy} and specific type,
    879      * like {@link #TYPE_LIMIT}. Okay to call multiple times.
    880      */
    881     private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
    882         final String tag = buildNotificationTag(policy, type);
    883         final Notification.Builder builder = new Notification.Builder(mContext);
    884         builder.setOnlyAlertOnce(true);
    885         builder.setWhen(0L);
    886         builder.setColor(mContext.getColor(
    887                 com.android.internal.R.color.system_notification_accent_color));
    888 
    889         final Resources res = mContext.getResources();
    890         switch (type) {
    891             case TYPE_WARNING: {
    892                 final CharSequence title = res.getText(R.string.data_usage_warning_title);
    893                 final CharSequence body = res.getString(R.string.data_usage_warning_body);
    894 
    895                 builder.setSmallIcon(R.drawable.stat_notify_error);
    896                 builder.setTicker(title);
    897                 builder.setContentTitle(title);
    898                 builder.setContentText(body);
    899 
    900                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
    901                 builder.setDeleteIntent(PendingIntent.getBroadcast(
    902                         mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
    903 
    904                 final Intent viewIntent = buildViewDataUsageIntent(policy.template);
    905                 builder.setContentIntent(PendingIntent.getActivity(
    906                         mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
    907 
    908                 break;
    909             }
    910             case TYPE_LIMIT: {
    911                 final CharSequence body = res.getText(R.string.data_usage_limit_body);
    912 
    913                 final CharSequence title;
    914                 int icon = R.drawable.stat_notify_disabled_data;
    915                 switch (policy.template.getMatchRule()) {
    916                     case MATCH_MOBILE_3G_LOWER:
    917                         title = res.getText(R.string.data_usage_3g_limit_title);
    918                         break;
    919                     case MATCH_MOBILE_4G:
    920                         title = res.getText(R.string.data_usage_4g_limit_title);
    921                         break;
    922                     case MATCH_MOBILE_ALL:
    923                         title = res.getText(R.string.data_usage_mobile_limit_title);
    924                         break;
    925                     case MATCH_WIFI:
    926                         title = res.getText(R.string.data_usage_wifi_limit_title);
    927                         icon = R.drawable.stat_notify_error;
    928                         break;
    929                     default:
    930                         title = null;
    931                         break;
    932                 }
    933 
    934                 builder.setOngoing(true);
    935                 builder.setSmallIcon(icon);
    936                 builder.setTicker(title);
    937                 builder.setContentTitle(title);
    938                 builder.setContentText(body);
    939 
    940                 final Intent intent = buildNetworkOverLimitIntent(policy.template);
    941                 builder.setContentIntent(PendingIntent.getActivity(
    942                         mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
    943                 break;
    944             }
    945             case TYPE_LIMIT_SNOOZED: {
    946                 final long overBytes = totalBytes - policy.limitBytes;
    947                 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body,
    948                         Formatter.formatFileSize(mContext, overBytes));
    949 
    950                 final CharSequence title;
    951                 switch (policy.template.getMatchRule()) {
    952                     case MATCH_MOBILE_3G_LOWER:
    953                         title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
    954                         break;
    955                     case MATCH_MOBILE_4G:
    956                         title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
    957                         break;
    958                     case MATCH_MOBILE_ALL:
    959                         title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
    960                         break;
    961                     case MATCH_WIFI:
    962                         title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
    963                         break;
    964                     default:
    965                         title = null;
    966                         break;
    967                 }
    968 
    969                 builder.setOngoing(true);
    970                 builder.setSmallIcon(R.drawable.stat_notify_error);
    971                 builder.setTicker(title);
    972                 builder.setContentTitle(title);
    973                 builder.setContentText(body);
    974 
    975                 final Intent intent = buildViewDataUsageIntent(policy.template);
    976                 builder.setContentIntent(PendingIntent.getActivity(
    977                         mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
    978                 break;
    979             }
    980         }
    981 
    982         // TODO: move to NotificationManager once we can mock it
    983         // XXX what to do about multi-user?
    984         try {
    985             final String packageName = mContext.getPackageName();
    986             final int[] idReceived = new int[1];
    987             mNotifManager.enqueueNotificationWithTag(
    988                     packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
    989                     UserHandle.USER_OWNER);
    990             mActiveNotifs.add(tag);
    991         } catch (RemoteException e) {
    992             // ignored; service lives in system_server
    993         }
    994     }
    995 
    996     /**
    997      * Show ongoing notification to reflect that {@link #mRestrictBackground}
    998      * has been enabled.
    999      */
   1000     private void enqueueRestrictedNotification(String tag) {
   1001         final Resources res = mContext.getResources();
   1002         final Notification.Builder builder = new Notification.Builder(mContext);
   1003 
   1004         final CharSequence title = res.getText(R.string.data_usage_restricted_title);
   1005         final CharSequence body = res.getString(R.string.data_usage_restricted_body);
   1006 
   1007         builder.setOnlyAlertOnce(true);
   1008         builder.setOngoing(true);
   1009         builder.setSmallIcon(R.drawable.stat_notify_error);
   1010         builder.setTicker(title);
   1011         builder.setContentTitle(title);
   1012         builder.setContentText(body);
   1013         builder.setColor(mContext.getColor(
   1014                 com.android.internal.R.color.system_notification_accent_color));
   1015 
   1016         final Intent intent = buildAllowBackgroundDataIntent();
   1017         builder.setContentIntent(
   1018                 PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
   1019 
   1020         // TODO: move to NotificationManager once we can mock it
   1021         // XXX what to do about multi-user?
   1022         try {
   1023             final String packageName = mContext.getPackageName();
   1024             final int[] idReceived = new int[1];
   1025             mNotifManager.enqueueNotificationWithTag(packageName, packageName, tag,
   1026                     0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER);
   1027             mActiveNotifs.add(tag);
   1028         } catch (RemoteException e) {
   1029             // ignored; service lives in system_server
   1030         }
   1031     }
   1032 
   1033     private void cancelNotification(String tag) {
   1034         // TODO: move to NotificationManager once we can mock it
   1035         // XXX what to do about multi-user?
   1036         try {
   1037             final String packageName = mContext.getPackageName();
   1038             mNotifManager.cancelNotificationWithTag(
   1039                     packageName, tag, 0x0, UserHandle.USER_OWNER);
   1040         } catch (RemoteException e) {
   1041             // ignored; service lives in system_server
   1042         }
   1043     }
   1044 
   1045     /**
   1046      * Receiver that watches for {@link IConnectivityManager} to claim network
   1047      * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
   1048      */
   1049     private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
   1050         @Override
   1051         public void onReceive(Context context, Intent intent) {
   1052             // on background handler thread, and verified CONNECTIVITY_INTERNAL
   1053             // permission above.
   1054 
   1055             maybeRefreshTrustedTime();
   1056             synchronized (mRulesLock) {
   1057                 ensureActiveMobilePolicyLocked();
   1058                 normalizePoliciesLocked();
   1059                 updateNetworkEnabledLocked();
   1060                 updateNetworkRulesLocked();
   1061                 updateNotificationsLocked();
   1062             }
   1063         }
   1064     };
   1065 
   1066     /**
   1067      * Proactively control network data connections when they exceed
   1068      * {@link NetworkPolicy#limitBytes}.
   1069      */
   1070     void updateNetworkEnabledLocked() {
   1071         if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()");
   1072 
   1073         // TODO: reset any policy-disabled networks when any policy is removed
   1074         // completely, which is currently rare case.
   1075 
   1076         final long currentTime = currentTimeMillis();
   1077         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   1078             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1079             // shortcut when policy has no limit
   1080             if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
   1081                 setNetworkTemplateEnabled(policy.template, true);
   1082                 continue;
   1083             }
   1084 
   1085             final long start = computeLastCycleBoundary(currentTime, policy);
   1086             final long end = currentTime;
   1087             final long totalBytes = getTotalBytes(policy.template, start, end);
   1088 
   1089             // disable data connection when over limit and not snoozed
   1090             final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
   1091                     && policy.lastLimitSnooze < start;
   1092             final boolean networkEnabled = !overLimitWithoutSnooze;
   1093 
   1094             setNetworkTemplateEnabled(policy.template, networkEnabled);
   1095         }
   1096     }
   1097 
   1098     /**
   1099      * Proactively disable networks that match the given
   1100      * {@link NetworkTemplate}.
   1101      */
   1102     private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
   1103         // TODO: reach into ConnectivityManager to proactively disable bringing
   1104         // up this network, since we know that traffic will be blocked.
   1105     }
   1106 
   1107     /**
   1108      * Examine all connected {@link NetworkState}, looking for
   1109      * {@link NetworkPolicy} that need to be enforced. When matches found, set
   1110      * remaining quota based on usage cycle and historical stats.
   1111      */
   1112     void updateNetworkRulesLocked() {
   1113         if (LOGV) Slog.v(TAG, "updateNetworkRulesLocked()");
   1114 
   1115         final NetworkState[] states;
   1116         try {
   1117             states = mConnManager.getAllNetworkState();
   1118         } catch (RemoteException e) {
   1119             // ignored; service lives in system_server
   1120             return;
   1121         }
   1122 
   1123         // If we are in restrict power mode, we want to treat all interfaces
   1124         // as metered, to restrict access to the network by uid.  However, we
   1125         // will not have a bandwidth limit.  Also only do this if restrict
   1126         // background data use is *not* enabled, since that takes precendence
   1127         // use over those networks can have a cost associated with it).
   1128         final boolean powerSave = mRestrictPower && !mRestrictBackground;
   1129 
   1130         // First, generate identities of all connected networks so we can
   1131         // quickly compare them against all defined policies below.
   1132         final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length);
   1133         final ArraySet<String> connIfaces = new ArraySet<String>(states.length);
   1134         for (NetworkState state : states) {
   1135             if (state.networkInfo.isConnected()) {
   1136                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   1137 
   1138                 final String baseIface = state.linkProperties.getInterfaceName();
   1139                 if (baseIface != null) {
   1140                     connIdents.add(Pair.create(baseIface, ident));
   1141                     if (powerSave) {
   1142                         connIfaces.add(baseIface);
   1143                     }
   1144                 }
   1145 
   1146                 // Stacked interfaces are considered to have same identity as
   1147                 // their parent network.
   1148                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
   1149                 for (LinkProperties stackedLink : stackedLinks) {
   1150                     final String stackedIface = stackedLink.getInterfaceName();
   1151                     if (stackedIface != null) {
   1152                         connIdents.add(Pair.create(stackedIface, ident));
   1153                         if (powerSave) {
   1154                             connIfaces.add(stackedIface);
   1155                         }
   1156                     }
   1157                 }
   1158             }
   1159         }
   1160 
   1161         // Apply policies against all connected interfaces found above
   1162         mNetworkRules.clear();
   1163         final ArrayList<String> ifaceList = Lists.newArrayList();
   1164         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
   1165             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1166 
   1167             ifaceList.clear();
   1168             for (int j = connIdents.size() - 1; j >= 0; j--) {
   1169                 final Pair<String, NetworkIdentity> ident = connIdents.get(j);
   1170                 if (policy.template.matches(ident.second)) {
   1171                     ifaceList.add(ident.first);
   1172                 }
   1173             }
   1174 
   1175             if (ifaceList.size() > 0) {
   1176                 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]);
   1177                 mNetworkRules.put(policy, ifaces);
   1178             }
   1179         }
   1180 
   1181         long lowestRule = Long.MAX_VALUE;
   1182         final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length);
   1183 
   1184         // apply each policy that we found ifaces for; compute remaining data
   1185         // based on current cycle and historical stats, and push to kernel.
   1186         final long currentTime = currentTimeMillis();
   1187         for (int i = mNetworkRules.size()-1; i >= 0; i--) {
   1188             final NetworkPolicy policy = mNetworkRules.keyAt(i);
   1189             final String[] ifaces = mNetworkRules.valueAt(i);
   1190 
   1191             final long start;
   1192             final long totalBytes;
   1193             if (policy.hasCycle()) {
   1194                 start = computeLastCycleBoundary(currentTime, policy);
   1195                 totalBytes = getTotalBytes(policy.template, start, currentTime);
   1196             } else {
   1197                 start = Long.MAX_VALUE;
   1198                 totalBytes = 0;
   1199             }
   1200 
   1201             if (LOGD) {
   1202                 Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces "
   1203                         + Arrays.toString(ifaces));
   1204             }
   1205 
   1206             final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
   1207             final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
   1208             if (hasLimit || policy.metered) {
   1209                 final long quotaBytes;
   1210                 if (!hasLimit) {
   1211                     // metered network, but no policy limit; we still need to
   1212                     // restrict apps, so push really high quota.
   1213                     quotaBytes = Long.MAX_VALUE;
   1214                 } else if (policy.lastLimitSnooze >= start) {
   1215                     // snoozing past quota, but we still need to restrict apps,
   1216                     // so push really high quota.
   1217                     quotaBytes = Long.MAX_VALUE;
   1218                 } else {
   1219                     // remaining "quota" bytes are based on total usage in
   1220                     // current cycle. kernel doesn't like 0-byte rules, so we
   1221                     // set 1-byte quota and disable the radio later.
   1222                     quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
   1223                 }
   1224 
   1225                 if (ifaces.length > 1) {
   1226                     // TODO: switch to shared quota once NMS supports
   1227                     Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
   1228                 }
   1229 
   1230                 for (String iface : ifaces) {
   1231                     removeInterfaceQuota(iface);
   1232                     setInterfaceQuota(iface, quotaBytes);
   1233                     newMeteredIfaces.add(iface);
   1234                     if (powerSave) {
   1235                         connIfaces.remove(iface);
   1236                     }
   1237                 }
   1238             }
   1239 
   1240             // keep track of lowest warning or limit of active policies
   1241             if (hasWarning && policy.warningBytes < lowestRule) {
   1242                 lowestRule = policy.warningBytes;
   1243             }
   1244             if (hasLimit && policy.limitBytes < lowestRule) {
   1245                 lowestRule = policy.limitBytes;
   1246             }
   1247         }
   1248 
   1249         for (int i = connIfaces.size()-1; i >= 0; i--) {
   1250             String iface = connIfaces.valueAt(i);
   1251             removeInterfaceQuota(iface);
   1252             setInterfaceQuota(iface, Long.MAX_VALUE);
   1253             newMeteredIfaces.add(iface);
   1254         }
   1255 
   1256         mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
   1257 
   1258         // remove quota on any trailing interfaces
   1259         for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
   1260             final String iface = mMeteredIfaces.valueAt(i);
   1261             if (!newMeteredIfaces.contains(iface)) {
   1262                 removeInterfaceQuota(iface);
   1263             }
   1264         }
   1265         mMeteredIfaces = newMeteredIfaces;
   1266 
   1267         final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
   1268         mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
   1269     }
   1270 
   1271     /**
   1272      * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
   1273      * have at least a default mobile policy defined.
   1274      */
   1275     private void ensureActiveMobilePolicyLocked() {
   1276         if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()");
   1277         if (mSuppressDefaultPolicy) return;
   1278 
   1279         final TelephonyManager tele = TelephonyManager.from(mContext);
   1280         final SubscriptionManager sub = SubscriptionManager.from(mContext);
   1281 
   1282         final int[] subIds = sub.getActiveSubscriptionIdList();
   1283         for (int subId : subIds) {
   1284             final String subscriberId = tele.getSubscriberId(subId);
   1285             ensureActiveMobilePolicyLocked(subscriberId);
   1286         }
   1287     }
   1288 
   1289     private void ensureActiveMobilePolicyLocked(String subscriberId) {
   1290         // Poke around to see if we already have a policy
   1291         final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
   1292                 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
   1293         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
   1294             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
   1295             if (template.matches(probeIdent)) {
   1296                 if (LOGD) {
   1297                     Slog.d(TAG, "Found template " + template + " which matches subscriber "
   1298                             + NetworkIdentity.scrubSubscriberId(subscriberId));
   1299                 }
   1300                 return;
   1301             }
   1302         }
   1303 
   1304         Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
   1305                 + "; generating default policy");
   1306 
   1307         // Build default mobile policy, and assume usage cycle starts today
   1308         final long warningBytes = mContext.getResources().getInteger(
   1309                 com.android.internal.R.integer.config_networkPolicyDefaultWarning) * MB_IN_BYTES;
   1310 
   1311         final Time time = new Time();
   1312         time.setToNow();
   1313 
   1314         final int cycleDay = time.monthDay;
   1315         final String cycleTimezone = time.timezone;
   1316 
   1317         final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
   1318         final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
   1319                 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
   1320         addNetworkPolicyLocked(policy);
   1321     }
   1322 
   1323     private void readPolicyLocked() {
   1324         if (LOGV) Slog.v(TAG, "readPolicyLocked()");
   1325 
   1326         // clear any existing policy and read from disk
   1327         mNetworkPolicy.clear();
   1328         mUidPolicy.clear();
   1329 
   1330         FileInputStream fis = null;
   1331         try {
   1332             fis = mPolicyFile.openRead();
   1333             final XmlPullParser in = Xml.newPullParser();
   1334             in.setInput(fis, StandardCharsets.UTF_8.name());
   1335 
   1336             int type;
   1337             int version = VERSION_INIT;
   1338             while ((type = in.next()) != END_DOCUMENT) {
   1339                 final String tag = in.getName();
   1340                 if (type == START_TAG) {
   1341                     if (TAG_POLICY_LIST.equals(tag)) {
   1342                         version = readIntAttribute(in, ATTR_VERSION);
   1343                         if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
   1344                             mRestrictBackground = readBooleanAttribute(
   1345                                     in, ATTR_RESTRICT_BACKGROUND);
   1346                         } else {
   1347                             mRestrictBackground = false;
   1348                         }
   1349 
   1350                     } else if (TAG_NETWORK_POLICY.equals(tag)) {
   1351                         final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
   1352                         final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
   1353                         final String networkId;
   1354                         if (version >= VERSION_ADDED_NETWORK_ID) {
   1355                             networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
   1356                         } else {
   1357                             networkId = null;
   1358                         }
   1359                         final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
   1360                         final String cycleTimezone;
   1361                         if (version >= VERSION_ADDED_TIMEZONE) {
   1362                             cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
   1363                         } else {
   1364                             cycleTimezone = Time.TIMEZONE_UTC;
   1365                         }
   1366                         final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
   1367                         final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
   1368                         final long lastLimitSnooze;
   1369                         if (version >= VERSION_SPLIT_SNOOZE) {
   1370                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
   1371                         } else if (version >= VERSION_ADDED_SNOOZE) {
   1372                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
   1373                         } else {
   1374                             lastLimitSnooze = SNOOZE_NEVER;
   1375                         }
   1376                         final boolean metered;
   1377                         if (version >= VERSION_ADDED_METERED) {
   1378                             metered = readBooleanAttribute(in, ATTR_METERED);
   1379                         } else {
   1380                             switch (networkTemplate) {
   1381                                 case MATCH_MOBILE_3G_LOWER:
   1382                                 case MATCH_MOBILE_4G:
   1383                                 case MATCH_MOBILE_ALL:
   1384                                     metered = true;
   1385                                     break;
   1386                                 default:
   1387                                     metered = false;
   1388                             }
   1389                         }
   1390                         final long lastWarningSnooze;
   1391                         if (version >= VERSION_SPLIT_SNOOZE) {
   1392                             lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
   1393                         } else {
   1394                             lastWarningSnooze = SNOOZE_NEVER;
   1395                         }
   1396                         final boolean inferred;
   1397                         if (version >= VERSION_ADDED_INFERRED) {
   1398                             inferred = readBooleanAttribute(in, ATTR_INFERRED);
   1399                         } else {
   1400                             inferred = false;
   1401                         }
   1402 
   1403                         final NetworkTemplate template = new NetworkTemplate(networkTemplate,
   1404                                 subscriberId, networkId);
   1405                         mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
   1406                                 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
   1407                                 lastLimitSnooze, metered, inferred));
   1408 
   1409                     } else if (TAG_UID_POLICY.equals(tag)) {
   1410                         final int uid = readIntAttribute(in, ATTR_UID);
   1411                         final int policy = readIntAttribute(in, ATTR_POLICY);
   1412 
   1413                         if (UserHandle.isApp(uid)) {
   1414                             setUidPolicyUncheckedLocked(uid, policy, false);
   1415                         } else {
   1416                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
   1417                         }
   1418                     } else if (TAG_APP_POLICY.equals(tag)) {
   1419                         final int appId = readIntAttribute(in, ATTR_APP_ID);
   1420                         final int policy = readIntAttribute(in, ATTR_POLICY);
   1421 
   1422                         // TODO: set for other users during upgrade
   1423                         final int uid = UserHandle.getUid(UserHandle.USER_OWNER, appId);
   1424                         if (UserHandle.isApp(uid)) {
   1425                             setUidPolicyUncheckedLocked(uid, policy, false);
   1426                         } else {
   1427                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
   1428                         }
   1429                     }
   1430                 }
   1431             }
   1432 
   1433         } catch (FileNotFoundException e) {
   1434             // missing policy is okay, probably first boot
   1435             upgradeLegacyBackgroundData();
   1436         } catch (IOException e) {
   1437             Log.wtf(TAG, "problem reading network policy", e);
   1438         } catch (XmlPullParserException e) {
   1439             Log.wtf(TAG, "problem reading network policy", e);
   1440         } finally {
   1441             IoUtils.closeQuietly(fis);
   1442         }
   1443     }
   1444 
   1445     /**
   1446      * Upgrade legacy background data flags, notifying listeners of one last
   1447      * change to always-true.
   1448      */
   1449     private void upgradeLegacyBackgroundData() {
   1450         mRestrictBackground = Settings.Secure.getInt(
   1451                 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
   1452 
   1453         // kick off one last broadcast if restricted
   1454         if (mRestrictBackground) {
   1455             final Intent broadcast = new Intent(
   1456                     ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
   1457             mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL);
   1458         }
   1459     }
   1460 
   1461     void writePolicyLocked() {
   1462         if (LOGV) Slog.v(TAG, "writePolicyLocked()");
   1463 
   1464         FileOutputStream fos = null;
   1465         try {
   1466             fos = mPolicyFile.startWrite();
   1467 
   1468             XmlSerializer out = new FastXmlSerializer();
   1469             out.setOutput(fos, StandardCharsets.UTF_8.name());
   1470             out.startDocument(null, true);
   1471 
   1472             out.startTag(null, TAG_POLICY_LIST);
   1473             writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
   1474             writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
   1475 
   1476             // write all known network policies
   1477             for (int i = 0; i < mNetworkPolicy.size(); i++) {
   1478                 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1479                 final NetworkTemplate template = policy.template;
   1480 
   1481                 out.startTag(null, TAG_NETWORK_POLICY);
   1482                 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
   1483                 final String subscriberId = template.getSubscriberId();
   1484                 if (subscriberId != null) {
   1485                     out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
   1486                 }
   1487                 final String networkId = template.getNetworkId();
   1488                 if (networkId != null) {
   1489                     out.attribute(null, ATTR_NETWORK_ID, networkId);
   1490                 }
   1491                 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
   1492                 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
   1493                 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
   1494                 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
   1495                 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
   1496                 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
   1497                 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
   1498                 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
   1499                 out.endTag(null, TAG_NETWORK_POLICY);
   1500             }
   1501 
   1502             // write all known uid policies
   1503             for (int i = 0; i < mUidPolicy.size(); i++) {
   1504                 final int uid = mUidPolicy.keyAt(i);
   1505                 final int policy = mUidPolicy.valueAt(i);
   1506 
   1507                 // skip writing empty policies
   1508                 if (policy == POLICY_NONE) continue;
   1509 
   1510                 out.startTag(null, TAG_UID_POLICY);
   1511                 writeIntAttribute(out, ATTR_UID, uid);
   1512                 writeIntAttribute(out, ATTR_POLICY, policy);
   1513                 out.endTag(null, TAG_UID_POLICY);
   1514             }
   1515 
   1516             out.endTag(null, TAG_POLICY_LIST);
   1517             out.endDocument();
   1518 
   1519             mPolicyFile.finishWrite(fos);
   1520         } catch (IOException e) {
   1521             if (fos != null) {
   1522                 mPolicyFile.failWrite(fos);
   1523             }
   1524         }
   1525     }
   1526 
   1527     @Override
   1528     public void setUidPolicy(int uid, int policy) {
   1529         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1530 
   1531         if (!UserHandle.isApp(uid)) {
   1532             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1533         }
   1534 
   1535         synchronized (mRulesLock) {
   1536             final long token = Binder.clearCallingIdentity();
   1537             try {
   1538                 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1539                 if (oldPolicy != policy) {
   1540                     setUidPolicyUncheckedLocked(uid, policy, true);
   1541                 }
   1542             } finally {
   1543                 Binder.restoreCallingIdentity(token);
   1544             }
   1545         }
   1546     }
   1547 
   1548     @Override
   1549     public void addUidPolicy(int uid, int policy) {
   1550         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1551 
   1552         if (!UserHandle.isApp(uid)) {
   1553             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1554         }
   1555 
   1556         synchronized (mRulesLock) {
   1557             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1558             policy |= oldPolicy;
   1559             if (oldPolicy != policy) {
   1560                 setUidPolicyUncheckedLocked(uid, policy, true);
   1561             }
   1562         }
   1563     }
   1564 
   1565     @Override
   1566     public void removeUidPolicy(int uid, int policy) {
   1567         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1568 
   1569         if (!UserHandle.isApp(uid)) {
   1570             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
   1571         }
   1572 
   1573         synchronized (mRulesLock) {
   1574             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
   1575             policy = oldPolicy & ~policy;
   1576             if (oldPolicy != policy) {
   1577                 setUidPolicyUncheckedLocked(uid, policy, true);
   1578             }
   1579         }
   1580     }
   1581 
   1582     private void setUidPolicyUncheckedLocked(int uid, int policy, boolean persist) {
   1583         mUidPolicy.put(uid, policy);
   1584 
   1585         // uid policy changed, recompute rules and persist policy.
   1586         updateRulesForUidLocked(uid);
   1587         if (persist) {
   1588             writePolicyLocked();
   1589         }
   1590     }
   1591 
   1592     @Override
   1593     public int getUidPolicy(int uid) {
   1594         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1595 
   1596         synchronized (mRulesLock) {
   1597             return mUidPolicy.get(uid, POLICY_NONE);
   1598         }
   1599     }
   1600 
   1601     @Override
   1602     public int[] getUidsWithPolicy(int policy) {
   1603         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1604 
   1605         int[] uids = new int[0];
   1606         synchronized (mRulesLock) {
   1607             for (int i = 0; i < mUidPolicy.size(); i++) {
   1608                 final int uid = mUidPolicy.keyAt(i);
   1609                 final int uidPolicy = mUidPolicy.valueAt(i);
   1610                 if (uidPolicy == policy) {
   1611                     uids = appendInt(uids, uid);
   1612                 }
   1613             }
   1614         }
   1615         return uids;
   1616     }
   1617 
   1618     /**
   1619      * Remove any policies associated with given {@link UserHandle}, persisting
   1620      * if any changes are made.
   1621      */
   1622     void removePoliciesForUserLocked(int userId) {
   1623         if (LOGV) Slog.v(TAG, "removePoliciesForUserLocked()");
   1624 
   1625         int[] uids = new int[0];
   1626         for (int i = 0; i < mUidPolicy.size(); i++) {
   1627             final int uid = mUidPolicy.keyAt(i);
   1628             if (UserHandle.getUserId(uid) == userId) {
   1629                 uids = appendInt(uids, uid);
   1630             }
   1631         }
   1632 
   1633         if (uids.length > 0) {
   1634             for (int uid : uids) {
   1635                 mUidPolicy.delete(uid);
   1636                 updateRulesForUidLocked(uid);
   1637             }
   1638             writePolicyLocked();
   1639         }
   1640     }
   1641 
   1642     @Override
   1643     public void registerListener(INetworkPolicyListener listener) {
   1644         // TODO: create permission for observing network policy
   1645         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1646 
   1647         mListeners.register(listener);
   1648 
   1649         // TODO: consider dispatching existing rules to new listeners
   1650     }
   1651 
   1652     @Override
   1653     public void unregisterListener(INetworkPolicyListener listener) {
   1654         // TODO: create permission for observing network policy
   1655         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1656 
   1657         mListeners.unregister(listener);
   1658     }
   1659 
   1660     @Override
   1661     public void setNetworkPolicies(NetworkPolicy[] policies) {
   1662         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1663 
   1664         maybeRefreshTrustedTime();
   1665         synchronized (mRulesLock) {
   1666             normalizePoliciesLocked(policies);
   1667             updateNetworkEnabledLocked();
   1668             updateNetworkRulesLocked();
   1669             updateNotificationsLocked();
   1670             writePolicyLocked();
   1671         }
   1672     }
   1673 
   1674     void addNetworkPolicyLocked(NetworkPolicy policy) {
   1675         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
   1676         policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
   1677         setNetworkPolicies(policies);
   1678     }
   1679 
   1680     @Override
   1681     public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
   1682         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1683         try {
   1684             mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
   1685             // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
   1686             // permission
   1687         } catch (SecurityException e) {
   1688             mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
   1689 
   1690             if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
   1691                     callingPackage) != AppOpsManager.MODE_ALLOWED) {
   1692                 return new NetworkPolicy[0];
   1693             }
   1694         }
   1695 
   1696         synchronized (mRulesLock) {
   1697             final int size = mNetworkPolicy.size();
   1698             final NetworkPolicy[] policies = new NetworkPolicy[size];
   1699             for (int i = 0; i < size; i++) {
   1700                 policies[i] = mNetworkPolicy.valueAt(i);
   1701             }
   1702             return policies;
   1703         }
   1704     }
   1705 
   1706     private void normalizePoliciesLocked() {
   1707         normalizePoliciesLocked(getNetworkPolicies(mContext.getOpPackageName()));
   1708     }
   1709 
   1710     private void normalizePoliciesLocked(NetworkPolicy[] policies) {
   1711         final TelephonyManager tele = TelephonyManager.from(mContext);
   1712         final String[] merged = tele.getMergedSubscriberIds();
   1713 
   1714         mNetworkPolicy.clear();
   1715         for (NetworkPolicy policy : policies) {
   1716             // When two normalized templates conflict, prefer the most
   1717             // restrictive policy
   1718             policy.template = NetworkTemplate.normalize(policy.template, merged);
   1719             final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
   1720             if (existing == null || existing.compareTo(policy) > 0) {
   1721                 if (existing != null) {
   1722                     Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
   1723                 }
   1724                 mNetworkPolicy.put(policy.template, policy);
   1725             }
   1726         }
   1727     }
   1728 
   1729     @Override
   1730     public void snoozeLimit(NetworkTemplate template) {
   1731         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1732 
   1733         final long token = Binder.clearCallingIdentity();
   1734         try {
   1735             performSnooze(template, TYPE_LIMIT);
   1736         } finally {
   1737             Binder.restoreCallingIdentity(token);
   1738         }
   1739     }
   1740 
   1741     void performSnooze(NetworkTemplate template, int type) {
   1742         maybeRefreshTrustedTime();
   1743         final long currentTime = currentTimeMillis();
   1744         synchronized (mRulesLock) {
   1745             // find and snooze local policy that matches
   1746             final NetworkPolicy policy = mNetworkPolicy.get(template);
   1747             if (policy == null) {
   1748                 throw new IllegalArgumentException("unable to find policy for " + template);
   1749             }
   1750 
   1751             switch (type) {
   1752                 case TYPE_WARNING:
   1753                     policy.lastWarningSnooze = currentTime;
   1754                     break;
   1755                 case TYPE_LIMIT:
   1756                     policy.lastLimitSnooze = currentTime;
   1757                     break;
   1758                 default:
   1759                     throw new IllegalArgumentException("unexpected type");
   1760             }
   1761 
   1762             normalizePoliciesLocked();
   1763             updateNetworkEnabledLocked();
   1764             updateNetworkRulesLocked();
   1765             updateNotificationsLocked();
   1766             writePolicyLocked();
   1767         }
   1768     }
   1769 
   1770     @Override
   1771     public void setRestrictBackground(boolean restrictBackground) {
   1772         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1773 
   1774         maybeRefreshTrustedTime();
   1775         synchronized (mRulesLock) {
   1776             mRestrictBackground = restrictBackground;
   1777             updateRulesForGlobalChangeLocked(true);
   1778             updateNotificationsLocked();
   1779             writePolicyLocked();
   1780         }
   1781 
   1782         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
   1783                 .sendToTarget();
   1784     }
   1785 
   1786     @Override
   1787     public boolean getRestrictBackground() {
   1788         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1789 
   1790         synchronized (mRulesLock) {
   1791             return mRestrictBackground;
   1792         }
   1793     }
   1794 
   1795     @Override
   1796     public void setDeviceIdleMode(boolean enabled) {
   1797         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   1798 
   1799         synchronized (mRulesLock) {
   1800             if (mDeviceIdleMode != enabled) {
   1801                 mDeviceIdleMode = enabled;
   1802                 if (mSystemReady) {
   1803                     updateRulesForDeviceIdleLocked();
   1804                 }
   1805                 if (enabled) {
   1806                     EventLogTags.writeDeviceIdleOnPhase("net");
   1807                 } else {
   1808                     EventLogTags.writeDeviceIdleOffPhase("net");
   1809                 }
   1810             }
   1811         }
   1812     }
   1813 
   1814     private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) {
   1815         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   1816             NetworkPolicy policy = mNetworkPolicy.valueAt(i);
   1817             if (policy.template.matches(ident)) {
   1818                 return policy;
   1819             }
   1820         }
   1821         return null;
   1822     }
   1823 
   1824     @Override
   1825     public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
   1826         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
   1827 
   1828         // only returns usage summary, so we don't require caller to have
   1829         // READ_NETWORK_USAGE_HISTORY.
   1830         final long token = Binder.clearCallingIdentity();
   1831         try {
   1832             return getNetworkQuotaInfoUnchecked(state);
   1833         } finally {
   1834             Binder.restoreCallingIdentity(token);
   1835         }
   1836     }
   1837 
   1838     private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
   1839         final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   1840 
   1841         final NetworkPolicy policy;
   1842         synchronized (mRulesLock) {
   1843             policy = findPolicyForNetworkLocked(ident);
   1844         }
   1845 
   1846         if (policy == null || !policy.hasCycle()) {
   1847             // missing policy means we can't derive useful quota info
   1848             return null;
   1849         }
   1850 
   1851         final long currentTime = currentTimeMillis();
   1852 
   1853         // find total bytes used under policy
   1854         final long start = computeLastCycleBoundary(currentTime, policy);
   1855         final long end = currentTime;
   1856         final long totalBytes = getTotalBytes(policy.template, start, end);
   1857 
   1858         // report soft and hard limits under policy
   1859         final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
   1860                 : NetworkQuotaInfo.NO_LIMIT;
   1861         final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
   1862                 : NetworkQuotaInfo.NO_LIMIT;
   1863 
   1864         return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
   1865     }
   1866 
   1867     @Override
   1868     public boolean isNetworkMetered(NetworkState state) {
   1869         final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
   1870 
   1871         // roaming networks are always considered metered
   1872         if (ident.getRoaming()) {
   1873             return true;
   1874         }
   1875 
   1876         final NetworkPolicy policy;
   1877         synchronized (mRulesLock) {
   1878             policy = findPolicyForNetworkLocked(ident);
   1879         }
   1880 
   1881         if (policy != null) {
   1882             return policy.metered;
   1883         } else {
   1884             final int type = state.networkInfo.getType();
   1885             if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) {
   1886                 return true;
   1887             }
   1888             return false;
   1889         }
   1890     }
   1891 
   1892     @Override
   1893     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
   1894         mContext.enforceCallingOrSelfPermission(DUMP, TAG);
   1895 
   1896         final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
   1897 
   1898         final ArraySet<String> argSet = new ArraySet<String>(args.length);
   1899         for (String arg : args) {
   1900             argSet.add(arg);
   1901         }
   1902 
   1903         synchronized (mRulesLock) {
   1904             if (argSet.contains("--unsnooze")) {
   1905                 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
   1906                     mNetworkPolicy.valueAt(i).clearSnooze();
   1907                 }
   1908 
   1909                 normalizePoliciesLocked();
   1910                 updateNetworkEnabledLocked();
   1911                 updateNetworkRulesLocked();
   1912                 updateNotificationsLocked();
   1913                 writePolicyLocked();
   1914 
   1915                 fout.println("Cleared snooze timestamps");
   1916                 return;
   1917             }
   1918 
   1919             fout.print("System ready: "); fout.println(mSystemReady);
   1920             fout.print("Restrict background: "); fout.println(mRestrictBackground);
   1921             fout.print("Restrict power: "); fout.println(mRestrictPower);
   1922             fout.print("Device idle: "); fout.println(mDeviceIdleMode);
   1923             fout.println("Network policies:");
   1924             fout.increaseIndent();
   1925             for (int i = 0; i < mNetworkPolicy.size(); i++) {
   1926                 fout.println(mNetworkPolicy.valueAt(i).toString());
   1927             }
   1928             fout.decreaseIndent();
   1929 
   1930             fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
   1931 
   1932             fout.println("Policy for UIDs:");
   1933             fout.increaseIndent();
   1934             int size = mUidPolicy.size();
   1935             for (int i = 0; i < size; i++) {
   1936                 final int uid = mUidPolicy.keyAt(i);
   1937                 final int policy = mUidPolicy.valueAt(i);
   1938                 fout.print("UID=");
   1939                 fout.print(uid);
   1940                 fout.print(" policy=");
   1941                 dumpPolicy(fout, policy);
   1942                 fout.println();
   1943             }
   1944             fout.decreaseIndent();
   1945 
   1946             size = mPowerSaveWhitelistExceptIdleAppIds.size();
   1947             if (size > 0) {
   1948                 fout.println("Power save whitelist (except idle) app ids:");
   1949                 fout.increaseIndent();
   1950                 for (int i = 0; i < size; i++) {
   1951                     fout.print("UID=");
   1952                     fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
   1953                     fout.print(": ");
   1954                     fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
   1955                     fout.println();
   1956                 }
   1957                 fout.decreaseIndent();
   1958             }
   1959 
   1960             size = mPowerSaveWhitelistAppIds.size();
   1961             if (size > 0) {
   1962                 fout.println("Power save whitelist app ids:");
   1963                 fout.increaseIndent();
   1964                 for (int i = 0; i < size; i++) {
   1965                     fout.print("UID=");
   1966                     fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
   1967                     fout.print(": ");
   1968                     fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
   1969                     fout.println();
   1970                 }
   1971                 fout.decreaseIndent();
   1972             }
   1973 
   1974             final SparseBooleanArray knownUids = new SparseBooleanArray();
   1975             collectKeys(mUidState, knownUids);
   1976             collectKeys(mUidRules, knownUids);
   1977 
   1978             fout.println("Status for known UIDs:");
   1979             fout.increaseIndent();
   1980             size = knownUids.size();
   1981             for (int i = 0; i < size; i++) {
   1982                 final int uid = knownUids.keyAt(i);
   1983                 fout.print("UID=");
   1984                 fout.print(uid);
   1985 
   1986                 int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   1987                 fout.print(" state=");
   1988                 fout.print(state);
   1989                 fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
   1990 
   1991                 fout.print(" rules=");
   1992                 final int rulesIndex = mUidRules.indexOfKey(uid);
   1993                 if (rulesIndex < 0) {
   1994                     fout.print("UNKNOWN");
   1995                 } else {
   1996                     dumpRules(fout, mUidRules.valueAt(rulesIndex));
   1997                 }
   1998 
   1999                 fout.println();
   2000             }
   2001             fout.decreaseIndent();
   2002         }
   2003     }
   2004 
   2005     @Override
   2006     public boolean isUidForeground(int uid) {
   2007         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
   2008 
   2009         synchronized (mRulesLock) {
   2010             return isUidForegroundLocked(uid);
   2011         }
   2012     }
   2013 
   2014     boolean isUidForegroundLocked(int uid) {
   2015         // only really in foreground when screen is also on
   2016         return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
   2017                 <= ActivityManager.PROCESS_STATE_TOP;
   2018     }
   2019 
   2020     /**
   2021      * Process state of UID changed; if needed, will trigger
   2022      * {@link #updateRulesForUidLocked(int)}.
   2023      */
   2024     void updateUidStateLocked(int uid, int uidState) {
   2025         final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2026         if (oldUidState != uidState) {
   2027             // state changed, push updated rules
   2028             mUidState.put(uid, uidState);
   2029             updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
   2030             if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
   2031                     != isProcStateAllowedWhileIdle(uidState)) {
   2032                 updateRulesForDeviceIdleLocked();
   2033             }
   2034         }
   2035     }
   2036 
   2037     void removeUidStateLocked(int uid) {
   2038         final int index = mUidState.indexOfKey(uid);
   2039         if (index >= 0) {
   2040             final int oldUidState = mUidState.valueAt(index);
   2041             mUidState.removeAt(index);
   2042             if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2043                 updateRulesForUidStateChangeLocked(uid, oldUidState,
   2044                         ActivityManager.PROCESS_STATE_CACHED_EMPTY);
   2045                 if (mDeviceIdleMode) {
   2046                     updateRulesForDeviceIdleLocked();
   2047                 }
   2048             }
   2049         }
   2050     }
   2051 
   2052     void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
   2053         final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP;
   2054         final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP;
   2055         if (oldForeground != newForeground) {
   2056             updateRulesForUidLocked(uid);
   2057         }
   2058     }
   2059 
   2060     private void updateScreenOn() {
   2061         synchronized (mRulesLock) {
   2062             try {
   2063                 mScreenOn = mPowerManager.isInteractive();
   2064             } catch (RemoteException e) {
   2065                 // ignored; service lives in system_server
   2066             }
   2067             updateRulesForScreenLocked();
   2068         }
   2069     }
   2070 
   2071     /**
   2072      * Update rules that might be changed by {@link #mScreenOn} value.
   2073      */
   2074     private void updateRulesForScreenLocked() {
   2075         // only update rules for anyone with foreground activities
   2076         final int size = mUidState.size();
   2077         for (int i = 0; i < size; i++) {
   2078             if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) {
   2079                 final int uid = mUidState.keyAt(i);
   2080                 updateRulesForUidLocked(uid);
   2081             }
   2082         }
   2083     }
   2084 
   2085     static boolean isProcStateAllowedWhileIdle(int procState) {
   2086         return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   2087     }
   2088 
   2089     void updateRulesForDeviceIdleLocked() {
   2090         if (mDeviceIdleMode) {
   2091             // sync the whitelists before enable dozable chain.  We don't care about the rules if
   2092             // we are disabling the chain.
   2093             SparseIntArray uidRules = new SparseIntArray();
   2094             final List<UserInfo> users = mUserManager.getUsers();
   2095             for (int ui = users.size() - 1; ui >= 0; ui--) {
   2096                 UserInfo user = users.get(ui);
   2097                 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
   2098                     if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
   2099                         int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
   2100                         int uid = UserHandle.getUid(user.id, appId);
   2101                         uidRules.put(uid, FIREWALL_RULE_ALLOW);
   2102                     }
   2103                 }
   2104                 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
   2105                     int appId = mPowerSaveWhitelistAppIds.keyAt(i);
   2106                     int uid = UserHandle.getUid(user.id, appId);
   2107                     uidRules.put(uid, FIREWALL_RULE_ALLOW);
   2108                 }
   2109             }
   2110             for (int i = mUidState.size() - 1; i >= 0; i--) {
   2111                 if (isProcStateAllowedWhileIdle(mUidState.valueAt(i))) {
   2112                     uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
   2113                 }
   2114             }
   2115             setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
   2116         }
   2117         enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
   2118     }
   2119 
   2120     void updateRuleForDeviceIdleLocked(int uid) {
   2121         if (mDeviceIdleMode) {
   2122             int appId = UserHandle.getAppId(uid);
   2123             if (mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId)
   2124                     || isProcStateAllowedWhileIdle(mUidState.get(uid))) {
   2125                 setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_ALLOW);
   2126             } else {
   2127                 setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
   2128             }
   2129         }
   2130     }
   2131 
   2132     void updateRulesForAppIdleLocked() {
   2133         // Fully update the app idle firewall chain.
   2134         SparseIntArray uidRules = new SparseIntArray();
   2135         final List<UserInfo> users = mUserManager.getUsers();
   2136         for (int ui = users.size() - 1; ui >= 0; ui--) {
   2137             UserInfo user = users.get(ui);
   2138             int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
   2139             for (int uid : idleUids) {
   2140                 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
   2141                     uidRules.put(uid, FIREWALL_RULE_DENY);
   2142                 }
   2143             }
   2144         }
   2145         setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
   2146     }
   2147 
   2148     void updateRuleForAppIdleLocked(int uid) {
   2149         if (!isUidValidForRules(uid)) return;
   2150 
   2151         int appId = UserHandle.getAppId(uid);
   2152         if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)) {
   2153             setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
   2154         } else {
   2155             setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
   2156         }
   2157     }
   2158 
   2159     void updateRulesForAppIdleParoleLocked() {
   2160         boolean enableChain = !mUsageStats.isAppIdleParoleOn();
   2161         enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
   2162     }
   2163 
   2164     /**
   2165      * Update rules that might be changed by {@link #mRestrictBackground},
   2166      * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
   2167      */
   2168     void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) {
   2169         final PackageManager pm = mContext.getPackageManager();
   2170 
   2171         updateRulesForDeviceIdleLocked();
   2172         updateRulesForAppIdleLocked();
   2173 
   2174         // update rules for all installed applications
   2175         final List<UserInfo> users = mUserManager.getUsers();
   2176         final List<ApplicationInfo> apps = pm.getInstalledApplications(
   2177                 PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
   2178 
   2179         for (UserInfo user : users) {
   2180             for (ApplicationInfo app : apps) {
   2181                 final int uid = UserHandle.getUid(user.id, app.uid);
   2182                 updateRulesForUidLocked(uid);
   2183             }
   2184         }
   2185 
   2186         // limit data usage for some internal system services
   2187         updateRulesForUidLocked(android.os.Process.MEDIA_UID);
   2188         updateRulesForUidLocked(android.os.Process.DRM_UID);
   2189 
   2190         // If the set of restricted networks may have changed, re-evaluate those.
   2191         if (restrictedNetworksChanged) {
   2192             normalizePoliciesLocked();
   2193             updateNetworkRulesLocked();
   2194         }
   2195     }
   2196 
   2197     void updateRulesForTempWhitelistChangeLocked() {
   2198         final List<UserInfo> users = mUserManager.getUsers();
   2199         for (UserInfo user : users) {
   2200             for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
   2201                 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
   2202                 int uid = UserHandle.getUid(user.id, appId);
   2203                 updateRuleForAppIdleLocked(uid);
   2204                 updateRuleForDeviceIdleLocked(uid);
   2205             }
   2206         }
   2207     }
   2208 
   2209     private static boolean isUidValidForRules(int uid) {
   2210         // allow rules on specific system services, and any apps
   2211         if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
   2212                 || UserHandle.isApp(uid)) {
   2213             return true;
   2214         }
   2215 
   2216         return false;
   2217     }
   2218 
   2219     private boolean isUidIdle(int uid) {
   2220         final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
   2221         final int userId = UserHandle.getUserId(uid);
   2222 
   2223         for (String packageName : packages) {
   2224             if (!mUsageStats.isAppIdle(packageName, userId)) {
   2225                 return false;
   2226             }
   2227         }
   2228         return true;
   2229     }
   2230 
   2231     /**
   2232      * Applies network rules to bandwidth and firewall controllers based on uid policy.
   2233      * @param uid The uid for which to apply the latest policy
   2234      */
   2235     void updateRulesForUidLocked(int uid) {
   2236         if (!isUidValidForRules(uid)) return;
   2237 
   2238         // quick check: if this uid doesn't have INTERNET permission, it doesn't have
   2239         // network access anyway, so it is a waste to mess with it here.
   2240         final IPackageManager ipm = AppGlobals.getPackageManager();
   2241         try {
   2242             if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid)
   2243                     != PackageManager.PERMISSION_GRANTED) {
   2244                 return;
   2245             }
   2246         } catch (RemoteException e) {
   2247         }
   2248 
   2249         final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
   2250         final boolean uidForeground = isUidForegroundLocked(uid);
   2251 
   2252         // derive active rules based on policy and active state
   2253 
   2254         int appId = UserHandle.getAppId(uid);
   2255         int uidRules = RULE_ALLOW_ALL;
   2256         if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
   2257             // uid in background, and policy says to block metered data
   2258             uidRules = RULE_REJECT_METERED;
   2259         } else if (mRestrictBackground) {
   2260             if (!uidForeground) {
   2261                 // uid in background, and global background disabled
   2262                 uidRules = RULE_REJECT_METERED;
   2263             }
   2264         } else if (mRestrictPower) {
   2265             final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId)
   2266                     || mPowerSaveTempWhitelistAppIds.get(appId);
   2267             if (!whitelisted && !uidForeground
   2268                     && (uidPolicy & POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) == 0) {
   2269                 // uid is in background, restrict power use mode is on (so we want to
   2270                 // restrict all background network access), and this uid is not on the
   2271                 // white list of those allowed background access.
   2272                 uidRules = RULE_REJECT_METERED;
   2273             }
   2274         }
   2275 
   2276         final int oldRules = mUidRules.get(uid);
   2277 
   2278         if (uidRules == RULE_ALLOW_ALL) {
   2279             mUidRules.delete(uid);
   2280         } else {
   2281             mUidRules.put(uid, uidRules);
   2282         }
   2283 
   2284         // Update bandwidth rules if necessary
   2285         final boolean oldRejectMetered = (oldRules & RULE_REJECT_METERED) != 0;
   2286         final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
   2287         if (oldRejectMetered != rejectMetered) {
   2288             setUidNetworkRules(uid, rejectMetered);
   2289         }
   2290 
   2291         // dispatch changed rule to existing listeners
   2292         if (oldRules != uidRules) {
   2293             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
   2294         }
   2295 
   2296         try {
   2297             // adjust stats accounting based on foreground status
   2298             mNetworkStats.setUidForeground(uid, uidForeground);
   2299         } catch (RemoteException e) {
   2300             // ignored; service lives in system_server
   2301         }
   2302     }
   2303 
   2304     private class AppIdleStateChangeListener
   2305             extends UsageStatsManagerInternal.AppIdleStateChangeListener {
   2306 
   2307         @Override
   2308         public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
   2309             try {
   2310                 int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
   2311                 synchronized (mRulesLock) {
   2312                     updateRuleForAppIdleLocked(uid);
   2313                 }
   2314             } catch (NameNotFoundException nnfe) {
   2315             }
   2316         }
   2317 
   2318         @Override
   2319         public void onParoleStateChanged(boolean isParoleOn) {
   2320             synchronized (mRulesLock) {
   2321                 updateRulesForAppIdleParoleLocked();
   2322             }
   2323         }
   2324     }
   2325 
   2326     private Handler.Callback mHandlerCallback = new Handler.Callback() {
   2327         @Override
   2328         public boolean handleMessage(Message msg) {
   2329             switch (msg.what) {
   2330                 case MSG_RULES_CHANGED: {
   2331                     final int uid = msg.arg1;
   2332                     final int uidRules = msg.arg2;
   2333                     final int length = mListeners.beginBroadcast();
   2334                     for (int i = 0; i < length; i++) {
   2335                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   2336                         if (listener != null) {
   2337                             try {
   2338                                 listener.onUidRulesChanged(uid, uidRules);
   2339                             } catch (RemoteException e) {
   2340                             }
   2341                         }
   2342                     }
   2343                     mListeners.finishBroadcast();
   2344                     return true;
   2345                 }
   2346                 case MSG_METERED_IFACES_CHANGED: {
   2347                     final String[] meteredIfaces = (String[]) msg.obj;
   2348                     final int length = mListeners.beginBroadcast();
   2349                     for (int i = 0; i < length; i++) {
   2350                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   2351                         if (listener != null) {
   2352                             try {
   2353                                 listener.onMeteredIfacesChanged(meteredIfaces);
   2354                             } catch (RemoteException e) {
   2355                             }
   2356                         }
   2357                     }
   2358                     mListeners.finishBroadcast();
   2359                     return true;
   2360                 }
   2361                 case MSG_LIMIT_REACHED: {
   2362                     final String iface = (String) msg.obj;
   2363 
   2364                     maybeRefreshTrustedTime();
   2365                     synchronized (mRulesLock) {
   2366                         if (mMeteredIfaces.contains(iface)) {
   2367                             try {
   2368                                 // force stats update to make sure we have
   2369                                 // numbers that caused alert to trigger.
   2370                                 mNetworkStats.forceUpdate();
   2371                             } catch (RemoteException e) {
   2372                                 // ignored; service lives in system_server
   2373                             }
   2374 
   2375                             updateNetworkEnabledLocked();
   2376                             updateNotificationsLocked();
   2377                         }
   2378                     }
   2379                     return true;
   2380                 }
   2381                 case MSG_RESTRICT_BACKGROUND_CHANGED: {
   2382                     final boolean restrictBackground = msg.arg1 != 0;
   2383                     final int length = mListeners.beginBroadcast();
   2384                     for (int i = 0; i < length; i++) {
   2385                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
   2386                         if (listener != null) {
   2387                             try {
   2388                                 listener.onRestrictBackgroundChanged(restrictBackground);
   2389                             } catch (RemoteException e) {
   2390                             }
   2391                         }
   2392                     }
   2393                     mListeners.finishBroadcast();
   2394                     return true;
   2395                 }
   2396                 case MSG_ADVISE_PERSIST_THRESHOLD: {
   2397                     final long lowestRule = (Long) msg.obj;
   2398                     try {
   2399                         // make sure stats are recorded frequently enough; we aim
   2400                         // for 2MB threshold for 2GB/month rules.
   2401                         final long persistThreshold = lowestRule / 1000;
   2402                         mNetworkStats.advisePersistThreshold(persistThreshold);
   2403                     } catch (RemoteException e) {
   2404                         // ignored; service lives in system_server
   2405                     }
   2406                     return true;
   2407                 }
   2408                 case MSG_SCREEN_ON_CHANGED: {
   2409                     updateScreenOn();
   2410                     return true;
   2411                 }
   2412                 default: {
   2413                     return false;
   2414                 }
   2415             }
   2416         }
   2417     };
   2418 
   2419     private void setInterfaceQuota(String iface, long quotaBytes) {
   2420         try {
   2421             mNetworkManager.setInterfaceQuota(iface, quotaBytes);
   2422         } catch (IllegalStateException e) {
   2423             Log.wtf(TAG, "problem setting interface quota", e);
   2424         } catch (RemoteException e) {
   2425             // ignored; service lives in system_server
   2426         }
   2427     }
   2428 
   2429     private void removeInterfaceQuota(String iface) {
   2430         try {
   2431             mNetworkManager.removeInterfaceQuota(iface);
   2432         } catch (IllegalStateException e) {
   2433             Log.wtf(TAG, "problem removing interface quota", e);
   2434         } catch (RemoteException e) {
   2435             // ignored; service lives in system_server
   2436         }
   2437     }
   2438 
   2439     private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
   2440         try {
   2441             mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
   2442         } catch (IllegalStateException e) {
   2443             Log.wtf(TAG, "problem setting uid rules", e);
   2444         } catch (RemoteException e) {
   2445             // ignored; service lives in system_server
   2446         }
   2447     }
   2448 
   2449     /**
   2450      * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
   2451      * here to netd.  It will clean up dead rules and make sure the target chain only contains rules
   2452      * specified here.
   2453      */
   2454     private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
   2455         try {
   2456             int size = uidRules.size();
   2457             int[] uids = new int[size];
   2458             int[] rules = new int[size];
   2459             for(int index = size - 1; index >= 0; --index) {
   2460                 uids[index] = uidRules.keyAt(index);
   2461                 rules[index] = uidRules.valueAt(index);
   2462             }
   2463             mNetworkManager.setFirewallUidRules(chain, uids, rules);
   2464         } catch (IllegalStateException e) {
   2465             Log.wtf(TAG, "problem setting firewall uid rules", e);
   2466         } catch (RemoteException e) {
   2467             // ignored; service lives in system_server
   2468         }
   2469     }
   2470 
   2471     /**
   2472      * Add or remove a uid to the firewall blacklist for all network ifaces.
   2473      */
   2474     private void setUidFirewallRule(int chain, int uid, int rule) {
   2475         try {
   2476             mNetworkManager.setFirewallUidRule(chain, uid, rule);
   2477         } catch (IllegalStateException e) {
   2478             Log.wtf(TAG, "problem setting firewall uid rules", e);
   2479         } catch (RemoteException e) {
   2480             // ignored; service lives in system_server
   2481         }
   2482     }
   2483 
   2484     /**
   2485      * Add or remove a uid to the firewall blacklist for all network ifaces.
   2486      */
   2487     private void enableFirewallChainLocked(int chain, boolean enable) {
   2488         if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
   2489                 mFirewallChainStates.get(chain) == enable) {
   2490             // All is the same, nothing to do.
   2491             return;
   2492         }
   2493         mFirewallChainStates.put(chain, enable);
   2494         try {
   2495             mNetworkManager.setFirewallChainEnabled(chain, enable);
   2496         } catch (IllegalStateException e) {
   2497             Log.wtf(TAG, "problem enable firewall chain", e);
   2498         } catch (RemoteException e) {
   2499             // ignored; service lives in system_server
   2500         }
   2501     }
   2502 
   2503     private long getTotalBytes(NetworkTemplate template, long start, long end) {
   2504         try {
   2505             return mNetworkStats.getNetworkTotalBytes(template, start, end);
   2506         } catch (RuntimeException e) {
   2507             Slog.w(TAG, "problem reading network stats: " + e);
   2508             return 0;
   2509         } catch (RemoteException e) {
   2510             // ignored; service lives in system_server
   2511             return 0;
   2512         }
   2513     }
   2514 
   2515     private boolean isBandwidthControlEnabled() {
   2516         final long token = Binder.clearCallingIdentity();
   2517         try {
   2518             return mNetworkManager.isBandwidthControlEnabled();
   2519         } catch (RemoteException e) {
   2520             // ignored; service lives in system_server
   2521             return false;
   2522         } finally {
   2523             Binder.restoreCallingIdentity(token);
   2524         }
   2525     }
   2526 
   2527     /**
   2528      * Try refreshing {@link #mTime} when stale.
   2529      */
   2530     void maybeRefreshTrustedTime() {
   2531         if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
   2532             mTime.forceRefresh();
   2533         }
   2534     }
   2535 
   2536     private long currentTimeMillis() {
   2537         return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
   2538     }
   2539 
   2540     private static Intent buildAllowBackgroundDataIntent() {
   2541         return new Intent(ACTION_ALLOW_BACKGROUND);
   2542     }
   2543 
   2544     private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
   2545         final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
   2546         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   2547         return intent;
   2548     }
   2549 
   2550     private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
   2551         final Intent intent = new Intent();
   2552         intent.setComponent(new ComponentName(
   2553                 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity"));
   2554         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2555         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   2556         return intent;
   2557     }
   2558 
   2559     private static Intent buildViewDataUsageIntent(NetworkTemplate template) {
   2560         final Intent intent = new Intent();
   2561         intent.setComponent(new ComponentName(
   2562                 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
   2563         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2564         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
   2565         return intent;
   2566     }
   2567 
   2568     @VisibleForTesting
   2569     public void addIdleHandler(IdleHandler handler) {
   2570         mHandler.getLooper().getQueue().addIdleHandler(handler);
   2571     }
   2572 
   2573     private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
   2574         final int size = source.size();
   2575         for (int i = 0; i < size; i++) {
   2576             target.put(source.keyAt(i), true);
   2577         }
   2578     }
   2579 
   2580     @Override
   2581     public void factoryReset(String subscriber) {
   2582         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   2583 
   2584         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
   2585             return;
   2586         }
   2587 
   2588         // Turn mobile data limit off
   2589         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
   2590         NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
   2591         for (NetworkPolicy policy : policies) {
   2592             if (policy.template.equals(template)) {
   2593                 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
   2594                 policy.inferred = false;
   2595                 policy.clearSnooze();
   2596             }
   2597         }
   2598         setNetworkPolicies(policies);
   2599 
   2600         // Turn restrict background data off
   2601         setRestrictBackground(false);
   2602 
   2603         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
   2604             // Remove app's "restrict background data" flag
   2605             for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
   2606                 setUidPolicy(uid, POLICY_NONE);
   2607             }
   2608         }
   2609     }
   2610 }
   2611