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