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
17package com.android.server.net;
18
19import static android.Manifest.permission.ACCESS_NETWORK_STATE;
20import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
21import static android.Manifest.permission.DUMP;
22import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
23import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
24import static android.Manifest.permission.READ_PHONE_STATE;
25import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
26import static android.content.Intent.ACTION_PACKAGE_ADDED;
27import static android.content.Intent.ACTION_UID_REMOVED;
28import static android.content.Intent.ACTION_USER_ADDED;
29import static android.content.Intent.ACTION_USER_REMOVED;
30import static android.content.Intent.EXTRA_UID;
31import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
32import static android.net.ConnectivityManager.TYPE_MOBILE;
33import static android.net.ConnectivityManager.TYPE_WIMAX;
34import static android.net.ConnectivityManager.isNetworkTypeMobile;
35import static android.net.NetworkPolicy.CYCLE_NONE;
36import static android.net.NetworkPolicy.LIMIT_DISABLED;
37import static android.net.NetworkPolicy.SNOOZE_NEVER;
38import static android.net.NetworkPolicy.WARNING_DISABLED;
39import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
40import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
41import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
42import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
43import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
44import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
45import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
46import static android.net.NetworkPolicyManager.POLICY_NONE;
47import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
48import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
49import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
50import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
51import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
52import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
53import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
54import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
55import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
56import static android.net.NetworkTemplate.MATCH_WIFI;
57import static android.net.NetworkTemplate.buildTemplateMobileAll;
58import static android.net.TrafficStats.MB_IN_BYTES;
59import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
60import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
61import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
62import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
63import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
64import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
65import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
66import static android.text.format.DateUtils.DAY_IN_MILLIS;
67import static com.android.internal.util.ArrayUtils.appendInt;
68import static com.android.internal.util.Preconditions.checkNotNull;
69import static com.android.internal.util.XmlUtils.readBooleanAttribute;
70import static com.android.internal.util.XmlUtils.readIntAttribute;
71import static com.android.internal.util.XmlUtils.readLongAttribute;
72import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
73import static com.android.internal.util.XmlUtils.writeIntAttribute;
74import static com.android.internal.util.XmlUtils.writeLongAttribute;
75import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
76import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
77import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
78import static org.xmlpull.v1.XmlPullParser.START_TAG;
79
80import android.Manifest;
81import android.app.ActivityManager;
82import android.app.AppGlobals;
83import android.app.AppOpsManager;
84import android.app.IActivityManager;
85import android.app.INotificationManager;
86import android.app.IUidObserver;
87import android.app.Notification;
88import android.app.PendingIntent;
89import android.app.usage.UsageStatsManagerInternal;
90import android.content.BroadcastReceiver;
91import android.content.ComponentName;
92import android.content.Context;
93import android.content.Intent;
94import android.content.IntentFilter;
95import android.content.pm.ApplicationInfo;
96import android.content.pm.IPackageManager;
97import android.content.pm.PackageManager;
98import android.content.pm.PackageManager.NameNotFoundException;
99import android.content.pm.UserInfo;
100import android.content.res.Resources;
101import android.net.ConnectivityManager;
102import android.net.IConnectivityManager;
103import android.net.INetworkManagementEventObserver;
104import android.net.INetworkPolicyListener;
105import android.net.INetworkPolicyManager;
106import android.net.INetworkStatsService;
107import android.net.LinkProperties;
108import android.net.NetworkIdentity;
109import android.net.NetworkInfo;
110import android.net.NetworkPolicy;
111import android.net.NetworkPolicyManager;
112import android.net.NetworkQuotaInfo;
113import android.net.NetworkState;
114import android.net.NetworkTemplate;
115import android.net.wifi.WifiConfiguration;
116import android.net.wifi.WifiInfo;
117import android.net.wifi.WifiManager;
118import android.os.Binder;
119import android.os.Environment;
120import android.os.Handler;
121import android.os.HandlerThread;
122import android.os.IDeviceIdleController;
123import android.os.INetworkManagementService;
124import android.os.IPowerManager;
125import android.os.Message;
126import android.os.MessageQueue.IdleHandler;
127import android.os.PowerManager;
128import android.os.PowerManagerInternal;
129import android.os.RemoteCallbackList;
130import android.os.RemoteException;
131import android.os.ServiceManager;
132import android.os.UserHandle;
133import android.os.UserManager;
134import android.provider.Settings;
135import android.telephony.SubscriptionManager;
136import android.telephony.TelephonyManager;
137import android.text.format.Formatter;
138import android.text.format.Time;
139import android.util.ArrayMap;
140import android.util.ArraySet;
141import android.util.AtomicFile;
142import android.util.DebugUtils;
143import android.util.Log;
144import android.util.NtpTrustedTime;
145import android.util.Pair;
146import android.util.Slog;
147import android.util.SparseBooleanArray;
148import android.util.SparseIntArray;
149import android.util.TrustedTime;
150import android.util.Xml;
151
152import libcore.io.IoUtils;
153
154import com.android.internal.R;
155import com.android.internal.annotations.VisibleForTesting;
156import com.android.internal.util.ArrayUtils;
157import com.android.internal.util.FastXmlSerializer;
158import com.android.internal.util.IndentingPrintWriter;
159import com.android.server.DeviceIdleController;
160import com.android.server.EventLogTags;
161import com.android.server.LocalServices;
162import com.google.android.collect.Lists;
163
164import org.xmlpull.v1.XmlPullParser;
165import org.xmlpull.v1.XmlPullParserException;
166import org.xmlpull.v1.XmlSerializer;
167
168import java.io.File;
169import java.io.FileDescriptor;
170import java.io.FileInputStream;
171import java.io.FileNotFoundException;
172import java.io.FileOutputStream;
173import java.io.IOException;
174import java.io.PrintWriter;
175import java.nio.charset.StandardCharsets;
176import java.util.ArrayList;
177import java.util.Arrays;
178import java.util.List;
179
180/**
181 * Service that maintains low-level network policy rules, using
182 * {@link NetworkStatsService} statistics to drive those rules.
183 * <p>
184 * Derives active rules by combining a given policy with other system status,
185 * and delivers to listeners, such as {@link ConnectivityManager}, for
186 * enforcement.
187 */
188public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
189    private static final String TAG = "NetworkPolicy";
190    private static final boolean LOGD = false;
191    private static final boolean LOGV = false;
192
193    private static final int VERSION_INIT = 1;
194    private static final int VERSION_ADDED_SNOOZE = 2;
195    private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
196    private static final int VERSION_ADDED_METERED = 4;
197    private static final int VERSION_SPLIT_SNOOZE = 5;
198    private static final int VERSION_ADDED_TIMEZONE = 6;
199    private static final int VERSION_ADDED_INFERRED = 7;
200    private static final int VERSION_SWITCH_APP_ID = 8;
201    private static final int VERSION_ADDED_NETWORK_ID = 9;
202    private static final int VERSION_SWITCH_UID = 10;
203    private static final int VERSION_LATEST = VERSION_SWITCH_UID;
204
205    @VisibleForTesting
206    public static final int TYPE_WARNING = 0x1;
207    @VisibleForTesting
208    public static final int TYPE_LIMIT = 0x2;
209    @VisibleForTesting
210    public static final int TYPE_LIMIT_SNOOZED = 0x3;
211
212    private static final String TAG_POLICY_LIST = "policy-list";
213    private static final String TAG_NETWORK_POLICY = "network-policy";
214    private static final String TAG_UID_POLICY = "uid-policy";
215    private static final String TAG_APP_POLICY = "app-policy";
216
217    private static final String ATTR_VERSION = "version";
218    private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
219    private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
220    private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
221    private static final String ATTR_NETWORK_ID = "networkId";
222    private static final String ATTR_CYCLE_DAY = "cycleDay";
223    private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
224    private static final String ATTR_WARNING_BYTES = "warningBytes";
225    private static final String ATTR_LIMIT_BYTES = "limitBytes";
226    private static final String ATTR_LAST_SNOOZE = "lastSnooze";
227    private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
228    private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
229    private static final String ATTR_METERED = "metered";
230    private static final String ATTR_INFERRED = "inferred";
231    private static final String ATTR_UID = "uid";
232    private static final String ATTR_APP_ID = "appId";
233    private static final String ATTR_POLICY = "policy";
234
235    private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground";
236
237    private static final String ACTION_ALLOW_BACKGROUND =
238            "com.android.server.net.action.ALLOW_BACKGROUND";
239    private static final String ACTION_SNOOZE_WARNING =
240            "com.android.server.net.action.SNOOZE_WARNING";
241
242    private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
243
244    private static final int MSG_RULES_CHANGED = 1;
245    private static final int MSG_METERED_IFACES_CHANGED = 2;
246    private static final int MSG_LIMIT_REACHED = 5;
247    private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
248    private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
249    private static final int MSG_SCREEN_ON_CHANGED = 8;
250
251    private final Context mContext;
252    private final IActivityManager mActivityManager;
253    private final IPowerManager mPowerManager;
254    private final INetworkStatsService mNetworkStats;
255    private final INetworkManagementService mNetworkManager;
256    private UsageStatsManagerInternal mUsageStats;
257    private final TrustedTime mTime;
258    private final UserManager mUserManager;
259
260    private IConnectivityManager mConnManager;
261    private INotificationManager mNotifManager;
262    private PowerManagerInternal mPowerManagerInternal;
263    private IDeviceIdleController mDeviceIdleController;
264
265    final Object mRulesLock = new Object();
266
267    volatile boolean mSystemReady;
268    volatile boolean mScreenOn;
269    volatile boolean mRestrictBackground;
270    volatile boolean mRestrictPower;
271    volatile boolean mDeviceIdleMode;
272
273    private final boolean mSuppressDefaultPolicy;
274
275    /** Defined network policies. */
276    final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
277    /** Currently active network rules for ifaces. */
278    final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
279
280    /** Defined UID policies. */
281    final SparseIntArray mUidPolicy = new SparseIntArray();
282    /** Currently derived rules for each UID. */
283    final SparseIntArray mUidRules = new SparseIntArray();
284
285    final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
286    final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
287
288    /** Set of states for the child firewall chains. True if the chain is active. */
289    final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
290
291    /**
292     * UIDs that have been white-listed to always be able to have network access
293     * in power save mode, except device idle (doze) still applies.
294     * TODO: An int array might be sufficient
295     */
296    private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
297
298    /**
299     * UIDs that have been white-listed to always be able to have network access
300     * in power save mode.
301     * TODO: An int array might be sufficient
302     */
303    private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
304
305    private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
306
307    /** Set of ifaces that are metered. */
308    private ArraySet<String> mMeteredIfaces = new ArraySet<>();
309    /** Set of over-limit templates that have been notified. */
310    private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
311
312    /** Set of currently active {@link Notification} tags. */
313    private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
314
315    /** Foreground at UID granularity. */
316    final SparseIntArray mUidState = new SparseIntArray();
317
318    private final RemoteCallbackList<INetworkPolicyListener>
319            mListeners = new RemoteCallbackList<>();
320
321    final Handler mHandler;
322
323    private final AtomicFile mPolicyFile;
324
325    private final AppOpsManager mAppOps;
326
327    // TODO: keep whitelist of system-critical services that should never have
328    // rules enforced, such as system, phone, and radio UIDs.
329
330    // TODO: migrate notifications to SystemUI
331
332    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
333            IPowerManager powerManager, INetworkStatsService networkStats,
334            INetworkManagementService networkManagement) {
335        this(context, activityManager, powerManager, networkStats, networkManagement,
336                NtpTrustedTime.getInstance(context), getSystemDir(), false);
337    }
338
339    private static File getSystemDir() {
340        return new File(Environment.getDataDirectory(), "system");
341    }
342
343    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
344            IPowerManager powerManager, INetworkStatsService networkStats,
345            INetworkManagementService networkManagement, TrustedTime time, File systemDir,
346            boolean suppressDefaultPolicy) {
347        mContext = checkNotNull(context, "missing context");
348        mActivityManager = checkNotNull(activityManager, "missing activityManager");
349        mPowerManager = checkNotNull(powerManager, "missing powerManager");
350        mNetworkStats = checkNotNull(networkStats, "missing networkStats");
351        mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
352        mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
353                Context.DEVICE_IDLE_CONTROLLER));
354        mTime = checkNotNull(time, "missing TrustedTime");
355        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
356
357        HandlerThread thread = new HandlerThread(TAG);
358        thread.start();
359        mHandler = new Handler(thread.getLooper(), mHandlerCallback);
360
361        mSuppressDefaultPolicy = suppressDefaultPolicy;
362
363        mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
364
365        mAppOps = context.getSystemService(AppOpsManager.class);
366    }
367
368    public void bindConnectivityManager(IConnectivityManager connManager) {
369        mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
370    }
371
372    public void bindNotificationManager(INotificationManager notifManager) {
373        mNotifManager = checkNotNull(notifManager, "missing INotificationManager");
374    }
375
376    void updatePowerSaveWhitelistLocked() {
377        try {
378            int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
379            mPowerSaveWhitelistExceptIdleAppIds.clear();
380            if (whitelist != null) {
381                for (int uid : whitelist) {
382                    mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
383                }
384            }
385            whitelist = mDeviceIdleController.getAppIdWhitelist();
386            mPowerSaveWhitelistAppIds.clear();
387            if (whitelist != null) {
388                for (int uid : whitelist) {
389                    mPowerSaveWhitelistAppIds.put(uid, true);
390                }
391            }
392        } catch (RemoteException e) {
393        }
394    }
395
396    void updatePowerSaveTempWhitelistLocked() {
397        try {
398            // Clear the states of the current whitelist
399            final int N = mPowerSaveTempWhitelistAppIds.size();
400            for (int i = 0; i < N; i++) {
401                mPowerSaveTempWhitelistAppIds.setValueAt(i, false);
402            }
403            // Update the states with the new whitelist
404            final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist();
405            if (whitelist != null) {
406                for (int uid : whitelist) {
407                    mPowerSaveTempWhitelistAppIds.put(uid, true);
408                }
409            }
410        } catch (RemoteException e) {
411        }
412    }
413
414    /**
415     * Remove unnecessary entries in the temp whitelist
416     */
417    void purgePowerSaveTempWhitelistLocked() {
418        final int N = mPowerSaveTempWhitelistAppIds.size();
419        for (int i = N - 1; i >= 0; i--) {
420            if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) {
421                mPowerSaveTempWhitelistAppIds.removeAt(i);
422            }
423        }
424    }
425
426    public void systemReady() {
427        if (!isBandwidthControlEnabled()) {
428            Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
429            return;
430        }
431
432        mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
433
434        synchronized (mRulesLock) {
435            updatePowerSaveWhitelistLocked();
436            mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
437            mPowerManagerInternal.registerLowPowerModeObserver(
438                    new PowerManagerInternal.LowPowerModeListener() {
439                @Override
440                public void onLowPowerModeChanged(boolean enabled) {
441                    synchronized (mRulesLock) {
442                        if (mRestrictPower != enabled) {
443                            mRestrictPower = enabled;
444                            updateRulesForGlobalChangeLocked(true);
445                        }
446                    }
447                }
448            });
449            mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
450            mSystemReady = true;
451
452            // read policy from disk
453            readPolicyLocked();
454
455            updateRulesForGlobalChangeLocked(false);
456            updateNotificationsLocked();
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                    // Device idle change means we need to rebuild rules for all
1804                    // known apps, so do a global refresh.
1805                    updateRulesForGlobalChangeLocked(false);
1806                }
1807                if (enabled) {
1808                    EventLogTags.writeDeviceIdleOnPhase("net");
1809                } else {
1810                    EventLogTags.writeDeviceIdleOffPhase("net");
1811                }
1812            }
1813        }
1814    }
1815
1816    private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) {
1817        for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1818            NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1819            if (policy.template.matches(ident)) {
1820                return policy;
1821            }
1822        }
1823        return null;
1824    }
1825
1826    @Override
1827    public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
1828        mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
1829
1830        // only returns usage summary, so we don't require caller to have
1831        // READ_NETWORK_USAGE_HISTORY.
1832        final long token = Binder.clearCallingIdentity();
1833        try {
1834            return getNetworkQuotaInfoUnchecked(state);
1835        } finally {
1836            Binder.restoreCallingIdentity(token);
1837        }
1838    }
1839
1840    private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
1841        final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
1842
1843        final NetworkPolicy policy;
1844        synchronized (mRulesLock) {
1845            policy = findPolicyForNetworkLocked(ident);
1846        }
1847
1848        if (policy == null || !policy.hasCycle()) {
1849            // missing policy means we can't derive useful quota info
1850            return null;
1851        }
1852
1853        final long currentTime = currentTimeMillis();
1854
1855        // find total bytes used under policy
1856        final long start = computeLastCycleBoundary(currentTime, policy);
1857        final long end = currentTime;
1858        final long totalBytes = getTotalBytes(policy.template, start, end);
1859
1860        // report soft and hard limits under policy
1861        final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
1862                : NetworkQuotaInfo.NO_LIMIT;
1863        final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
1864                : NetworkQuotaInfo.NO_LIMIT;
1865
1866        return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
1867    }
1868
1869    @Override
1870    public boolean isNetworkMetered(NetworkState state) {
1871        final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
1872
1873        // roaming networks are always considered metered
1874        if (ident.getRoaming()) {
1875            return true;
1876        }
1877
1878        final NetworkPolicy policy;
1879        synchronized (mRulesLock) {
1880            policy = findPolicyForNetworkLocked(ident);
1881        }
1882
1883        if (policy != null) {
1884            return policy.metered;
1885        } else {
1886            final int type = state.networkInfo.getType();
1887            if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) {
1888                return true;
1889            }
1890            return false;
1891        }
1892    }
1893
1894    @Override
1895    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
1896        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
1897
1898        final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
1899
1900        final ArraySet<String> argSet = new ArraySet<String>(args.length);
1901        for (String arg : args) {
1902            argSet.add(arg);
1903        }
1904
1905        synchronized (mRulesLock) {
1906            if (argSet.contains("--unsnooze")) {
1907                for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1908                    mNetworkPolicy.valueAt(i).clearSnooze();
1909                }
1910
1911                normalizePoliciesLocked();
1912                updateNetworkEnabledLocked();
1913                updateNetworkRulesLocked();
1914                updateNotificationsLocked();
1915                writePolicyLocked();
1916
1917                fout.println("Cleared snooze timestamps");
1918                return;
1919            }
1920
1921            fout.print("System ready: "); fout.println(mSystemReady);
1922            fout.print("Restrict background: "); fout.println(mRestrictBackground);
1923            fout.print("Restrict power: "); fout.println(mRestrictPower);
1924            fout.print("Device idle: "); fout.println(mDeviceIdleMode);
1925            fout.println("Network policies:");
1926            fout.increaseIndent();
1927            for (int i = 0; i < mNetworkPolicy.size(); i++) {
1928                fout.println(mNetworkPolicy.valueAt(i).toString());
1929            }
1930            fout.decreaseIndent();
1931
1932            fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
1933
1934            fout.println("Policy for UIDs:");
1935            fout.increaseIndent();
1936            int size = mUidPolicy.size();
1937            for (int i = 0; i < size; i++) {
1938                final int uid = mUidPolicy.keyAt(i);
1939                final int policy = mUidPolicy.valueAt(i);
1940                fout.print("UID=");
1941                fout.print(uid);
1942                fout.print(" policy=");
1943                fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
1944                fout.println();
1945            }
1946            fout.decreaseIndent();
1947
1948            size = mPowerSaveWhitelistExceptIdleAppIds.size();
1949            if (size > 0) {
1950                fout.println("Power save whitelist (except idle) app ids:");
1951                fout.increaseIndent();
1952                for (int i = 0; i < size; i++) {
1953                    fout.print("UID=");
1954                    fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
1955                    fout.print(": ");
1956                    fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
1957                    fout.println();
1958                }
1959                fout.decreaseIndent();
1960            }
1961
1962            size = mPowerSaveWhitelistAppIds.size();
1963            if (size > 0) {
1964                fout.println("Power save whitelist app ids:");
1965                fout.increaseIndent();
1966                for (int i = 0; i < size; i++) {
1967                    fout.print("UID=");
1968                    fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
1969                    fout.print(": ");
1970                    fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
1971                    fout.println();
1972                }
1973                fout.decreaseIndent();
1974            }
1975
1976            final SparseBooleanArray knownUids = new SparseBooleanArray();
1977            collectKeys(mUidState, knownUids);
1978            collectKeys(mUidRules, knownUids);
1979
1980            fout.println("Status for known UIDs:");
1981            fout.increaseIndent();
1982            size = knownUids.size();
1983            for (int i = 0; i < size; i++) {
1984                final int uid = knownUids.keyAt(i);
1985                fout.print("UID=");
1986                fout.print(uid);
1987
1988                final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
1989                fout.print(" state=");
1990                fout.print(state);
1991                fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
1992
1993                final int rule = mUidRules.get(uid, RULE_UNKNOWN);
1994                fout.print(" rule=");
1995                fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
1996
1997                fout.println();
1998            }
1999            fout.decreaseIndent();
2000        }
2001    }
2002
2003    @Override
2004    public boolean isUidForeground(int uid) {
2005        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2006
2007        synchronized (mRulesLock) {
2008            return isUidForegroundLocked(uid);
2009        }
2010    }
2011
2012    boolean isUidForegroundLocked(int uid) {
2013        // only really in foreground when screen is also on
2014        return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
2015                <= ActivityManager.PROCESS_STATE_TOP;
2016    }
2017
2018    /**
2019     * Process state of UID changed; if needed, will trigger
2020     * {@link #updateRulesForUidLocked(int)}.
2021     */
2022    void updateUidStateLocked(int uid, int uidState) {
2023        final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2024        if (oldUidState != uidState) {
2025            // state changed, push updated rules
2026            mUidState.put(uid, uidState);
2027            updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
2028            if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
2029                    != isProcStateAllowedWhileIdle(uidState)) {
2030                updateRuleForDeviceIdleLocked(uid);
2031            }
2032        }
2033    }
2034
2035    void removeUidStateLocked(int uid) {
2036        final int index = mUidState.indexOfKey(uid);
2037        if (index >= 0) {
2038            final int oldUidState = mUidState.valueAt(index);
2039            mUidState.removeAt(index);
2040            if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2041                updateRulesForUidStateChangeLocked(uid, oldUidState,
2042                        ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2043                if (mDeviceIdleMode) {
2044                    updateRuleForDeviceIdleLocked(uid);
2045                }
2046            }
2047        }
2048    }
2049
2050    void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
2051        final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP;
2052        final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP;
2053        if (oldForeground != newForeground) {
2054            updateRulesForUidLocked(uid);
2055        }
2056    }
2057
2058    private void updateScreenOn() {
2059        synchronized (mRulesLock) {
2060            try {
2061                mScreenOn = mPowerManager.isInteractive();
2062            } catch (RemoteException e) {
2063                // ignored; service lives in system_server
2064            }
2065            updateRulesForScreenLocked();
2066        }
2067    }
2068
2069    /**
2070     * Update rules that might be changed by {@link #mScreenOn} value.
2071     */
2072    private void updateRulesForScreenLocked() {
2073        // only update rules for anyone with foreground activities
2074        final int size = mUidState.size();
2075        for (int i = 0; i < size; i++) {
2076            if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) {
2077                final int uid = mUidState.keyAt(i);
2078                updateRulesForUidLocked(uid);
2079            }
2080        }
2081    }
2082
2083    static boolean isProcStateAllowedWhileIdle(int procState) {
2084        return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
2085    }
2086
2087    void updateRulesForDeviceIdleLocked() {
2088        if (mDeviceIdleMode) {
2089            // sync the whitelists before enable dozable chain.  We don't care about the rules if
2090            // we are disabling the chain.
2091            final SparseIntArray uidRules = mUidFirewallDozableRules;
2092            uidRules.clear();
2093            final List<UserInfo> users = mUserManager.getUsers();
2094            for (int ui = users.size() - 1; ui >= 0; ui--) {
2095                UserInfo user = users.get(ui);
2096                for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
2097                    if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
2098                        int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
2099                        int uid = UserHandle.getUid(user.id, appId);
2100                        uidRules.put(uid, FIREWALL_RULE_ALLOW);
2101                    }
2102                }
2103                for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
2104                    int appId = mPowerSaveWhitelistAppIds.keyAt(i);
2105                    int uid = UserHandle.getUid(user.id, appId);
2106                    uidRules.put(uid, FIREWALL_RULE_ALLOW);
2107                }
2108            }
2109            for (int i = mUidState.size() - 1; i >= 0; i--) {
2110                if (isProcStateAllowedWhileIdle(mUidState.valueAt(i))) {
2111                    uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
2112                }
2113            }
2114            setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
2115        }
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        updateRulesForUidLocked(uid);
2132    }
2133
2134    void updateRulesForAppIdleLocked() {
2135        final SparseIntArray uidRules = mUidFirewallStandbyRules;
2136        uidRules.clear();
2137
2138        // Fully update the app idle firewall chain.
2139        final List<UserInfo> users = mUserManager.getUsers();
2140        for (int ui = users.size() - 1; ui >= 0; ui--) {
2141            UserInfo user = users.get(ui);
2142            int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
2143            for (int uid : idleUids) {
2144                if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
2145                    uidRules.put(uid, FIREWALL_RULE_DENY);
2146                }
2147            }
2148        }
2149
2150        setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
2151    }
2152
2153    void updateRuleForAppIdleLocked(int uid) {
2154        if (!isUidValidForRules(uid)) return;
2155
2156        int appId = UserHandle.getAppId(uid);
2157        if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)) {
2158            setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
2159        } else {
2160            setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
2161        }
2162
2163        updateRulesForUidLocked(uid);
2164    }
2165
2166    void updateRulesForAppIdleParoleLocked() {
2167        boolean enableChain = !mUsageStats.isAppIdleParoleOn();
2168        enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
2169        updateRulesForUidsLocked(mUidFirewallStandbyRules);
2170    }
2171
2172    /**
2173     * Update rules that might be changed by {@link #mRestrictBackground},
2174     * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
2175     */
2176    void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) {
2177        final PackageManager pm = mContext.getPackageManager();
2178
2179        updateRulesForDeviceIdleLocked();
2180        updateRulesForAppIdleLocked();
2181
2182        // update rules for all installed applications
2183        final List<UserInfo> users = mUserManager.getUsers();
2184        final List<ApplicationInfo> apps = pm.getInstalledApplications(
2185                PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
2186
2187        for (UserInfo user : users) {
2188            for (ApplicationInfo app : apps) {
2189                final int uid = UserHandle.getUid(user.id, app.uid);
2190                updateRulesForUidLocked(uid);
2191            }
2192        }
2193
2194        // limit data usage for some internal system services
2195        updateRulesForUidLocked(android.os.Process.MEDIA_UID);
2196        updateRulesForUidLocked(android.os.Process.DRM_UID);
2197
2198        // If the set of restricted networks may have changed, re-evaluate those.
2199        if (restrictedNetworksChanged) {
2200            normalizePoliciesLocked();
2201            updateNetworkRulesLocked();
2202        }
2203    }
2204
2205    void updateRulesForTempWhitelistChangeLocked() {
2206        final List<UserInfo> users = mUserManager.getUsers();
2207        for (UserInfo user : users) {
2208            for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
2209                int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
2210                int uid = UserHandle.getUid(user.id, appId);
2211                updateRuleForAppIdleLocked(uid);
2212                updateRuleForDeviceIdleLocked(uid);
2213            }
2214        }
2215    }
2216
2217    private static boolean isUidValidForRules(int uid) {
2218        // allow rules on specific system services, and any apps
2219        if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
2220                || UserHandle.isApp(uid)) {
2221            return true;
2222        }
2223
2224        return false;
2225    }
2226
2227    private boolean isUidIdle(int uid) {
2228        final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
2229        final int userId = UserHandle.getUserId(uid);
2230
2231        for (String packageName : packages) {
2232            if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
2233                return false;
2234            }
2235        }
2236        return true;
2237    }
2238
2239    void updateRulesForUidsLocked(SparseIntArray uids) {
2240        for (int i = 0; i < uids.size(); i++) {
2241            updateRulesForUidLocked(uids.keyAt(i));
2242        }
2243    }
2244
2245    /**
2246     * Applies network rules to bandwidth and firewall controllers based on uid policy.
2247     * @param uid The uid for which to apply the latest policy
2248     */
2249    void updateRulesForUidLocked(int uid) {
2250        if (!isUidValidForRules(uid)) return;
2251
2252        // quick check: if this uid doesn't have INTERNET permission, it doesn't have
2253        // network access anyway, so it is a waste to mess with it here.
2254        final IPackageManager ipm = AppGlobals.getPackageManager();
2255        try {
2256            if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid)
2257                    != PackageManager.PERMISSION_GRANTED) {
2258                return;
2259            }
2260        } catch (RemoteException e) {
2261        }
2262
2263        final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
2264        final boolean uidForeground = isUidForegroundLocked(uid);
2265
2266        // Derive active rules based on policy and active state
2267        int appId = UserHandle.getAppId(uid);
2268        int uidRules = RULE_ALLOW_ALL;
2269        if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
2270            // uid in background, and policy says to block metered data
2271            uidRules = RULE_REJECT_METERED;
2272        } else if (mRestrictBackground) {
2273            if (!uidForeground) {
2274                // uid in background, and global background disabled
2275                uidRules = RULE_REJECT_METERED;
2276            }
2277        } else if (mRestrictPower) {
2278            final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId)
2279                    || mPowerSaveTempWhitelistAppIds.get(appId);
2280            if (!whitelisted && !uidForeground
2281                    && (uidPolicy & POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) == 0) {
2282                // uid is in background, restrict power use mode is on (so we want to
2283                // restrict all background network access), and this uid is not on the
2284                // white list of those allowed background access.
2285                uidRules = RULE_REJECT_METERED;
2286            }
2287        }
2288
2289        // Check dozable state, which is whitelist
2290        if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)
2291                && mUidFirewallDozableRules.get(uid, FIREWALL_RULE_DEFAULT) != FIREWALL_RULE_ALLOW) {
2292            uidRules = RULE_REJECT_ALL;
2293        }
2294
2295        // Check standby state, which is blacklist
2296        if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)
2297                && mUidFirewallStandbyRules.get(uid, FIREWALL_RULE_DEFAULT) == FIREWALL_RULE_DENY) {
2298            uidRules = RULE_REJECT_ALL;
2299        }
2300
2301        final int oldRules = mUidRules.get(uid);
2302        if (uidRules == RULE_ALLOW_ALL) {
2303            mUidRules.delete(uid);
2304        } else {
2305            mUidRules.put(uid, uidRules);
2306        }
2307
2308        final boolean rejectMetered = (uidRules == RULE_REJECT_METERED);
2309        setUidNetworkRules(uid, rejectMetered);
2310
2311        // dispatch changed rule to existing listeners
2312        if (oldRules != uidRules) {
2313            mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
2314        }
2315
2316        try {
2317            // adjust stats accounting based on foreground status
2318            mNetworkStats.setUidForeground(uid, uidForeground);
2319        } catch (RemoteException e) {
2320            // ignored; service lives in system_server
2321        }
2322    }
2323
2324    private class AppIdleStateChangeListener
2325            extends UsageStatsManagerInternal.AppIdleStateChangeListener {
2326
2327        @Override
2328        public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
2329            try {
2330                int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
2331                synchronized (mRulesLock) {
2332                    updateRuleForAppIdleLocked(uid);
2333                }
2334            } catch (NameNotFoundException nnfe) {
2335            }
2336        }
2337
2338        @Override
2339        public void onParoleStateChanged(boolean isParoleOn) {
2340            synchronized (mRulesLock) {
2341                updateRulesForAppIdleParoleLocked();
2342            }
2343        }
2344    }
2345
2346    private Handler.Callback mHandlerCallback = new Handler.Callback() {
2347        @Override
2348        public boolean handleMessage(Message msg) {
2349            switch (msg.what) {
2350                case MSG_RULES_CHANGED: {
2351                    final int uid = msg.arg1;
2352                    final int uidRules = msg.arg2;
2353                    final int length = mListeners.beginBroadcast();
2354                    for (int i = 0; i < length; i++) {
2355                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
2356                        if (listener != null) {
2357                            try {
2358                                listener.onUidRulesChanged(uid, uidRules);
2359                            } catch (RemoteException e) {
2360                            }
2361                        }
2362                    }
2363                    mListeners.finishBroadcast();
2364                    return true;
2365                }
2366                case MSG_METERED_IFACES_CHANGED: {
2367                    final String[] meteredIfaces = (String[]) msg.obj;
2368                    final int length = mListeners.beginBroadcast();
2369                    for (int i = 0; i < length; i++) {
2370                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
2371                        if (listener != null) {
2372                            try {
2373                                listener.onMeteredIfacesChanged(meteredIfaces);
2374                            } catch (RemoteException e) {
2375                            }
2376                        }
2377                    }
2378                    mListeners.finishBroadcast();
2379                    return true;
2380                }
2381                case MSG_LIMIT_REACHED: {
2382                    final String iface = (String) msg.obj;
2383
2384                    maybeRefreshTrustedTime();
2385                    synchronized (mRulesLock) {
2386                        if (mMeteredIfaces.contains(iface)) {
2387                            try {
2388                                // force stats update to make sure we have
2389                                // numbers that caused alert to trigger.
2390                                mNetworkStats.forceUpdate();
2391                            } catch (RemoteException e) {
2392                                // ignored; service lives in system_server
2393                            }
2394
2395                            updateNetworkEnabledLocked();
2396                            updateNotificationsLocked();
2397                        }
2398                    }
2399                    return true;
2400                }
2401                case MSG_RESTRICT_BACKGROUND_CHANGED: {
2402                    final boolean restrictBackground = msg.arg1 != 0;
2403                    final int length = mListeners.beginBroadcast();
2404                    for (int i = 0; i < length; i++) {
2405                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
2406                        if (listener != null) {
2407                            try {
2408                                listener.onRestrictBackgroundChanged(restrictBackground);
2409                            } catch (RemoteException e) {
2410                            }
2411                        }
2412                    }
2413                    mListeners.finishBroadcast();
2414                    return true;
2415                }
2416                case MSG_ADVISE_PERSIST_THRESHOLD: {
2417                    final long lowestRule = (Long) msg.obj;
2418                    try {
2419                        // make sure stats are recorded frequently enough; we aim
2420                        // for 2MB threshold for 2GB/month rules.
2421                        final long persistThreshold = lowestRule / 1000;
2422                        mNetworkStats.advisePersistThreshold(persistThreshold);
2423                    } catch (RemoteException e) {
2424                        // ignored; service lives in system_server
2425                    }
2426                    return true;
2427                }
2428                case MSG_SCREEN_ON_CHANGED: {
2429                    updateScreenOn();
2430                    return true;
2431                }
2432                default: {
2433                    return false;
2434                }
2435            }
2436        }
2437    };
2438
2439    private void setInterfaceQuota(String iface, long quotaBytes) {
2440        try {
2441            mNetworkManager.setInterfaceQuota(iface, quotaBytes);
2442        } catch (IllegalStateException e) {
2443            Log.wtf(TAG, "problem setting interface quota", e);
2444        } catch (RemoteException e) {
2445            // ignored; service lives in system_server
2446        }
2447    }
2448
2449    private void removeInterfaceQuota(String iface) {
2450        try {
2451            mNetworkManager.removeInterfaceQuota(iface);
2452        } catch (IllegalStateException e) {
2453            Log.wtf(TAG, "problem removing interface quota", e);
2454        } catch (RemoteException e) {
2455            // ignored; service lives in system_server
2456        }
2457    }
2458
2459    private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
2460        try {
2461            mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
2462        } catch (IllegalStateException e) {
2463            Log.wtf(TAG, "problem setting uid rules", e);
2464        } catch (RemoteException e) {
2465            // ignored; service lives in system_server
2466        }
2467    }
2468
2469    /**
2470     * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
2471     * here to netd.  It will clean up dead rules and make sure the target chain only contains rules
2472     * specified here.
2473     */
2474    private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
2475        try {
2476            int size = uidRules.size();
2477            int[] uids = new int[size];
2478            int[] rules = new int[size];
2479            for(int index = size - 1; index >= 0; --index) {
2480                uids[index] = uidRules.keyAt(index);
2481                rules[index] = uidRules.valueAt(index);
2482            }
2483            mNetworkManager.setFirewallUidRules(chain, uids, rules);
2484        } catch (IllegalStateException e) {
2485            Log.wtf(TAG, "problem setting firewall uid rules", e);
2486        } catch (RemoteException e) {
2487            // ignored; service lives in system_server
2488        }
2489    }
2490
2491    /**
2492     * Add or remove a uid to the firewall blacklist for all network ifaces.
2493     */
2494    private void setUidFirewallRule(int chain, int uid, int rule) {
2495        if (chain == FIREWALL_CHAIN_DOZABLE) {
2496            mUidFirewallDozableRules.put(uid, rule);
2497        } else if (chain == FIREWALL_CHAIN_STANDBY) {
2498            mUidFirewallStandbyRules.put(uid, rule);
2499        }
2500
2501        try {
2502            mNetworkManager.setFirewallUidRule(chain, uid, rule);
2503        } catch (IllegalStateException e) {
2504            Log.wtf(TAG, "problem setting firewall uid rules", e);
2505        } catch (RemoteException e) {
2506            // ignored; service lives in system_server
2507        }
2508    }
2509
2510    /**
2511     * Add or remove a uid to the firewall blacklist for all network ifaces.
2512     */
2513    private void enableFirewallChainLocked(int chain, boolean enable) {
2514        if (mFirewallChainStates.get(chain, false) == enable) {
2515            // All is the same, nothing to do.  This relies on the fact that netd has child
2516            // chains default detached.
2517            return;
2518        }
2519        mFirewallChainStates.put(chain, enable);
2520        try {
2521            mNetworkManager.setFirewallChainEnabled(chain, enable);
2522        } catch (IllegalStateException e) {
2523            Log.wtf(TAG, "problem enable firewall chain", e);
2524        } catch (RemoteException e) {
2525            // ignored; service lives in system_server
2526        }
2527    }
2528
2529    private long getTotalBytes(NetworkTemplate template, long start, long end) {
2530        try {
2531            return mNetworkStats.getNetworkTotalBytes(template, start, end);
2532        } catch (RuntimeException e) {
2533            Slog.w(TAG, "problem reading network stats: " + e);
2534            return 0;
2535        } catch (RemoteException e) {
2536            // ignored; service lives in system_server
2537            return 0;
2538        }
2539    }
2540
2541    private boolean isBandwidthControlEnabled() {
2542        final long token = Binder.clearCallingIdentity();
2543        try {
2544            return mNetworkManager.isBandwidthControlEnabled();
2545        } catch (RemoteException e) {
2546            // ignored; service lives in system_server
2547            return false;
2548        } finally {
2549            Binder.restoreCallingIdentity(token);
2550        }
2551    }
2552
2553    /**
2554     * Try refreshing {@link #mTime} when stale.
2555     */
2556    void maybeRefreshTrustedTime() {
2557        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
2558            mTime.forceRefresh();
2559        }
2560    }
2561
2562    private long currentTimeMillis() {
2563        return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
2564    }
2565
2566    private static Intent buildAllowBackgroundDataIntent() {
2567        return new Intent(ACTION_ALLOW_BACKGROUND);
2568    }
2569
2570    private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
2571        final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
2572        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
2573        return intent;
2574    }
2575
2576    private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
2577        final Intent intent = new Intent();
2578        intent.setComponent(new ComponentName(
2579                "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity"));
2580        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2581        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
2582        return intent;
2583    }
2584
2585    private static Intent buildViewDataUsageIntent(NetworkTemplate template) {
2586        final Intent intent = new Intent();
2587        intent.setComponent(new ComponentName(
2588                "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
2589        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2590        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
2591        return intent;
2592    }
2593
2594    @VisibleForTesting
2595    public void addIdleHandler(IdleHandler handler) {
2596        mHandler.getLooper().getQueue().addIdleHandler(handler);
2597    }
2598
2599    private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
2600        final int size = source.size();
2601        for (int i = 0; i < size; i++) {
2602            target.put(source.keyAt(i), true);
2603        }
2604    }
2605
2606    @Override
2607    public void factoryReset(String subscriber) {
2608        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2609
2610        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
2611            return;
2612        }
2613
2614        // Turn mobile data limit off
2615        NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
2616        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
2617        for (NetworkPolicy policy : policies) {
2618            if (policy.template.equals(template)) {
2619                policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2620                policy.inferred = false;
2621                policy.clearSnooze();
2622            }
2623        }
2624        setNetworkPolicies(policies);
2625
2626        // Turn restrict background data off
2627        setRestrictBackground(false);
2628
2629        if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
2630            // Remove app's "restrict background data" flag
2631            for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
2632                setUidPolicy(uid, POLICY_NONE);
2633            }
2634        }
2635    }
2636}
2637