OSDN Git Service

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