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