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