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