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