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