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