[go: nahoru, domu]

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