• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.net;
18 
19 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
20 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
21 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
23 import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS;
24 import static android.Manifest.permission.NETWORK_SETTINGS;
25 import static android.Manifest.permission.NETWORK_STACK;
26 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
27 import static android.Manifest.permission.READ_PHONE_STATE;
28 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
29 import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
30 import static android.app.ActivityManager.isProcStateConsideredInteraction;
31 import static android.app.ActivityManager.procStateToString;
32 import static android.app.PendingIntent.FLAG_IMMUTABLE;
33 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
34 import static android.content.Intent.ACTION_PACKAGE_ADDED;
35 import static android.content.Intent.ACTION_UID_REMOVED;
36 import static android.content.Intent.ACTION_USER_ADDED;
37 import static android.content.Intent.ACTION_USER_REMOVED;
38 import static android.content.Intent.EXTRA_UID;
39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
40 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
43 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
46 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
47 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
48 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
49 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
50 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
51 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
52 import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY;
53 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
54 import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE;
55 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
57 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
58 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
59 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
60 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
61 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
62 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
63 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
64 import static android.net.ConnectivityManager.TYPE_MOBILE;
65 import static android.net.INetd.FIREWALL_RULE_ALLOW;
66 import static android.net.INetd.FIREWALL_RULE_DENY;
67 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
68 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
69 import static android.net.NetworkPolicy.LIMIT_DISABLED;
70 import static android.net.NetworkPolicy.SNOOZE_NEVER;
71 import static android.net.NetworkPolicy.WARNING_DISABLED;
72 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND;
73 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
74 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
75 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
76 import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
77 import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST;
78 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
79 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
80 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
81 import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
82 import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
83 import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP;
84 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
85 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
86 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
87 import static android.net.NetworkPolicyManager.POLICY_NONE;
88 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
89 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
90 import static android.net.NetworkPolicyManager.RULE_NONE;
91 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
92 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
93 import static android.net.NetworkPolicyManager.RULE_REJECT_RESTRICTED_MODE;
94 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
95 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
96 import static android.net.NetworkPolicyManager.allowedReasonsToString;
97 import static android.net.NetworkPolicyManager.blockedReasonsToString;
98 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
99 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileInLowPowerStandby;
100 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
101 import static android.net.NetworkPolicyManager.resolveNetworkId;
102 import static android.net.NetworkPolicyManager.uidPoliciesToString;
103 import static android.net.NetworkPolicyManager.uidRulesToString;
104 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
105 import static android.net.NetworkStats.METERED_ALL;
106 import static android.net.NetworkStats.METERED_YES;
107 import static android.net.NetworkTemplate.MATCH_CARRIER;
108 import static android.net.NetworkTemplate.MATCH_MOBILE;
109 import static android.net.NetworkTemplate.MATCH_WIFI;
110 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
111 import static android.os.Trace.TRACE_TAG_NETWORK;
112 import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
113 import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
114 import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
115 import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
116 import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
117 import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
118 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
119 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
120 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
121 import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL;
122 import static android.telephony.CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL;
123 import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL;
124 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
125 
126 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
127 import static com.android.internal.util.ArrayUtils.appendInt;
128 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
129 import static com.android.internal.util.XmlUtils.readIntAttribute;
130 import static com.android.internal.util.XmlUtils.readLongAttribute;
131 import static com.android.internal.util.XmlUtils.readStringAttribute;
132 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
133 import static com.android.internal.util.XmlUtils.writeIntAttribute;
134 import static com.android.internal.util.XmlUtils.writeLongAttribute;
135 import static com.android.internal.util.XmlUtils.writeStringAttribute;
136 import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
137 
138 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
139 import static org.xmlpull.v1.XmlPullParser.END_TAG;
140 import static org.xmlpull.v1.XmlPullParser.START_TAG;
141 
142 import android.Manifest;
143 import android.annotation.IntDef;
144 import android.annotation.NonNull;
145 import android.annotation.Nullable;
146 import android.app.ActivityManager;
147 import android.app.ActivityManager.ProcessCapability;
148 import android.app.ActivityManagerInternal;
149 import android.app.AppGlobals;
150 import android.app.AppOpsManager;
151 import android.app.IActivityManager;
152 import android.app.IUidObserver;
153 import android.app.Notification;
154 import android.app.NotificationManager;
155 import android.app.PendingIntent;
156 import android.app.usage.NetworkStats;
157 import android.app.usage.NetworkStatsManager;
158 import android.app.usage.UsageStatsManagerInternal;
159 import android.content.BroadcastReceiver;
160 import android.content.ComponentName;
161 import android.content.ContentResolver;
162 import android.content.Context;
163 import android.content.Intent;
164 import android.content.IntentFilter;
165 import android.content.pm.ApplicationInfo;
166 import android.content.pm.IPackageManager;
167 import android.content.pm.PackageManager;
168 import android.content.pm.PackageManager.NameNotFoundException;
169 import android.content.pm.PackageManagerInternal;
170 import android.content.pm.UserInfo;
171 import android.content.res.Resources;
172 import android.database.ContentObserver;
173 import android.net.ConnectivityManager;
174 import android.net.ConnectivityManager.NetworkCallback;
175 import android.net.INetworkManagementEventObserver;
176 import android.net.INetworkPolicyListener;
177 import android.net.INetworkPolicyManager;
178 import android.net.LinkProperties;
179 import android.net.Network;
180 import android.net.NetworkCapabilities;
181 import android.net.NetworkIdentity;
182 import android.net.NetworkPolicy;
183 import android.net.NetworkPolicyManager;
184 import android.net.NetworkPolicyManager.UidState;
185 import android.net.NetworkRequest;
186 import android.net.NetworkStack;
187 import android.net.NetworkStateSnapshot;
188 import android.net.NetworkTemplate;
189 import android.net.wifi.WifiConfiguration;
190 import android.net.wifi.WifiManager;
191 import android.os.BestClock;
192 import android.os.Binder;
193 import android.os.Environment;
194 import android.os.Handler;
195 import android.os.HandlerExecutor;
196 import android.os.HandlerThread;
197 import android.os.INetworkManagementService;
198 import android.os.Message;
199 import android.os.MessageQueue.IdleHandler;
200 import android.os.ParcelFileDescriptor;
201 import android.os.PersistableBundle;
202 import android.os.PowerExemptionManager.ReasonCode;
203 import android.os.PowerManager;
204 import android.os.PowerManager.ServiceType;
205 import android.os.PowerManagerInternal;
206 import android.os.PowerSaveState;
207 import android.os.PowerWhitelistManager;
208 import android.os.Process;
209 import android.os.RemoteCallbackList;
210 import android.os.RemoteException;
211 import android.os.SystemClock;
212 import android.os.SystemProperties;
213 import android.os.Trace;
214 import android.os.UserHandle;
215 import android.os.UserManager;
216 import android.provider.Settings;
217 import android.provider.Settings.Global;
218 import android.telephony.CarrierConfigManager;
219 import android.telephony.SubscriptionInfo;
220 import android.telephony.SubscriptionManager;
221 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
222 import android.telephony.SubscriptionPlan;
223 import android.telephony.TelephonyManager;
224 import android.text.TextUtils;
225 import android.text.format.DateUtils;
226 import android.text.format.Formatter;
227 import android.util.ArrayMap;
228 import android.util.ArraySet;
229 import android.util.AtomicFile;
230 import android.util.DataUnit;
231 import android.util.IntArray;
232 import android.util.Log;
233 import android.util.Pair;
234 import android.util.Range;
235 import android.util.RecurrenceRule;
236 import android.util.Slog;
237 import android.util.SparseArray;
238 import android.util.SparseBooleanArray;
239 import android.util.SparseIntArray;
240 import android.util.SparseLongArray;
241 import android.util.SparseSetArray;
242 import android.util.TypedXmlPullParser;
243 import android.util.TypedXmlSerializer;
244 import android.util.Xml;
245 
246 import com.android.internal.R;
247 import com.android.internal.annotations.GuardedBy;
248 import com.android.internal.annotations.VisibleForTesting;
249 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
250 import com.android.internal.notification.SystemNotificationChannels;
251 import com.android.internal.os.SomeArgs;
252 import com.android.internal.util.ArrayUtils;
253 import com.android.internal.util.CollectionUtils;
254 import com.android.internal.util.ConcurrentUtils;
255 import com.android.internal.util.DumpUtils;
256 import com.android.internal.util.IndentingPrintWriter;
257 import com.android.internal.util.StatLogger;
258 import com.android.net.module.util.NetworkIdentityUtils;
259 import com.android.net.module.util.NetworkStatsUtils;
260 import com.android.net.module.util.PermissionUtils;
261 import com.android.server.EventLogTags;
262 import com.android.server.LocalServices;
263 import com.android.server.ServiceThread;
264 import com.android.server.SystemConfig;
265 import com.android.server.connectivity.MultipathPolicyTracker;
266 import com.android.server.usage.AppStandbyInternal;
267 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
268 
269 import dalvik.annotation.optimization.NeverCompile;
270 
271 import libcore.io.IoUtils;
272 
273 import java.io.File;
274 import java.io.FileDescriptor;
275 import java.io.FileInputStream;
276 import java.io.FileNotFoundException;
277 import java.io.FileOutputStream;
278 import java.io.IOException;
279 import java.io.PrintWriter;
280 import java.lang.annotation.Retention;
281 import java.lang.annotation.RetentionPolicy;
282 import java.time.Clock;
283 import java.time.Instant;
284 import java.time.ZoneId;
285 import java.time.ZoneOffset;
286 import java.time.ZonedDateTime;
287 import java.time.temporal.ChronoUnit;
288 import java.util.ArrayList;
289 import java.util.Arrays;
290 import java.util.Calendar;
291 import java.util.List;
292 import java.util.Objects;
293 import java.util.Set;
294 import java.util.concurrent.CountDownLatch;
295 import java.util.concurrent.Executor;
296 import java.util.concurrent.TimeUnit;
297 import java.util.function.IntConsumer;
298 
299 /**
300  * Service that maintains low-level network policy rules, using
301  * {@link NetworkStatsService} statistics to drive those rules.
302  * <p>
303  * Derives active rules by combining a given policy with other system status,
304  * and delivers to listeners, such as {@link ConnectivityManager}, for
305  * enforcement.
306  *
307  * <p>
308  * This class uses 2 locks to synchronize state:
309  * <ul>
310  * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
311  * rules).
312  * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
313  * as network policies).
314  * </ul>
315  *
316  * <p>
317  * As such, methods that require synchronization have the following prefixes:
318  * <ul>
319  * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
320  * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
321  * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
322  * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
323  * </ul>
324  */
325 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
326     static final String TAG = NetworkPolicyLogger.TAG;
327     private static final boolean LOGD = NetworkPolicyLogger.LOGD;
328     private static final boolean LOGV = NetworkPolicyLogger.LOGV;
329 
330     /**
331      * No opportunistic quota could be calculated from user data plan or data settings.
332      */
333     public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1;
334 
335     private static final int VERSION_INIT = 1;
336     private static final int VERSION_ADDED_SNOOZE = 2;
337     private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
338     private static final int VERSION_ADDED_METERED = 4;
339     private static final int VERSION_SPLIT_SNOOZE = 5;
340     private static final int VERSION_ADDED_TIMEZONE = 6;
341     private static final int VERSION_ADDED_INFERRED = 7;
342     private static final int VERSION_SWITCH_APP_ID = 8;
343     private static final int VERSION_ADDED_NETWORK_ID = 9;
344     private static final int VERSION_SWITCH_UID = 10;
345     private static final int VERSION_ADDED_CYCLE = 11;
346     private static final int VERSION_ADDED_NETWORK_TYPES = 12;
347     private static final int VERSION_SUPPORTED_CARRIER_USAGE = 13;
348     private static final int VERSION_REMOVED_SUBSCRIPTION_PLANS = 14;
349     private static final int VERSION_LATEST = VERSION_REMOVED_SUBSCRIPTION_PLANS;
350 
351     @VisibleForTesting
352     public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
353     @VisibleForTesting
354     public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
355     @VisibleForTesting
356     public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
357     @VisibleForTesting
358     public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID;
359 
360     private static final String TAG_POLICY_LIST = "policy-list";
361     private static final String TAG_NETWORK_POLICY = "network-policy";
362     private static final String TAG_UID_POLICY = "uid-policy";
363     private static final String TAG_APP_POLICY = "app-policy";
364     private static final String TAG_WHITELIST = "whitelist";
365     private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
366     private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
367     private static final String TAG_XML_UTILS_INT_ARRAY = "int-array";
368 
369     private static final String ATTR_VERSION = "version";
370     private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
371     private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
372     private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
373     private static final String ATTR_SUBSCRIBER_ID_MATCH_RULE = "subscriberIdMatchRule";
374     private static final String ATTR_NETWORK_ID = "networkId";
375     private static final String ATTR_TEMPLATE_METERED = "templateMetered";
376     @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
377     @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
378     private static final String ATTR_CYCLE_START = "cycleStart";
379     private static final String ATTR_CYCLE_END = "cycleEnd";
380     private static final String ATTR_CYCLE_PERIOD = "cyclePeriod";
381     private static final String ATTR_WARNING_BYTES = "warningBytes";
382     private static final String ATTR_LIMIT_BYTES = "limitBytes";
383     private static final String ATTR_LAST_SNOOZE = "lastSnooze";
384     private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
385     private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
386     private static final String ATTR_METERED = "metered";
387     private static final String ATTR_INFERRED = "inferred";
388     private static final String ATTR_UID = "uid";
389     private static final String ATTR_APP_ID = "appId";
390     private static final String ATTR_POLICY = "policy";
391     private static final String ATTR_SUB_ID = "subId";
392     private static final String ATTR_TITLE = "title";
393     private static final String ATTR_SUMMARY = "summary";
394     private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
395     private static final String ATTR_USAGE_BYTES = "usageBytes";
396     private static final String ATTR_USAGE_TIME = "usageTime";
397     private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
398     private static final String ATTR_NETWORK_TYPES = "networkTypes";
399     private static final String ATTR_XML_UTILS_NAME = "name";
400 
401     private static final String ACTION_SNOOZE_WARNING =
402             "com.android.server.net.action.SNOOZE_WARNING";
403     private static final String ACTION_SNOOZE_RAPID =
404             "com.android.server.net.action.SNOOZE_RAPID";
405 
406     /**
407      * Indicates the maximum wait time for admin data to be available.
408      */
409     private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
410 
411     private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
412     private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
413     private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
414     private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
415 
416     private static final int MSG_RULES_CHANGED = 1;
417     private static final int MSG_METERED_IFACES_CHANGED = 2;
418     private static final int MSG_LIMIT_REACHED = 5;
419     private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
420     private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
421     private static final int MSG_UPDATE_INTERFACE_QUOTAS = 10;
422     private static final int MSG_REMOVE_INTERFACE_QUOTAS = 11;
423     private static final int MSG_POLICIES_CHANGED = 13;
424     private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
425     private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
426     private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
427     private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
428     private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
429     private static final int MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED = 20;
430 
431     // TODO: Add similar docs for other messages.
432     /**
433      * Message to indicate that reasons for why an uid is blocked changed.
434      * arg1 = uid
435      * arg2 = newBlockedReasons
436      * obj = oldBlockedReasons
437      */
438     private static final int MSG_UID_BLOCKED_REASON_CHANGED = 21;
439 
440     /**
441      * Message to indicate that subscription plans expired and should be cleared.
442      * arg1 = subId
443      * arg2 = setSubscriptionPlans call ID
444      * obj = callingPackage
445      */
446     private static final int MSG_CLEAR_SUBSCRIPTION_PLANS = 22;
447 
448     /**
449      * Message to indicate that reasons for why some uids are blocked changed.
450      * obj = SparseArray<SomeArgs> where key = uid and value = SomeArgs object with
451      *       value.argi1 = oldEffectiveBlockedReasons,
452      *       value.argi2 = newEffectiveBlockedReasons,
453      *       value.argi3 = uidRules
454      */
455     private static final int MSG_UIDS_BLOCKED_REASONS_CHANGED = 23;
456 
457     private static final int UID_MSG_STATE_CHANGED = 100;
458     private static final int UID_MSG_GONE = 101;
459 
460     private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";
461 
462     private final Context mContext;
463     private final IActivityManager mActivityManager;
464     private NetworkStatsManager mNetworkStats;
465     private final INetworkManagementService mNetworkManager;
466     private UsageStatsManagerInternal mUsageStats;
467     private AppStandbyInternal mAppStandby;
468     private final Clock mClock;
469     private final UserManager mUserManager;
470     private final CarrierConfigManager mCarrierConfigManager;
471     private final MultipathPolicyTracker mMultipathPolicyTracker;
472 
473     private ConnectivityManager mConnManager;
474     private PowerManagerInternal mPowerManagerInternal;
475     private PowerWhitelistManager mPowerWhitelistManager;
476     @NonNull
477     private final Dependencies mDeps;
478 
479     /** Current cached value of the current Battery Saver mode's setting for restrict background. */
480     @GuardedBy("mUidRulesFirstLock")
481     private boolean mRestrictBackgroundLowPowerMode;
482 
483     // Store the status of restrict background before turning on battery saver.
484     // Used to restore mRestrictBackground when battery saver is turned off.
485     private boolean mRestrictBackgroundBeforeBsm;
486 
487     // Denotes the status of restrict background read from disk.
488     private boolean mLoadedRestrictBackground;
489 
490     // See main javadoc for instructions on how to use these locks.
491     final Object mUidRulesFirstLock = new Object();
492     final Object mNetworkPoliciesSecondLock = new Object();
493 
494     @GuardedBy(anyOf = {"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
495     volatile boolean mSystemReady;
496 
497     @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
498     @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
499     @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
500     // Store whether user flipped restrict background in battery saver mode
501     @GuardedBy("mUidRulesFirstLock")
502     volatile boolean mRestrictBackgroundChangedInBsm;
503     @GuardedBy("mUidRulesFirstLock")
504     volatile boolean mRestrictedNetworkingMode;
505     @GuardedBy("mUidRulesFirstLock")
506     volatile boolean mLowPowerStandbyActive;
507 
508     private final boolean mSuppressDefaultPolicy;
509 
510     private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
511 
512     private volatile boolean mNetworkManagerReady;
513 
514     /** Defined network policies. */
515     @GuardedBy("mNetworkPoliciesSecondLock")
516     final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
517 
518     /** Map from subId to subscription plans. */
519     @GuardedBy("mNetworkPoliciesSecondLock")
520     final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
521     /** Map from subId to package name that owns subscription plans. */
522     @GuardedBy("mNetworkPoliciesSecondLock")
523     final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
524     /** Map from subId to the ID of the clear plans request. */
525     @GuardedBy("mNetworkPoliciesSecondLock")
526     final SparseIntArray mSetSubscriptionPlansIds = new SparseIntArray();
527     /** Atomic integer to generate a new ID for each clear plans request. */
528     @GuardedBy("mNetworkPoliciesSecondLock")
529     int mSetSubscriptionPlansIdCounter = 0;
530 
531     /** Map from subId to daily opportunistic quota. */
532     @GuardedBy("mNetworkPoliciesSecondLock")
533     final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray();
534 
535     /** Defined UID policies. */
536     @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
537 
538     @GuardedBy("mUidRulesFirstLock")
539     final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
540     @GuardedBy("mUidRulesFirstLock")
541     final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
542     @GuardedBy("mUidRulesFirstLock")
543     final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
544     @GuardedBy("mUidRulesFirstLock")
545     final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray();
546     @GuardedBy("mUidRulesFirstLock")
547     final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray();
548 
549     /** Set of states for the child firewall chains. True if the chain is active. */
550     @GuardedBy("mUidRulesFirstLock")
551     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
552 
553     // "Power save mode" is the concept used in the DeviceIdleController that includes various
554     // features including Doze and Battery Saver. It include Battery Saver, but "power save mode"
555     // and "battery saver" are not equivalent.
556 
557     /**
558      * UIDs that have been allowlisted to always be able to have network access
559      * in power save mode, except device idle (doze) still applies.
560      * TODO: An int array might be sufficient
561      */
562     @GuardedBy("mUidRulesFirstLock")
563     private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
564 
565     /**
566      * UIDs that have been allowlisted to always be able to have network access
567      * in power save mode.
568      * TODO: An int array might be sufficient
569      */
570     @GuardedBy("mUidRulesFirstLock")
571     private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
572 
573     @GuardedBy("mUidRulesFirstLock")
574     private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
575 
576     @GuardedBy("mUidRulesFirstLock")
577     private final SparseBooleanArray mLowPowerStandbyAllowlistUids = new SparseBooleanArray();
578 
579     /**
580      * UIDs that have been allowlisted temporarily to be able to have network access despite being
581      * idle. Other power saving restrictions still apply.
582      */
583     @GuardedBy("mUidRulesFirstLock")
584     private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray();
585 
586     /**
587      * UIDs that have been initially allowlisted by system to avoid restricted background.
588      */
589     @GuardedBy("mUidRulesFirstLock")
590     private final SparseBooleanArray mDefaultRestrictBackgroundAllowlistUids =
591             new SparseBooleanArray();
592 
593     /**
594      * UIDs that have been initially allowlisted by system to avoid restricted background,
595      * but later revoked by user.
596      */
597     @GuardedBy("mUidRulesFirstLock")
598     private final SparseBooleanArray mRestrictBackgroundAllowlistRevokedUids =
599             new SparseBooleanArray();
600 
601     final Object mMeteredIfacesLock = new Object();
602     /** Set of ifaces that are metered. */
603     @GuardedBy("mMeteredIfacesLock")
604     private ArraySet<String> mMeteredIfaces = new ArraySet<>();
605     /** Set of over-limit templates that have been notified. */
606     @GuardedBy("mNetworkPoliciesSecondLock")
607     private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
608 
609     /** Set of currently active {@link Notification} tags. */
610     @GuardedBy("mNetworkPoliciesSecondLock")
611     private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
612 
613     /** Foreground at UID granularity. */
614     @GuardedBy("mUidRulesFirstLock")
615     private final SparseArray<UidState> mUidState = new SparseArray<>();
616 
617     @GuardedBy("mUidBlockedState")
618     private final SparseArray<UidBlockedState> mUidBlockedState = new SparseArray<>();
619 
620     /** Objects used temporarily while computing the new blocked state for each uid. */
621     @GuardedBy("mUidRulesFirstLock")
622     private final SparseArray<UidBlockedState> mTmpUidBlockedState = new SparseArray<>();
623 
624     /** Map from network ID to last observed meteredness state */
625     @GuardedBy("mNetworkPoliciesSecondLock")
626     private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();
627     /** Map from network ID to last observed roaming state */
628     @GuardedBy("mNetworkPoliciesSecondLock")
629     private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
630     /** Map from network ID to the last ifaces on it */
631     @GuardedBy("mNetworkPoliciesSecondLock")
632     private SparseSetArray<String> mNetworkToIfaces = new SparseSetArray<>();
633 
634     /** Map from netId to subId as of last update */
635     @GuardedBy("mNetworkPoliciesSecondLock")
636     private final SparseIntArray mNetIdToSubId = new SparseIntArray();
637 
638     /** Map from subId to subscriberId as of last update */
639     @GuardedBy("mNetworkPoliciesSecondLock")
640     private final SparseArray<String> mSubIdToSubscriberId = new SparseArray<>();
641     /** Set of all merged subscriberId as of last update */
642     @GuardedBy("mNetworkPoliciesSecondLock")
643     private List<String[]> mMergedSubscriberIds = new ArrayList<>();
644     /** Map from subId to carrierConfig as of last update */
645     @GuardedBy("mNetworkPoliciesSecondLock")
646     private final SparseArray<PersistableBundle> mSubIdToCarrierConfig =
647             new SparseArray<PersistableBundle>();
648 
649     /**
650      * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
651      * userId to restricted uids which belong to that user.
652      */
653     @GuardedBy("mUidRulesFirstLock")
654     private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>();
655 
656     private final RemoteCallbackList<INetworkPolicyListener>
657             mListeners = new RemoteCallbackList<>();
658 
659     final Handler mHandler;
660     @VisibleForTesting
661     final Handler mUidEventHandler;
662 
663     private final ServiceThread mUidEventThread;
664 
665     @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
666     private final AtomicFile mPolicyFile;
667 
668     private final AppOpsManager mAppOps;
669 
670     private final IPackageManager mIPm;
671 
672     private ActivityManagerInternal mActivityManagerInternal;
673 
674     private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
675 
676     /** List of apps indexed by uid and whether they have the internet permission */
677     @GuardedBy("mUidRulesFirstLock")
678     private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
679 
680     /**
681      * Map of uid -> UidStateCallbackInfo objects holding the data received from
682      * {@link IUidObserver#onUidStateChanged(int, int, long, int)} callbacks. In order to avoid
683      * creating a new object for every callback received, we hold onto the object created for each
684      * uid and reuse it.
685      *
686      * Note that the lock used for accessing this object should not be used for anything else and we
687      * should not be acquiring new locks or doing any heavy work while this lock is held since this
688      * will be used in the callback from ActivityManagerService.
689      */
690     @GuardedBy("mUidStateCallbackInfos")
691     private final SparseArray<UidStateCallbackInfo> mUidStateCallbackInfos =
692             new SparseArray<>();
693 
694     private RestrictedModeObserver mRestrictedModeObserver;
695 
696     // TODO: keep allowlist of system-critical services that should never have
697     // rules enforced, such as system, phone, and radio UIDs.
698 
699     // TODO: migrate notifications to SystemUI
700 
701 
702     interface Stats {
703         int UPDATE_NETWORK_ENABLED = 0;
704         int IS_UID_NETWORKING_BLOCKED = 1;
705 
706         int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
707     }
708 
709     private static class RestrictedModeObserver extends ContentObserver {
710         private final Context mContext;
711         private final RestrictedModeListener mListener;
712 
RestrictedModeObserver(Context ctx, RestrictedModeListener listener)713         RestrictedModeObserver(Context ctx, RestrictedModeListener listener) {
714             super(null);
715             mContext = ctx;
716             mListener = listener;
717             mContext.getContentResolver().registerContentObserver(
718                     Settings.Global.getUriFor(Settings.Global.RESTRICTED_NETWORKING_MODE), false,
719                     this);
720         }
721 
isRestrictedModeEnabled()722         public boolean isRestrictedModeEnabled() {
723             return Settings.Global.getInt(mContext.getContentResolver(),
724                     Settings.Global.RESTRICTED_NETWORKING_MODE, 0) != 0;
725         }
726 
727         @Override
onChange(boolean selfChange)728         public void onChange(boolean selfChange) {
729             mListener.onChange(isRestrictedModeEnabled());
730         }
731 
732         public interface RestrictedModeListener {
onChange(boolean enabled)733             void onChange(boolean enabled);
734         }
735     }
736 
737     public final StatLogger mStatLogger = new StatLogger(new String[]{
738             "updateNetworkEnabledNL()",
739             "isUidNetworkingBlocked()",
740     });
741 
NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkManagementService networkManagement)742     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
743             INetworkManagementService networkManagement) {
744         this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
745                 getDefaultClock(), getDefaultSystemDir(), false, new Dependencies(context));
746     }
747 
getDefaultSystemDir()748     private static @NonNull File getDefaultSystemDir() {
749         return new File(Environment.getDataDirectory(), "system");
750     }
751 
getDefaultClock()752     private static @NonNull Clock getDefaultClock() {
753         return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
754                 Clock.systemUTC());
755     }
756 
757     static class Dependencies {
758         final Context mContext;
759         final NetworkStatsManager mNetworkStatsManager;
Dependencies(Context context)760         Dependencies(Context context) {
761             mContext = context;
762             mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class);
763             // Query stats from NetworkStatsService will trigger a poll by default.
764             // But since NPMS listens stats updated event, and will query stats
765             // after the event. A polling -> updated -> query -> polling loop will be introduced
766             // if polls on open. Hence, while NPMS manages it's poll requests explicitly, set
767             // flag to false to prevent a polling loop.
768             mNetworkStatsManager.setPollOnOpen(false);
769         }
770 
getNetworkTotalBytes(NetworkTemplate template, long start, long end)771         long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
772             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
773             try {
774                 final NetworkStats.Bucket ret = mNetworkStatsManager
775                         .querySummaryForDevice(template, start, end);
776                 return ret.getRxBytes() + ret.getTxBytes();
777             } catch (RuntimeException e) {
778                 Slog.w(TAG, "Failed to read network stats: " + e);
779                 return 0;
780             } finally {
781                 Trace.traceEnd(TRACE_TAG_NETWORK);
782             }
783         }
784 
785         @NonNull
getNetworkUidBytes( @onNull NetworkTemplate template, long start, long end)786         List<NetworkStats.Bucket> getNetworkUidBytes(
787                 @NonNull NetworkTemplate template, long start, long end) {
788             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
789             final List<NetworkStats.Bucket> buckets = new ArrayList<>();
790             try {
791                 final NetworkStats stats = mNetworkStatsManager.querySummary(template, start, end);
792                 while (stats.hasNextBucket()) {
793                     final NetworkStats.Bucket bucket = new NetworkStats.Bucket();
794                     stats.getNextBucket(bucket);
795                     buckets.add(bucket);
796                 }
797             } catch (RuntimeException e) {
798                 Slog.w(TAG, "Failed to read network stats: " + e);
799             } finally {
800                 Trace.traceEnd(TRACE_TAG_NETWORK);
801             }
802             return buckets;
803         }
804     }
805 
806     @VisibleForTesting
NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkManagementService networkManagement, IPackageManager pm, Clock clock, File systemDir, boolean suppressDefaultPolicy, Dependencies deps)807     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
808             INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
809             File systemDir, boolean suppressDefaultPolicy, Dependencies deps) {
810         mContext = Objects.requireNonNull(context, "missing context");
811         mActivityManager = Objects.requireNonNull(activityManager, "missing activityManager");
812         mNetworkManager = Objects.requireNonNull(networkManagement, "missing networkManagement");
813         mPowerWhitelistManager = mContext.getSystemService(PowerWhitelistManager.class);
814         mClock = Objects.requireNonNull(clock, "missing Clock");
815         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
816         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
817         mIPm = pm;
818 
819         HandlerThread thread = new HandlerThread(TAG);
820         thread.start();
821         mHandler = new Handler(thread.getLooper(), mHandlerCallback);
822 
823         // We create another thread for the UID events, which are more time-critical.
824         mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
825                 /*allowIo=*/ false);
826         mUidEventThread.start();
827         mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
828 
829         mSuppressDefaultPolicy = suppressDefaultPolicy;
830         mDeps = Objects.requireNonNull(deps, "missing Dependencies");
831 
832         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
833 
834         mAppOps = context.getSystemService(AppOpsManager.class);
835         mNetworkStats = context.getSystemService(NetworkStatsManager.class);
836         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
837         // Expose private service for system components to use.
838         LocalServices.addService(NetworkPolicyManagerInternal.class,
839                 new NetworkPolicyManagerInternalImpl());
840     }
841 
bindConnectivityManager()842     public void bindConnectivityManager() {
843         mConnManager = Objects.requireNonNull(mContext.getSystemService(ConnectivityManager.class),
844                 "missing ConnectivityManager");
845     }
846 
847     @GuardedBy("mUidRulesFirstLock")
updatePowerSaveWhitelistUL()848     private void updatePowerSaveWhitelistUL() {
849         int[] whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ false);
850         mPowerSaveWhitelistExceptIdleAppIds.clear();
851         for (int uid : whitelist) {
852             mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
853         }
854 
855         whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ true);
856         mPowerSaveWhitelistAppIds.clear();
857         for (int uid : whitelist) {
858             mPowerSaveWhitelistAppIds.put(uid, true);
859         }
860     }
861 
862     /**
863      * Allows pre-defined apps for restrict background, but only if the user didn't already
864      * revoked them.
865      *
866      * @return whether any uid has been added to allowlist.
867      */
868     @GuardedBy("mUidRulesFirstLock")
addDefaultRestrictBackgroundAllowlistUidsUL()869     boolean addDefaultRestrictBackgroundAllowlistUidsUL() {
870         final List<UserInfo> users = mUserManager.getUsers();
871         final int numberUsers = users.size();
872 
873         boolean changed = false;
874         for (int i = 0; i < numberUsers; i++) {
875             final UserInfo user = users.get(i);
876             changed = addDefaultRestrictBackgroundAllowlistUidsUL(user.id) || changed;
877         }
878         return changed;
879     }
880 
881     @GuardedBy("mUidRulesFirstLock")
addDefaultRestrictBackgroundAllowlistUidsUL(int userId)882     private boolean addDefaultRestrictBackgroundAllowlistUidsUL(int userId) {
883         final SystemConfig sysConfig = SystemConfig.getInstance();
884         final PackageManager pm = mContext.getPackageManager();
885         final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
886         boolean changed = false;
887         for (int i = 0; i < allowDataUsage.size(); i++) {
888             final String pkg = allowDataUsage.valueAt(i);
889             if (LOGD)
890                 Slog.d(TAG, "checking restricted background exemption for package " + pkg
891                         + " and user " + userId);
892             final ApplicationInfo app;
893             try {
894                 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
895             } catch (PackageManager.NameNotFoundException e) {
896                 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
897                 // Ignore it - some apps on allow-in-data-usage-save are optional.
898                 continue;
899             }
900             if (!app.isPrivilegedApp()) {
901                 Slog.e(TAG, "addDefaultRestrictBackgroundAllowlistUidsUL(): "
902                         + "skipping non-privileged app  " + pkg);
903                 continue;
904             }
905             final int uid = UserHandle.getUid(userId, app.uid);
906             mDefaultRestrictBackgroundAllowlistUids.append(uid, true);
907             if (LOGD)
908                 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
909                         + "background allowlist. Revoked status: "
910                         + mRestrictBackgroundAllowlistRevokedUids.get(uid));
911             if (!mRestrictBackgroundAllowlistRevokedUids.get(uid)) {
912                 if (LOGD)
913                     Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
914                             + userId + ") to restrict background allowlist");
915                 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false);
916                 changed = true;
917             }
918         }
919         return changed;
920     }
921 
initService(CountDownLatch initCompleteSignal)922     private void initService(CountDownLatch initCompleteSignal) {
923         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
924         final int oldPriority = Process.getThreadPriority(Process.myTid());
925         try {
926             // Boost thread's priority during system server init
927             Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
928             if (!isBandwidthControlEnabled()) {
929                 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
930                 return;
931             }
932 
933             mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
934             mAppStandby = LocalServices.getService(AppStandbyInternal.class);
935             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
936 
937             synchronized (mUidRulesFirstLock) {
938                 synchronized (mNetworkPoliciesSecondLock) {
939                     updatePowerSaveWhitelistUL();
940                     mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
941                     mPowerManagerInternal.registerLowPowerModeObserver(
942                             new PowerManagerInternal.LowPowerModeListener() {
943                                 @Override
944                                 public int getServiceType() {
945                                     return ServiceType.NETWORK_FIREWALL;
946                                 }
947 
948                                 @Override
949                                 public void onLowPowerModeChanged(PowerSaveState result) {
950                                     final boolean enabled = result.batterySaverEnabled;
951                                     if (LOGD) {
952                                         Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
953                                     }
954                                     synchronized (mUidRulesFirstLock) {
955                                         if (mRestrictPower != enabled) {
956                                             mRestrictPower = enabled;
957                                             updateRulesForRestrictPowerUL();
958                                         }
959                                     }
960                                 }
961                             });
962                     mRestrictPower = mPowerManagerInternal.getLowPowerState(
963                             ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
964 
965                     mRestrictedModeObserver = new RestrictedModeObserver(mContext,
966                             enabled -> {
967                                 synchronized (mUidRulesFirstLock) {
968                                     mRestrictedNetworkingMode = enabled;
969                                     updateRestrictedModeAllowlistUL();
970                                 }
971                             });
972                     mRestrictedNetworkingMode = mRestrictedModeObserver.isRestrictedModeEnabled();
973 
974                     mSystemReady = true;
975 
976                     waitForAdminData();
977 
978                     // read policy from disk
979                     readPolicyAL();
980 
981                     // Update the restrictBackground if battery saver is turned on
982                     mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
983                     mRestrictBackgroundLowPowerMode = mPowerManagerInternal
984                             .getLowPowerState(ServiceType.DATA_SAVER).batterySaverEnabled;
985                     if (mRestrictBackgroundLowPowerMode && !mLoadedRestrictBackground) {
986                         mLoadedRestrictBackground = true;
987                     }
988                     mPowerManagerInternal.registerLowPowerModeObserver(
989                             new PowerManagerInternal.LowPowerModeListener() {
990                                 @Override
991                                 public int getServiceType() {
992                                     return ServiceType.DATA_SAVER;
993                                 }
994 
995                                 @Override
996                                 public void onLowPowerModeChanged(PowerSaveState result) {
997                                     synchronized (mUidRulesFirstLock) {
998                                         updateRestrictBackgroundByLowPowerModeUL(result);
999                                     }
1000                                 }
1001                             });
1002 
1003                     if (addDefaultRestrictBackgroundAllowlistUidsUL()) {
1004                         writePolicyAL();
1005                     }
1006 
1007                     setRestrictBackgroundUL(mLoadedRestrictBackground, "init_service");
1008                     updateRulesForGlobalChangeAL(false);
1009                     updateNotificationsNL();
1010                 }
1011             }
1012 
1013             try {
1014                 final int changes = ActivityManager.UID_OBSERVER_PROCSTATE
1015                         | ActivityManager.UID_OBSERVER_GONE
1016                         | ActivityManager.UID_OBSERVER_CAPABILITY;
1017                 mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes,
1018                         NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
1019                 mNetworkManager.registerObserver(mAlertObserver);
1020             } catch (RemoteException e) {
1021                 // ignored; both services live in system_server
1022             }
1023 
1024             // listen for changes to power save allowlist
1025             final IntentFilter whitelistFilter = new IntentFilter(
1026                     PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
1027             mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
1028 
1029             // watch for network interfaces to be claimed
1030             final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
1031             mContext.registerReceiver(mConnReceiver, connFilter, NETWORK_STACK, mHandler);
1032 
1033             // listen for package changes to update policy
1034             final IntentFilter packageFilter = new IntentFilter();
1035             packageFilter.addAction(ACTION_PACKAGE_ADDED);
1036             packageFilter.addDataScheme("package");
1037             mContext.registerReceiverForAllUsers(mPackageReceiver, packageFilter, null, mHandler);
1038 
1039             // listen for UID changes to update policy
1040             mContext.registerReceiverForAllUsers(
1041                     mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
1042 
1043             // listen for user changes to update policy
1044             final IntentFilter userFilter = new IntentFilter();
1045             userFilter.addAction(ACTION_USER_ADDED);
1046             userFilter.addAction(ACTION_USER_REMOVED);
1047             mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
1048 
1049             // listen for stats updated callbacks for interested network types.
1050             final Executor executor = new HandlerExecutor(mHandler);
1051             mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(),
1052                     0 /* thresholdBytes */, executor, mStatsCallback);
1053             mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(),
1054                     0 /* thresholdBytes */, executor, mStatsCallback);
1055 
1056             // Listen for snooze from notifications
1057             mContext.registerReceiver(mSnoozeReceiver,
1058                     new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler);
1059             mContext.registerReceiver(mSnoozeReceiver,
1060                     new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler);
1061 
1062             // listen for configured wifi networks to be loaded
1063             final IntentFilter wifiFilter =
1064                     new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
1065             mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler);
1066 
1067             // listen for carrier config changes to update data cycle information
1068             final IntentFilter carrierConfigFilter = new IntentFilter(
1069                     ACTION_CARRIER_CONFIG_CHANGED);
1070             mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
1071 
1072             // listen for meteredness changes
1073             mConnManager.registerNetworkCallback(
1074                     new NetworkRequest.Builder().build(), mNetworkCallback);
1075 
1076             mAppStandby.addListener(new NetPolicyAppIdleStateChangeListener());
1077             synchronized (mUidRulesFirstLock) {
1078                 updateRulesForAppIdleParoleUL();
1079             }
1080 
1081             // Listen for subscriber changes
1082             mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
1083                     new HandlerExecutor(mHandler),
1084                     new OnSubscriptionsChangedListener() {
1085                         @Override
1086                         public void onSubscriptionsChanged() {
1087                             updateNetworksInternal();
1088                         }
1089                     });
1090 
1091             // tell systemReady() that the service has been initialized
1092             initCompleteSignal.countDown();
1093         } finally {
1094             // Restore the default priority after init is done
1095             Process.setThreadPriority(oldPriority);
1096             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
1097         }
1098     }
1099 
networkScoreAndNetworkManagementServiceReady()1100     public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
1101         mNetworkManagerReady = true;
1102         final CountDownLatch initCompleteSignal = new CountDownLatch(1);
1103         mHandler.post(() -> initService(initCompleteSignal));
1104         return initCompleteSignal;
1105     }
1106 
systemReady(CountDownLatch initCompleteSignal)1107     public void systemReady(CountDownLatch initCompleteSignal) {
1108         // wait for initService to complete
1109         try {
1110             if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
1111                 throw new IllegalStateException("Service " + TAG +" init timeout");
1112             }
1113             mMultipathPolicyTracker.start();
1114         } catch (InterruptedException e) {
1115             Thread.currentThread().interrupt();
1116             throw new IllegalStateException("Service " + TAG + " init interrupted", e);
1117         }
1118     }
1119 
1120     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
1121         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
1122                 @ProcessCapability int capability) {
1123             synchronized (mUidStateCallbackInfos) {
1124                 UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid);
1125                 if (callbackInfo == null) {
1126                     callbackInfo = new UidStateCallbackInfo();
1127                     mUidStateCallbackInfos.put(uid, callbackInfo);
1128                 }
1129                 if (callbackInfo.procStateSeq == -1 || procStateSeq > callbackInfo.procStateSeq) {
1130                     callbackInfo.update(uid, procState, procStateSeq, capability);
1131                 }
1132                 if (!callbackInfo.isPending) {
1133                     mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo)
1134                             .sendToTarget();
1135                 }
1136             }
1137         }
1138 
1139         @Override public void onUidGone(int uid, boolean disabled) {
1140             mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
1141         }
1142 
1143         @Override public void onUidActive(int uid) {
1144         }
1145 
1146         @Override public void onUidIdle(int uid, boolean disabled) {
1147         }
1148 
1149         @Override public void onUidCachedChanged(int uid, boolean cached) {
1150         }
1151 
1152         @Override public void onUidProcAdjChanged(int uid) {
1153         }
1154     };
1155 
1156     private static final class UidStateCallbackInfo {
1157         public int uid;
1158         public int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
1159         public long procStateSeq = -1;
1160         @ProcessCapability
1161         public int capability;
1162         public boolean isPending;
1163 
update(int uid, int procState, long procStateSeq, int capability)1164         public void update(int uid, int procState, long procStateSeq, int capability) {
1165             this.uid = uid;
1166             this.procState = procState;
1167             this.procStateSeq = procStateSeq;
1168             this.capability = capability;
1169         }
1170     }
1171 
1172     final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
1173         @Override
1174         public void onReceive(Context context, Intent intent) {
1175             // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
1176             synchronized (mUidRulesFirstLock) {
1177                 updatePowerSaveWhitelistUL();
1178                 updateRulesForRestrictPowerUL();
1179                 updateRulesForAppIdleUL();
1180             }
1181         }
1182     };
1183 
1184     final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
1185         @Override
1186         public void onReceive(Context context, Intent intent) {
1187             // on background handler thread, and PACKAGE_ADDED is protected
1188 
1189             final String action = intent.getAction();
1190             final int uid = intent.getIntExtra(EXTRA_UID, -1);
1191             if (uid == -1) return;
1192 
1193             if (ACTION_PACKAGE_ADDED.equals(action)) {
1194                 // update rules for UID, since it might be subject to
1195                 // global background data policy
1196                 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
1197                 // Clear the cache for the app
1198                 synchronized (mUidRulesFirstLock) {
1199                     mInternetPermissionMap.delete(uid);
1200                     updateRestrictionRulesForUidUL(uid);
1201                 }
1202             }
1203         }
1204     };
1205 
1206     final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
1207         @Override
1208         public void onReceive(Context context, Intent intent) {
1209             // on background handler thread, and UID_REMOVED is protected
1210 
1211             final int uid = intent.getIntExtra(EXTRA_UID, -1);
1212             if (uid == -1) return;
1213 
1214             // remove any policy and update rules to clean up
1215             if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
1216             synchronized (mUidRulesFirstLock) {
1217                 onUidDeletedUL(uid);
1218                 synchronized (mNetworkPoliciesSecondLock) {
1219                     writePolicyAL();
1220                 }
1221             }
1222         }
1223     };
1224 
1225     final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1226         @Override
1227         public void onReceive(Context context, Intent intent) {
1228             // on background handler thread, and USER_ADDED and USER_REMOVED
1229             // broadcasts are protected
1230 
1231             final String action = intent.getAction();
1232             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1233             if (userId == -1) return;
1234 
1235             switch (action) {
1236                 case ACTION_USER_REMOVED:
1237                 case ACTION_USER_ADDED:
1238                     synchronized (mUidRulesFirstLock) {
1239                         // Remove any persistable state for the given user; both cleaning up after a
1240                         // USER_REMOVED, and one last check during USER_ADDED
1241                         removeUserStateUL(userId, true, false);
1242                         // Removing outside removeUserStateUL since that can also be called when
1243                         // user resets app preferences.
1244                         mMeteredRestrictedUids.remove(userId);
1245                         if (action == ACTION_USER_ADDED) {
1246                             // Add apps that are allowed by default.
1247                             addDefaultRestrictBackgroundAllowlistUidsUL(userId);
1248                         }
1249                         // Update global restrict for that user
1250                         synchronized (mNetworkPoliciesSecondLock) {
1251                             updateRulesForGlobalChangeAL(true);
1252                         }
1253                     }
1254                     break;
1255             }
1256         }
1257     };
1258 
1259     /**
1260      * Listener that watches for {@link NetworkStatsManager} updates, which
1261      * NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}.
1262      */
1263     private final StatsCallback mStatsCallback = new StatsCallback();
1264     private class StatsCallback extends NetworkStatsManager.UsageCallback {
1265         private boolean mIsAnyCallbackReceived = false;
1266 
1267         @Override
onThresholdReached(int networkType, String subscriberId)1268         public void onThresholdReached(int networkType, String subscriberId) {
1269             mIsAnyCallbackReceived = true;
1270 
1271             synchronized (mNetworkPoliciesSecondLock) {
1272                 updateNetworkRulesNL();
1273                 updateNetworkEnabledNL();
1274                 updateNotificationsNL();
1275             }
1276         }
1277 
1278         /**
1279          * Return whether any callback is received.
1280          * Used to determine if NetworkStatsService is ready.
1281          */
isAnyCallbackReceived()1282         public boolean isAnyCallbackReceived() {
1283             // Warning : threading for this member is broken. It should only be read
1284             // and written on the handler thread ; furthermore, the constructor
1285             // is called on a different thread, so this stops working if the default
1286             // value is not false or if this member ever goes back to false after
1287             // being set to true.
1288             // TODO : fix threading for this member.
1289             return mIsAnyCallbackReceived;
1290         }
1291     };
1292 
1293     /**
1294      * Receiver that watches for {@link Notification} control of
1295      * {@link NetworkPolicy#lastWarningSnooze}.
1296      */
1297     final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
1298         @Override
1299         public void onReceive(Context context, Intent intent) {
1300             // on background handler thread, and verified MANAGE_NETWORK_POLICY
1301             // permission above.
1302 
1303             final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
1304             if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) {
1305                 performSnooze(template, TYPE_WARNING);
1306             } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) {
1307                 performSnooze(template, TYPE_RAPID);
1308             }
1309         }
1310     };
1311 
1312     /**
1313      * Receiver that watches for {@link WifiConfiguration} to be loaded so that
1314      * we can perform upgrade logic. After initial upgrade logic, it updates
1315      * {@link #mMeteredIfaces} based on configuration changes.
1316      */
1317     final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
1318         @Override
1319         public void onReceive(Context context, Intent intent) {
1320             upgradeWifiMeteredOverride();
1321             // Only need to perform upgrade logic once
1322             mContext.unregisterReceiver(this);
1323         }
1324     };
1325 
updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue, Network network)1326     private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue,
1327             Network network) {
1328         final boolean lastValue = lastValues.get(network.getNetId(), false);
1329         final boolean changed = (lastValue != newValue)
1330                 || lastValues.indexOfKey(network.getNetId()) < 0;
1331         if (changed) {
1332             lastValues.put(network.getNetId(), newValue);
1333         }
1334         return changed;
1335     }
1336 
1337     @GuardedBy("mNetworkPoliciesSecondLock")
1338     private boolean updateNetworkToIfacesNL(int netId, @NonNull ArraySet<String> newIfaces) {
1339         // TODO: Add a facility SparseSetArray.contains(key) to return whether the key exists.
1340         final ArraySet<String> lastIfaces = mNetworkToIfaces.get(netId);
1341         final boolean changed = lastIfaces == null ? true : !lastIfaces.equals(newIfaces);
1342 
1343         if (changed) {
1344             // Changed on the same network should remove last ifaces and add new ifaces.
1345             // TODO: Add a facility SparseSetArray.put(key, value) for replacing the
1346             //       value for a given key.
1347             mNetworkToIfaces.remove(netId);
1348             for (String iface : newIfaces) {
1349                 mNetworkToIfaces.add(netId, iface);
1350             }
1351         }
1352         return changed;
1353     }
1354 
1355     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
1356         @Override
1357         public void onCapabilitiesChanged(@NonNull Network network,
1358                 @NonNull NetworkCapabilities networkCapabilities) {
1359 
1360             synchronized (mNetworkPoliciesSecondLock) {
1361                 final boolean newMetered = !networkCapabilities
1362                         .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1363                 final boolean meteredChanged = updateCapabilityChange(
1364                         mNetworkMetered, newMetered, network);
1365 
1366                 final boolean newRoaming = !networkCapabilities
1367                         .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
1368                 final boolean roamingChanged = updateCapabilityChange(
1369                         mNetworkRoaming, newRoaming, network);
1370 
1371                 if (meteredChanged || roamingChanged) {
1372                     mLogger.meterednessChanged(network.getNetId(), newMetered);
1373                     updateNetworkRulesNL();
1374                 }
1375             }
1376         }
1377 
1378         @Override
1379         public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties lp) {
1380             synchronized (mNetworkPoliciesSecondLock) {
1381                 final ArraySet<String> newIfaces = new ArraySet<>(lp.getAllInterfaceNames());
1382                 final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(),
1383                         newIfaces);
1384                 if (ifacesChanged) {
1385                     updateNetworkRulesNL();
1386                 }
1387             }
1388         }
1389 
1390         @Override
1391         public void onLost(@NonNull Network network) {
1392             synchronized (mNetworkPoliciesSecondLock) {
1393                 mNetworkToIfaces.remove(network.getNetId());
1394             }
1395         }
1396     };
1397 
1398     /**
1399      * Observer that watches for {@link INetworkManagementService} alerts.
1400      */
1401     final private INetworkManagementEventObserver mAlertObserver
1402             = new BaseNetworkObserver() {
1403         @Override
1404         public void limitReached(String limitName, String iface) {
1405             // only someone like NMS should be calling us
1406             NetworkStack.checkNetworkStackPermission(mContext);
1407 
1408             if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1409                 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
1410             }
1411         }
1412     };
1413 
1414     /**
1415      * Check {@link NetworkPolicy} against current {@link NetworkStatsManager}
1416      * to show visible notifications as needed.
1417      */
1418     @GuardedBy("mNetworkPoliciesSecondLock")
1419     void updateNotificationsNL() {
1420         if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
1421         Trace.traceBegin(TRACE_TAG_NETWORK, "updateNotificationsNL");
1422 
1423         // keep track of previously active notifications
1424         final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
1425         mActiveNotifs.clear();
1426 
1427         // TODO: when switching to kernel notifications, compute next future
1428         // cycle boundary to recompute notifications.
1429 
1430         // examine stats for each active policy
1431         final long now = mClock.millis();
1432         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1433             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1434             final int subId = findRelevantSubIdNL(policy.template);
1435 
1436             // ignore policies that aren't relevant to user
1437             if (subId == INVALID_SUBSCRIPTION_ID) continue;
1438             if (!policy.hasCycle()) continue;
1439 
1440             final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1441                     .cycleIterator(policy).next();
1442             final long cycleStart = cycle.first.toInstant().toEpochMilli();
1443             final long cycleEnd = cycle.second.toInstant().toEpochMilli();
1444             final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
1445 
1446             // Carrier might want to manage notifications themselves
1447             final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
1448             if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) {
1449                 if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false");
1450                 // Don't show notifications until we confirm that the loaded config is from an
1451                 // identified carrier, which may want to manage their own notifications. This method
1452                 // should be called every time the carrier config changes anyways, and there's no
1453                 // reason to alert if there isn't a carrier.
1454                 continue;
1455             }
1456 
1457             final boolean notifyWarning = getBooleanDefeatingNullable(config,
1458                     KEY_DATA_WARNING_NOTIFICATION_BOOL, true);
1459             final boolean notifyLimit = getBooleanDefeatingNullable(config,
1460                     KEY_DATA_LIMIT_NOTIFICATION_BOOL, true);
1461             final boolean notifyRapid = getBooleanDefeatingNullable(config,
1462                     KEY_DATA_RAPID_NOTIFICATION_BOOL, true);
1463 
1464             // Notify when data usage is over warning
1465             if (notifyWarning) {
1466                 if (policy.isOverWarning(totalBytes) && !policy.isOverLimit(totalBytes)) {
1467                     final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
1468                     if (!snoozedThisCycle) {
1469                         enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
1470                     }
1471                 }
1472             }
1473 
1474             // Notify when data usage is over limit
1475             if (notifyLimit) {
1476                 if (policy.isOverLimit(totalBytes)) {
1477                     final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
1478                     if (snoozedThisCycle) {
1479                         enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
1480                     } else {
1481                         enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
1482                         notifyOverLimitNL(policy.template);
1483                     }
1484                 } else {
1485                     notifyUnderLimitNL(policy.template);
1486                 }
1487             }
1488 
1489             // Warn if average usage over last 4 days is on track to blow pretty
1490             // far past the plan limits.
1491             if (notifyRapid && policy.limitBytes != LIMIT_DISABLED) {
1492                 final long recentDuration = TimeUnit.DAYS.toMillis(4);
1493                 final long recentStart = now - recentDuration;
1494                 final long recentEnd = now;
1495                 final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
1496 
1497                 final long cycleDuration = cycleEnd - cycleStart;
1498                 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
1499                 final long alertBytes = (policy.limitBytes * 3) / 2;
1500 
1501                 if (LOGD) {
1502                     Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected "
1503                             + projectedBytes + " alert " + alertBytes);
1504                 }
1505 
1506                 final boolean snoozedRecently = policy.lastRapidSnooze >= now
1507                         - DateUtils.DAY_IN_MILLIS;
1508                 if (projectedBytes > alertBytes && !snoozedRecently) {
1509                     enqueueNotification(policy, TYPE_RAPID, 0,
1510                             findRapidBlame(policy.template, recentStart, recentEnd));
1511                 }
1512             }
1513         }
1514 
1515         // cancel stale notifications that we didn't renew above
1516         for (int i = beforeNotifs.size()-1; i >= 0; i--) {
1517             final NotificationId notificationId = beforeNotifs.valueAt(i);
1518             if (!mActiveNotifs.contains(notificationId)) {
1519                 cancelNotification(notificationId);
1520             }
1521         }
1522 
1523         Trace.traceEnd(TRACE_TAG_NETWORK);
1524     }
1525 
1526     /**
1527      * Attempt to find a specific app to blame for rapid data usage during the
1528      * given time period.
1529      */
findRapidBlame(NetworkTemplate template, long start, long end)1530     private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
1531             long start, long end) {
1532         long totalBytes = 0;
1533         long maxBytes = 0;
1534         int maxUid = 0;
1535 
1536         // Skip if not ready. NetworkStatsService will block public API calls until it is
1537         // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
1538         if (!mStatsCallback.isAnyCallbackReceived()) return null;
1539 
1540         final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end);
1541         for (final NetworkStats.Bucket entry : stats) {
1542             final long bytes = entry.getRxBytes() + entry.getTxBytes();
1543             totalBytes += bytes;
1544             if (bytes > maxBytes) {
1545                 maxBytes = bytes;
1546                 maxUid = entry.getUid();
1547             }
1548         }
1549 
1550         // Only point blame if the majority of usage was done by a single app.
1551         // TODO: support shared UIDs
1552         if (maxBytes > 0 && maxBytes > totalBytes / 2) {
1553             final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
1554             if (packageNames != null && packageNames.length == 1) {
1555                 try {
1556                     return mContext.getPackageManager().getApplicationInfo(packageNames[0],
1557                             MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
1558                                     | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
1559                 } catch (NameNotFoundException ignored) {
1560                 }
1561             }
1562         }
1563 
1564         return null;
1565     }
1566 
1567     /**
1568      * Test if given {@link NetworkTemplate} is relevant to user based on
1569      * current device state, such as when
1570      * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
1571      * data connection status.
1572      *
1573      * @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no
1574      *         matching subId found.
1575      */
1576     @GuardedBy("mNetworkPoliciesSecondLock")
findRelevantSubIdNL(NetworkTemplate template)1577     private int findRelevantSubIdNL(NetworkTemplate template) {
1578         // Carrier template is relevant when any active subscriber matches
1579         for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1580             final int subId = mSubIdToSubscriberId.keyAt(i);
1581             final String subscriberId = mSubIdToSubscriberId.valueAt(i);
1582             final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
1583                     .setType(TYPE_MOBILE)
1584                     .setSubscriberId(subscriberId)
1585                     .setMetered(true)
1586                     .setDefaultNetwork(true)
1587                     .setSubId(subId).build();
1588             if (template.matches(probeIdent)) {
1589                 return subId;
1590             }
1591         }
1592         return INVALID_SUBSCRIPTION_ID;
1593     }
1594 
1595     /**
1596      * Notify that given {@link NetworkTemplate} is over
1597      * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1598      */
1599     @GuardedBy("mNetworkPoliciesSecondLock")
notifyOverLimitNL(NetworkTemplate template)1600     private void notifyOverLimitNL(NetworkTemplate template) {
1601         if (!mOverLimitNotified.contains(template)) {
1602             mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
1603             mOverLimitNotified.add(template);
1604         }
1605     }
1606 
1607     @GuardedBy("mNetworkPoliciesSecondLock")
notifyUnderLimitNL(NetworkTemplate template)1608     private void notifyUnderLimitNL(NetworkTemplate template) {
1609         mOverLimitNotified.remove(template);
1610     }
1611 
1612     /**
1613      * Show notification for combined {@link NetworkPolicy} and specific type,
1614      * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1615      */
enqueueNotification(NetworkPolicy policy, int type, long totalBytes, ApplicationInfo rapidBlame)1616     private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
1617             ApplicationInfo rapidBlame) {
1618         final NotificationId notificationId = new NotificationId(policy, type);
1619         final Notification.Builder builder =
1620                 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
1621         builder.setOnlyAlertOnce(true);
1622         builder.setWhen(0L);
1623         builder.setColor(mContext.getColor(
1624                 com.android.internal.R.color.system_notification_accent_color));
1625 
1626         final Resources res = mContext.getResources();
1627         final CharSequence title;
1628         final CharSequence body;
1629         switch (type) {
1630             case TYPE_WARNING: {
1631                 title = res.getText(R.string.data_usage_warning_title);
1632                 body = res.getString(R.string.data_usage_warning_body,
1633                         Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS));
1634 
1635                 builder.setSmallIcon(R.drawable.stat_notify_error);
1636 
1637                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template,
1638                         mContext.getPackageName());
1639                 builder.setDeleteIntent(PendingIntent.getBroadcast(
1640                         mContext, 0, snoozeIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1641 
1642                 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
1643                 // TODO: Resolve to single code path.
1644                 if (UserManager.isHeadlessSystemUserMode()) {
1645                     builder.setContentIntent(PendingIntent.getActivityAsUser(
1646                             mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE,
1647                             /* options= */ null, UserHandle.CURRENT));
1648                 } else {
1649                     builder.setContentIntent(PendingIntent.getActivity(
1650                             mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1651                 }
1652                 break;
1653             }
1654             case TYPE_LIMIT: {
1655                 switch (policy.template.getMatchRule()) {
1656                     case MATCH_CARRIER:
1657                     case MATCH_MOBILE:
1658                         title = res.getText(R.string.data_usage_mobile_limit_title);
1659                         break;
1660                     case MATCH_WIFI:
1661                         title = res.getText(R.string.data_usage_wifi_limit_title);
1662                         break;
1663                     default:
1664                         return;
1665                 }
1666                 body = res.getText(R.string.data_usage_limit_body);
1667 
1668                 builder.setOngoing(true);
1669                 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
1670 
1671                 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
1672                 // TODO: Resolve to single code path.
1673                 if (UserManager.isHeadlessSystemUserMode()) {
1674                     builder.setContentIntent(PendingIntent.getActivityAsUser(
1675                             mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE,
1676                             /* options= */ null, UserHandle.CURRENT));
1677                 } else {
1678                     builder.setContentIntent(PendingIntent.getActivity(
1679                             mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1680                 }
1681                 break;
1682             }
1683             case TYPE_LIMIT_SNOOZED: {
1684                 switch (policy.template.getMatchRule()) {
1685                     case MATCH_CARRIER:
1686                     case MATCH_MOBILE:
1687                         title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1688                         break;
1689                     case MATCH_WIFI:
1690                         title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1691                         break;
1692                     default:
1693                         return;
1694                 }
1695                 final long overBytes = totalBytes - policy.limitBytes;
1696                 body = res.getString(R.string.data_usage_limit_snoozed_body,
1697                         Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS));
1698 
1699                 builder.setOngoing(true);
1700                 builder.setSmallIcon(R.drawable.stat_notify_error);
1701                 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
1702 
1703                 final Intent intent = buildViewDataUsageIntent(res, policy.template);
1704                 // TODO: Resolve to single code path.
1705                 if (UserManager.isHeadlessSystemUserMode()) {
1706                     builder.setContentIntent(PendingIntent.getActivityAsUser(
1707                             mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE,
1708                             /* options= */ null, UserHandle.CURRENT));
1709                 } else {
1710                     builder.setContentIntent(PendingIntent.getActivity(
1711                             mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1712                 }
1713                 break;
1714             }
1715             case TYPE_RAPID: {
1716                 title = res.getText(R.string.data_usage_rapid_title);
1717                 if (rapidBlame != null) {
1718                     body = res.getString(R.string.data_usage_rapid_app_body,
1719                             rapidBlame.loadLabel(mContext.getPackageManager()));
1720                 } else {
1721                     body = res.getString(R.string.data_usage_rapid_body);
1722                 }
1723 
1724                 builder.setSmallIcon(R.drawable.stat_notify_error);
1725 
1726                 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template,
1727                         mContext.getPackageName());
1728                 builder.setDeleteIntent(PendingIntent.getBroadcast(
1729                         mContext, 0, snoozeIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1730 
1731                 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
1732                 // TODO: Resolve to single code path.
1733                 if (UserManager.isHeadlessSystemUserMode()) {
1734                     builder.setContentIntent(PendingIntent.getActivityAsUser(
1735                             mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE,
1736                             /* options= */ null, UserHandle.CURRENT));
1737                 } else {
1738                     builder.setContentIntent(PendingIntent.getActivity(
1739                             mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
1740                 }
1741                 break;
1742             }
1743             default: {
1744                 return;
1745             }
1746         }
1747 
1748         builder.setTicker(title);
1749         builder.setContentTitle(title);
1750         builder.setContentText(body);
1751         builder.setStyle(new Notification.BigTextStyle().bigText(body));
1752 
1753         mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
1754                 notificationId.getId(), builder.build(), UserHandle.ALL);
1755         mActiveNotifs.add(notificationId);
1756     }
1757 
cancelNotification(NotificationId notificationId)1758     private void cancelNotification(NotificationId notificationId) {
1759         mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(),
1760                 notificationId.getId());
1761     }
1762 
1763     /**
1764      * Receiver that watches for {@link IConnectivityManager} to claim network
1765      * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
1766      */
1767     private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
1768         @Override
1769         public void onReceive(Context context, Intent intent) {
1770             // on background handler thread, and verified NETWORK_STACK
1771             // permission above.
1772             updateNetworksInternal();
1773         }
1774     };
1775 
updateNetworksInternal()1776     private void updateNetworksInternal() {
1777         // Get all of our cross-process communication with telephony out of
1778         // the way before we acquire internal locks.
1779         updateSubscriptions();
1780 
1781         synchronized (mUidRulesFirstLock) {
1782             synchronized (mNetworkPoliciesSecondLock) {
1783                 ensureActiveCarrierPolicyAL();
1784                 normalizePoliciesNL();
1785                 updateNetworkEnabledNL();
1786                 updateNetworkRulesNL();
1787                 updateNotificationsNL();
1788             }
1789         }
1790     }
1791 
1792     @VisibleForTesting
updateNetworks()1793     void updateNetworks() throws InterruptedException {
1794         updateNetworksInternal();
1795         final CountDownLatch latch = new CountDownLatch(1);
1796         mHandler.post(() -> {
1797             latch.countDown();
1798         });
1799         latch.await(5, TimeUnit.SECONDS);
1800     }
1801 
1802     @VisibleForTesting
getHandlerForTesting()1803     Handler getHandlerForTesting() {
1804         return mHandler;
1805     }
1806 
1807     /**
1808      * Update carrier policies with data cycle information from {@link CarrierConfigManager}
1809      * if necessary.
1810      *
1811      * @param subId that has its associated NetworkPolicy updated if necessary
1812      * @return if any policies were updated
1813      */
1814     @GuardedBy("mNetworkPoliciesSecondLock")
maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId)1815     private boolean maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId) {
1816         if (LOGV) Slog.v(TAG, "maybeUpdateCarrierPolicyCycleAL()");
1817 
1818         // find and update the carrier NetworkPolicy for this subscriber id
1819         boolean policyUpdated = false;
1820         final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
1821                 .setType(TYPE_MOBILE)
1822                 .setSubscriberId(subscriberId)
1823                 .setMetered(true)
1824                 .setDefaultNetwork(true)
1825                 .setSubId(subId).build();
1826         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1827             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1828             if (template.matches(probeIdent)) {
1829                 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1830                 policyUpdated |= updateDefaultCarrierPolicyAL(subId, policy);
1831             }
1832         }
1833         return policyUpdated;
1834     }
1835 
1836     /**
1837      * Returns the cycle day that should be used for a carrier NetworkPolicy.
1838      *
1839      * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
1840      * to do so, it returns the fallback value.
1841      *
1842      * @param config The CarrierConfig to read the value from.
1843      * @param fallbackCycleDay to return if the CarrierConfig can't be read.
1844      * @return cycleDay to use in the carrier NetworkPolicy.
1845      */
1846     @VisibleForTesting
getCycleDayFromCarrierConfig(@ullable PersistableBundle config, int fallbackCycleDay)1847     int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
1848             int fallbackCycleDay) {
1849         if (config == null) {
1850             return fallbackCycleDay;
1851         }
1852         int cycleDay =
1853                 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1854         if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1855             return fallbackCycleDay;
1856         }
1857         // validate cycleDay value
1858         final Calendar cal = Calendar.getInstance();
1859         if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
1860                 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
1861             Slog.e(TAG, "Invalid date in "
1862                     + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
1863             return fallbackCycleDay;
1864         }
1865         return cycleDay;
1866     }
1867 
1868     /**
1869      * Returns the warning bytes that should be used for a carrier NetworkPolicy.
1870      *
1871      * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1872      * to do so, it returns the fallback value.
1873      *
1874      * @param config The CarrierConfig to read the value from.
1875      * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
1876      * @return warningBytes to use in the carrier NetworkPolicy.
1877      */
1878     @VisibleForTesting
getWarningBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackWarningBytes)1879     long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
1880             long fallbackWarningBytes) {
1881         if (config == null) {
1882             return fallbackWarningBytes;
1883         }
1884         long warningBytes =
1885                 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
1886 
1887         if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1888             return WARNING_DISABLED;
1889         } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1890             return getPlatformDefaultWarningBytes();
1891         } else if (warningBytes < 0) {
1892             Slog.e(TAG, "Invalid value in "
1893                     + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
1894                     + "non-negative value but got: " + warningBytes);
1895             return fallbackWarningBytes;
1896         }
1897 
1898         return warningBytes;
1899     }
1900 
1901     /**
1902      * Returns the limit bytes that should be used for a carrier NetworkPolicy.
1903      *
1904      * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1905      * to do so, it returns the fallback value.
1906      *
1907      * @param config The CarrierConfig to read the value from.
1908      * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
1909      * @return limitBytes to use in the carrier NetworkPolicy.
1910      */
1911     @VisibleForTesting
getLimitBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackLimitBytes)1912     long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
1913             long fallbackLimitBytes) {
1914         if (config == null) {
1915             return fallbackLimitBytes;
1916         }
1917         long limitBytes =
1918                 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
1919 
1920         if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1921             return LIMIT_DISABLED;
1922         } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1923             return getPlatformDefaultLimitBytes();
1924         } else if (limitBytes < 0) {
1925             Slog.e(TAG, "Invalid value in "
1926                     + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
1927                     + "non-negative value but got: " + limitBytes);
1928             return fallbackLimitBytes;
1929         }
1930         return limitBytes;
1931     }
1932 
1933     /**
1934      * Receiver that watches for {@link CarrierConfigManager} to be changed.
1935      */
1936     private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
1937         @Override
1938         public void onReceive(Context context, Intent intent) {
1939             // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
1940             // broadcast is protected and can't be spoofed. Runs on a background handler thread.
1941 
1942             if (!intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX)) {
1943                 return;
1944             }
1945             final int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
1946 
1947             // Get all of our cross-process communication with telephony out of
1948             // the way before we acquire internal locks.
1949             updateSubscriptions();
1950 
1951             synchronized (mUidRulesFirstLock) {
1952                 synchronized (mNetworkPoliciesSecondLock) {
1953                     final String subscriberId = mSubIdToSubscriberId.get(subId, null);
1954                     if (subscriberId != null) {
1955                         ensureActiveCarrierPolicyAL(subId, subscriberId);
1956                         maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
1957                     } else {
1958                         Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
1959                     }
1960 
1961                     // update network and notification rules, as the data cycle changed and it's
1962                     // possible that we should be triggering warnings/limits now
1963                     handleNetworkPoliciesUpdateAL(true);
1964                 }
1965             }
1966         }
1967     };
1968 
1969     /**
1970      * Handles all tasks that need to be run after a new network policy has been set, or an existing
1971      * one has been updated.
1972      *
1973      * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1974      *                                update.
1975      */
1976     @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies)1977     void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1978         if (shouldNormalizePolicies) {
1979             normalizePoliciesNL();
1980         }
1981         updateNetworkEnabledNL();
1982         updateNetworkRulesNL();
1983         updateNotificationsNL();
1984         writePolicyAL();
1985     }
1986 
1987     /**
1988      * Proactively control network data connections when they exceed
1989      * {@link NetworkPolicy#limitBytes}.
1990      */
1991     @GuardedBy("mNetworkPoliciesSecondLock")
updateNetworkEnabledNL()1992     void updateNetworkEnabledNL() {
1993         if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
1994         Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkEnabledNL");
1995 
1996         // TODO: reset any policy-disabled networks when any policy is removed
1997         // completely, which is currently rare case.
1998 
1999         final long startTime = mStatLogger.getTime();
2000 
2001         for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
2002             final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2003             // shortcut when policy has no limit
2004             if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
2005                 setNetworkTemplateEnabled(policy.template, true);
2006                 continue;
2007             }
2008 
2009             final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
2010                     .cycleIterator(policy).next();
2011             final long start = cycle.first.toInstant().toEpochMilli();
2012             final long end = cycle.second.toInstant().toEpochMilli();
2013             final long totalBytes = getTotalBytes(policy.template, start, end);
2014 
2015             // disable data connection when over limit and not snoozed
2016             final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
2017                     && policy.lastLimitSnooze < start;
2018             final boolean networkEnabled = !overLimitWithoutSnooze;
2019 
2020             setNetworkTemplateEnabled(policy.template, networkEnabled);
2021         }
2022 
2023         mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime);
2024         Trace.traceEnd(TRACE_TAG_NETWORK);
2025     }
2026 
2027     /**
2028      * Proactively disable networks that match the given
2029      * {@link NetworkTemplate}.
2030      */
2031     private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
2032         // Don't call setNetworkTemplateEnabledInner() directly because we may have a lock
2033         // held. Call it via the handler.
2034         mHandler.obtainMessage(MSG_SET_NETWORK_TEMPLATE_ENABLED, enabled ? 1 : 0, 0, template)
2035                 .sendToTarget();
2036     }
2037 
2038     private void setNetworkTemplateEnabledInner(NetworkTemplate template, boolean enabled) {
2039         // TODO: reach into ConnectivityManager to proactively disable bringing
2040         // up this network, since we know that traffic will be blocked.
2041 
2042         if (template.getMatchRule() == MATCH_MOBILE
2043                 || template.getMatchRule() == MATCH_CARRIER) {
2044             // If carrier data usage hits the limit or if the user resumes the data, we need to
2045             // notify telephony.
2046 
2047             // TODO: It needs to check if it matches the merged WIFI and notify to wifi module.
2048             final IntArray matchingSubIds = new IntArray();
2049             synchronized (mNetworkPoliciesSecondLock) {
2050                 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
2051                     final int subId = mSubIdToSubscriberId.keyAt(i);
2052                     final String subscriberId = mSubIdToSubscriberId.valueAt(i);
2053                     final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
2054                             .setType(TYPE_MOBILE)
2055                             .setSubscriberId(subscriberId)
2056                             .setMetered(true)
2057                             .setDefaultNetwork(true)
2058                             .setSubId(subId).build();
2059                     // Template is matched when subscriber id matches.
2060                     if (template.matches(probeIdent)) {
2061                         matchingSubIds.add(subId);
2062                     }
2063                 }
2064             }
2065 
2066             // Only talk with telephony outside of locks
2067             final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
2068             for (int i = 0; i < matchingSubIds.size(); i++) {
2069                 final int subId = matchingSubIds.get(i);
2070                 tm.createForSubscriptionId(subId).setPolicyDataEnabled(enabled);
2071             }
2072         }
2073     }
2074 
2075     /**
2076      * Collect all ifaces from a {@link NetworkStateSnapshot} into the given set.
2077      */
2078     private static void collectIfaces(ArraySet<String> ifaces, NetworkStateSnapshot snapshot) {
2079         ifaces.addAll(snapshot.getLinkProperties().getAllInterfaceNames());
2080     }
2081 
2082     /**
2083      * Examine all currently active subscriptions from
2084      * {@link SubscriptionManager#getActiveSubscriptionInfoList()} and update
2085      * internal data structures.
2086      * <p>
2087      * Callers <em>must not</em> hold any locks when this method called.
2088      */
2089     void updateSubscriptions() {
2090         if (LOGV) Slog.v(TAG, "updateSubscriptions()");
2091         Trace.traceBegin(TRACE_TAG_NETWORK, "updateSubscriptions");
2092 
2093         final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
2094         final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
2095         final List<SubscriptionInfo> subList = CollectionUtils.emptyIfNull(
2096                 sm.getActiveSubscriptionInfoList());
2097 
2098         final List<String[]> mergedSubscriberIdsList = new ArrayList();
2099         final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subList.size());
2100         final SparseArray<PersistableBundle> subIdToCarrierConfig =
2101                 new SparseArray<PersistableBundle>();
2102         for (final SubscriptionInfo sub : subList) {
2103             final int subId = sub.getSubscriptionId();
2104             final TelephonyManager tmSub = tm.createForSubscriptionId(subId);
2105             final String subscriberId = tmSub.getSubscriberId();
2106             if (!TextUtils.isEmpty(subscriberId)) {
2107                 subIdToSubscriberId.put(tmSub.getSubscriptionId(), subscriberId);
2108             } else {
2109                 Slog.wtf(TAG, "Missing subscriberId for subId " + tmSub.getSubscriptionId());
2110             }
2111 
2112             final String[] mergedSubscriberId = ArrayUtils.defeatNullable(
2113                     tmSub.getMergedImsisFromGroup());
2114             mergedSubscriberIdsList.add(mergedSubscriberId);
2115 
2116             final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
2117             if (config != null) {
2118                 subIdToCarrierConfig.put(subId, config);
2119             } else {
2120                 Slog.e(TAG, "Missing CarrierConfig for subId " + subId);
2121             }
2122         }
2123 
2124         synchronized (mNetworkPoliciesSecondLock) {
2125             mSubIdToSubscriberId.clear();
2126             for (int i = 0; i < subIdToSubscriberId.size(); i++) {
2127                 mSubIdToSubscriberId.put(subIdToSubscriberId.keyAt(i),
2128                         subIdToSubscriberId.valueAt(i));
2129             }
2130 
2131             mMergedSubscriberIds = mergedSubscriberIdsList;
2132 
2133             mSubIdToCarrierConfig.clear();
2134             for (int i = 0; i < subIdToCarrierConfig.size(); i++) {
2135                 mSubIdToCarrierConfig.put(subIdToCarrierConfig.keyAt(i),
2136                         subIdToCarrierConfig.valueAt(i));
2137             }
2138         }
2139 
2140         Trace.traceEnd(TRACE_TAG_NETWORK);
2141     }
2142 
2143     /**
2144      * Examine all connected {@link NetworkStateSnapshot}, looking for
2145      * {@link NetworkPolicy} that need to be enforced. When matches found, set
2146      * remaining quota based on usage cycle and historical stats.
2147      */
2148     @GuardedBy("mNetworkPoliciesSecondLock")
2149     void updateNetworkRulesNL() {
2150         if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
2151         Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
2152 
2153         final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshots();
2154 
2155         // First, generate identities of all connected networks so we can
2156         // quickly compare them against all defined policies below.
2157         mNetIdToSubId.clear();
2158         final ArrayMap<NetworkStateSnapshot, NetworkIdentity> identified = new ArrayMap<>();
2159         for (final NetworkStateSnapshot snapshot : snapshots) {
2160             final int subId = snapshot.getSubId();
2161             mNetIdToSubId.put(snapshot.getNetwork().getNetId(), subId);
2162 
2163             // Policies matched by NPMS only match by subscriber ID or by network ID.
2164             final NetworkIdentity ident = new NetworkIdentity.Builder()
2165                     .setNetworkStateSnapshot(snapshot).setDefaultNetwork(true).build();
2166             identified.put(snapshot, ident);
2167         }
2168 
2169         final ArraySet<String> newMeteredIfaces = new ArraySet<>();
2170         long lowestRule = Long.MAX_VALUE;
2171 
2172         // For every well-defined policy, compute remaining data based on
2173         // current cycle and historical stats, and push to kernel.
2174         final ArraySet<String> matchingIfaces = new ArraySet<>();
2175         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
2176            final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2177 
2178             // Collect all ifaces that match this policy
2179             matchingIfaces.clear();
2180             for (int j = identified.size() - 1; j >= 0; j--) {
2181                 if (policy.template.matches(identified.valueAt(j))) {
2182                     collectIfaces(matchingIfaces, identified.keyAt(j));
2183                 }
2184             }
2185 
2186             if (LOGD) {
2187                 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces);
2188             }
2189 
2190             final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
2191             final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
2192             long limitBytes = Long.MAX_VALUE;
2193             long warningBytes = Long.MAX_VALUE;
2194             if ((hasLimit || hasWarning) && policy.hasCycle()) {
2195                 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
2196                         .cycleIterator(policy).next();
2197                 final long start = cycle.first.toInstant().toEpochMilli();
2198                 final long end = cycle.second.toInstant().toEpochMilli();
2199                 final long totalBytes = getTotalBytes(policy.template, start, end);
2200 
2201                 // If the limit notification is not snoozed, the limit quota needs to be calculated.
2202                 if (hasLimit && policy.lastLimitSnooze < start) {
2203                     // remaining "quota" bytes are based on total usage in
2204                     // current cycle. kernel doesn't like 0-byte rules, so we
2205                     // set 1-byte quota and disable the radio later.
2206                     limitBytes = Math.max(1, policy.limitBytes - totalBytes);
2207                 }
2208 
2209                 // If the warning notification was snoozed by user, or the service already knows
2210                 // it is over warning bytes, doesn't need to calculate warning bytes.
2211                 if (hasWarning && policy.lastWarningSnooze < start
2212                         && !policy.isOverWarning(totalBytes)) {
2213                     warningBytes = Math.max(1, policy.warningBytes - totalBytes);
2214                 }
2215             }
2216 
2217             if (hasWarning || hasLimit || policy.metered) {
2218                 if (matchingIfaces.size() > 1) {
2219                     // TODO: switch to shared quota once NMS supports
2220                     Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
2221                 }
2222 
2223                 // Set the interface warning and limit. For interfaces which has no cycle,
2224                 // or metered with no policy quotas, or snoozed notification; we still need to put
2225                 // iptables rule hooks to restrict apps for data saver, so push really high quota.
2226                 // TODO: Push NetworkStatsProvider.QUOTA_UNLIMITED instead of Long.MAX_VALUE to
2227                 //  providers.
2228                 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
2229                     final String iface = matchingIfaces.valueAt(j);
2230                     setInterfaceQuotasAsync(iface, warningBytes, limitBytes);
2231                     newMeteredIfaces.add(iface);
2232                 }
2233             }
2234 
2235             // keep track of lowest warning or limit of active policies
2236             if (hasWarning && policy.warningBytes < lowestRule) {
2237                 lowestRule = policy.warningBytes;
2238             }
2239             if (hasLimit && policy.limitBytes < lowestRule) {
2240                 lowestRule = policy.limitBytes;
2241             }
2242         }
2243 
2244         // One final pass to catch any metered ifaces that don't have explicitly
2245         // defined policies; typically Wi-Fi networks.
2246         for (final NetworkStateSnapshot snapshot : snapshots) {
2247             if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)) {
2248                 matchingIfaces.clear();
2249                 collectIfaces(matchingIfaces, snapshot);
2250                 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
2251                     final String iface = matchingIfaces.valueAt(j);
2252                     if (!newMeteredIfaces.contains(iface)) {
2253                         setInterfaceQuotasAsync(iface, Long.MAX_VALUE, Long.MAX_VALUE);
2254                         newMeteredIfaces.add(iface);
2255                     }
2256                 }
2257             }
2258         }
2259 
2260         // Remove quota from any interfaces that are no longer metered.
2261         synchronized (mMeteredIfacesLock) {
2262             for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
2263                 final String iface = mMeteredIfaces.valueAt(i);
2264                 if (!newMeteredIfaces.contains(iface)) {
2265                     removeInterfaceQuotasAsync(iface);
2266                 }
2267             }
2268             mMeteredIfaces = newMeteredIfaces;
2269         }
2270 
2271         final ContentResolver cr = mContext.getContentResolver();
2272         final boolean quotaEnabled = Settings.Global.getInt(cr,
2273                 NETPOLICY_QUOTA_ENABLED, 1) != 0;
2274         final long quotaUnlimited = Settings.Global.getLong(cr,
2275                 NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
2276         final float quotaLimited = Settings.Global.getFloat(cr,
2277                 NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
2278 
2279         // Finally, calculate our opportunistic quotas
2280         mSubscriptionOpportunisticQuota.clear();
2281         for (final NetworkStateSnapshot snapshot : snapshots) {
2282             if (!quotaEnabled) continue;
2283             if (snapshot.getNetwork() == null) continue;
2284             final int subId = getSubIdLocked(snapshot.getNetwork());
2285             if (subId == INVALID_SUBSCRIPTION_ID) continue;
2286             final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
2287             if (plan == null) continue;
2288 
2289             final long quotaBytes;
2290             final long limitBytes = plan.getDataLimitBytes();
2291             if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
2292                 // Clamp to 0 when roaming
2293                 quotaBytes = 0;
2294             } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
2295                 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
2296             } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
2297                 // Unlimited data; let's use 20MiB/day (600MiB/month)
2298                 quotaBytes = quotaUnlimited;
2299             } else {
2300                 // Limited data; let's only use 10% of remaining budget
2301                 final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
2302                 final long start = cycle.getLower().toInstant().toEpochMilli();
2303                 final long end = cycle.getUpper().toInstant().toEpochMilli();
2304                 final Instant now = mClock.instant();
2305                 final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
2306                         .truncatedTo(ChronoUnit.DAYS)
2307                         .toInstant().toEpochMilli();
2308                 final String subscriberId = snapshot.getSubscriberId();
2309                 final long totalBytes = subscriberId == null
2310                         ? 0 : getTotalBytes(
2311                                 buildTemplateCarrierMetered(subscriberId), start, startOfDay);
2312                 final long remainingBytes = limitBytes - totalBytes;
2313                 // Number of remaining days including current day
2314                 final long remainingDays =
2315                         1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
2316 
2317                 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
2318             }
2319 
2320             mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
2321         }
2322 
2323         final String[] meteredIfaces;
2324         synchronized (mMeteredIfacesLock) {
2325             meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
2326         }
2327         mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
2328 
2329         mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
2330 
2331         Trace.traceEnd(TRACE_TAG_NETWORK);
2332     }
2333 
2334     /**
2335      * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
2336      * have at least a default carrier policy defined.
2337      */
2338     @GuardedBy("mNetworkPoliciesSecondLock")
2339     private void ensureActiveCarrierPolicyAL() {
2340         if (LOGV) Slog.v(TAG, "ensureActiveCarrierPolicyAL()");
2341         if (mSuppressDefaultPolicy) return;
2342 
2343         for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
2344             final int subId = mSubIdToSubscriberId.keyAt(i);
2345             final String subscriberId = mSubIdToSubscriberId.valueAt(i);
2346 
2347             ensureActiveCarrierPolicyAL(subId, subscriberId);
2348         }
2349     }
2350 
2351     /**
2352      * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
2353      * have at least a default carrier policy defined.
2354      *
2355      * @param subId to build a default policy for
2356      * @param subscriberId that we check for an existing policy
2357      * @return true if a carrier network policy was added, or false one already existed.
2358      */
2359     @GuardedBy("mNetworkPoliciesSecondLock")
2360     private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) {
2361         // Poke around to see if we already have a policy
2362         final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
2363                 .setType(TYPE_MOBILE)
2364                 .setSubscriberId(subscriberId)
2365                 .setMetered(true)
2366                 .setDefaultNetwork(true)
2367                 .setSubId(subId).build();
2368         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
2369             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
2370             if (template.matches(probeIdent)) {
2371                 if (LOGD) {
2372                     Slog.d(TAG, "Found template " + template + " which matches subscriber "
2373                             + NetworkIdentityUtils.scrubSubscriberId(subscriberId));
2374                 }
2375                 return false;
2376             }
2377         }
2378 
2379         Slog.i(TAG, "No policy for subscriber "
2380                 + NetworkIdentityUtils.scrubSubscriberId(subscriberId)
2381                 + "; generating default policy");
2382         final NetworkPolicy policy = buildDefaultCarrierPolicy(subId, subscriberId);
2383         addNetworkPolicyAL(policy);
2384         return true;
2385     }
2386 
2387     private long getPlatformDefaultWarningBytes() {
2388         final int dataWarningConfig = mContext.getResources().getInteger(
2389                 com.android.internal.R.integer.config_networkPolicyDefaultWarning);
2390         if (dataWarningConfig == WARNING_DISABLED) {
2391             return WARNING_DISABLED;
2392         } else {
2393             return DataUnit.MEBIBYTES.toBytes(dataWarningConfig);
2394         }
2395     }
2396 
2397     private long getPlatformDefaultLimitBytes() {
2398         return LIMIT_DISABLED;
2399     }
2400 
2401     @VisibleForTesting
2402     NetworkPolicy buildDefaultCarrierPolicy(int subId, String subscriberId) {
2403         final NetworkTemplate template = buildTemplateCarrierMetered(subscriberId);
2404         final RecurrenceRule cycleRule = NetworkPolicy
2405                 .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
2406         final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
2407                 getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(),
2408                 SNOOZE_NEVER, SNOOZE_NEVER, true, true);
2409         synchronized (mUidRulesFirstLock) {
2410             synchronized (mNetworkPoliciesSecondLock) {
2411                 updateDefaultCarrierPolicyAL(subId, policy);
2412             }
2413         }
2414         return policy;
2415     }
2416 
2417     /**
2418      * Template to match all metered carrier networks with the given IMSI.
2419      *
2420      * @hide
2421      */
2422     public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) {
2423         Objects.requireNonNull(subscriberId);
2424         return new NetworkTemplate.Builder(MATCH_CARRIER)
2425                 .setSubscriberIds(Set.of(subscriberId))
2426                 .setMeteredness(METERED_YES).build();
2427     }
2428 
2429     /**
2430      * Update the given {@link NetworkPolicy} based on any carrier-provided
2431      * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}.
2432      * Leaves policy untouched if the user has modified it.
2433      *
2434      * @return if the policy was modified
2435      */
2436     @GuardedBy("mNetworkPoliciesSecondLock")
2437     private boolean updateDefaultCarrierPolicyAL(int subId, NetworkPolicy policy) {
2438         if (!policy.inferred) {
2439             if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
2440             return false;
2441         }
2442 
2443         final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
2444                 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
2445                 policy.lastLimitSnooze, policy.metered, policy.inferred);
2446 
2447         final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
2448         if (!ArrayUtils.isEmpty(plans)) {
2449             final SubscriptionPlan plan = plans[0];
2450             policy.cycleRule = plan.getCycleRule();
2451             final long planLimitBytes = plan.getDataLimitBytes();
2452             if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
2453                 policy.warningBytes = getPlatformDefaultWarningBytes();
2454                 policy.limitBytes = getPlatformDefaultLimitBytes();
2455             } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
2456                 policy.warningBytes = NetworkPolicy.WARNING_DISABLED;
2457                 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2458             } else {
2459                 policy.warningBytes = (planLimitBytes * 9) / 10;
2460                 switch (plan.getDataLimitBehavior()) {
2461                     case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED:
2462                     case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED:
2463                         policy.limitBytes = planLimitBytes;
2464                         break;
2465                     default:
2466                         policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2467                         break;
2468                 }
2469             }
2470         } else {
2471             final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
2472             final int currentCycleDay;
2473             if (policy.cycleRule.isMonthly()) {
2474                 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
2475             } else {
2476                 currentCycleDay = NetworkPolicy.CYCLE_NONE;
2477             }
2478             final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
2479             policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
2480             policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes);
2481             policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes);
2482         }
2483 
2484         if (policy.equals(original)) {
2485             return false;
2486         } else {
2487             Slog.d(TAG, "Updated " + original + " to " + policy);
2488             return true;
2489         }
2490     }
2491 
2492     @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
2493     private void readPolicyAL() {
2494         if (LOGV) Slog.v(TAG, "readPolicyAL()");
2495 
2496         // clear any existing policy and read from disk
2497         mNetworkPolicy.clear();
2498         mSubscriptionPlans.clear();
2499         mSubscriptionPlansOwner.clear();
2500         mUidPolicy.clear();
2501 
2502         FileInputStream fis = null;
2503         try {
2504             fis = mPolicyFile.openRead();
2505             final TypedXmlPullParser in = Xml.resolvePullParser(fis);
2506 
2507              // Must save the <restrict-background> tags and convert them to <uid-policy> later,
2508              // to skip UIDs that were explicitly denied.
2509             final SparseBooleanArray restrictBackgroundAllowedUids = new SparseBooleanArray();
2510 
2511             int type;
2512             int version = VERSION_INIT;
2513             boolean insideAllowlist = false;
2514             while ((type = in.next()) != END_DOCUMENT) {
2515                 final String tag = in.getName();
2516                 if (type == START_TAG) {
2517                     if (TAG_POLICY_LIST.equals(tag)) {
2518                         final boolean oldValue = mRestrictBackground;
2519                         version = readIntAttribute(in, ATTR_VERSION);
2520                         mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
2521                                 && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
2522                     } else if (TAG_NETWORK_POLICY.equals(tag)) {
2523                         int templateType = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
2524                         final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
2525                         final String networkId;
2526                         final int subscriberIdMatchRule;
2527                         final int templateMeteredness;
2528                         if (version >= VERSION_ADDED_NETWORK_ID) {
2529                             networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
2530                         } else {
2531                             networkId = null;
2532                         }
2533 
2534                         if (version >= VERSION_SUPPORTED_CARRIER_USAGE) {
2535                             subscriberIdMatchRule = readIntAttribute(in,
2536                                     ATTR_SUBSCRIBER_ID_MATCH_RULE);
2537                             templateMeteredness = readIntAttribute(in, ATTR_TEMPLATE_METERED);
2538 
2539                         } else {
2540                             subscriberIdMatchRule =
2541                                     NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
2542                             if (templateType == MATCH_MOBILE) {
2543                                 Log.d(TAG, "Update template match rule from mobile to carrier and"
2544                                         + " force to metered");
2545                                 templateType = MATCH_CARRIER;
2546                                 templateMeteredness = METERED_YES;
2547                             } else {
2548                                 templateMeteredness = METERED_ALL;
2549                             }
2550                         }
2551                         final RecurrenceRule cycleRule;
2552                         if (version >= VERSION_ADDED_CYCLE) {
2553                             final String start = readStringAttribute(in, ATTR_CYCLE_START);
2554                             final String end = readStringAttribute(in, ATTR_CYCLE_END);
2555                             final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2556                             cycleRule = new RecurrenceRule(
2557                                     RecurrenceRule.convertZonedDateTime(start),
2558                                     RecurrenceRule.convertZonedDateTime(end),
2559                                     RecurrenceRule.convertPeriod(period));
2560                         } else {
2561                             final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
2562                             final String cycleTimezone;
2563                             if (version >= VERSION_ADDED_TIMEZONE) {
2564                                 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
2565                             } else {
2566                                 cycleTimezone = "UTC";
2567                             }
2568                             cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone));
2569                         }
2570                         final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
2571                         final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
2572                         final long lastLimitSnooze;
2573                         if (version >= VERSION_SPLIT_SNOOZE) {
2574                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
2575                         } else if (version >= VERSION_ADDED_SNOOZE) {
2576                             lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
2577                         } else {
2578                             lastLimitSnooze = SNOOZE_NEVER;
2579                         }
2580                         final boolean metered;
2581                         if (version >= VERSION_ADDED_METERED) {
2582                             metered = readBooleanAttribute(in, ATTR_METERED);
2583                         } else {
2584                             switch (templateType) {
2585                                 case MATCH_MOBILE:
2586                                     metered = true;
2587                                     break;
2588                                 default:
2589                                     metered = false;
2590                             }
2591                         }
2592                         final long lastWarningSnooze;
2593                         if (version >= VERSION_SPLIT_SNOOZE) {
2594                             lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
2595                         } else {
2596                             lastWarningSnooze = SNOOZE_NEVER;
2597                         }
2598                         final boolean inferred;
2599                         if (version >= VERSION_ADDED_INFERRED) {
2600                             inferred = readBooleanAttribute(in, ATTR_INFERRED);
2601                         } else {
2602                             inferred = false;
2603                         }
2604                         final NetworkTemplate.Builder builder =
2605                                 new NetworkTemplate.Builder(templateType)
2606                                         .setMeteredness(templateMeteredness);
2607                         if (subscriberIdMatchRule
2608                                 == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT) {
2609                             final ArraySet<String> ids = new ArraySet<>();
2610                             ids.add(subscriberId);
2611                             builder.setSubscriberIds(ids);
2612                         }
2613                         if (networkId != null) {
2614                             builder.setWifiNetworkKeys(Set.of(networkId));
2615                         }
2616                         final NetworkTemplate template = builder.build();
2617                         if (NetworkPolicy.isTemplatePersistable(template)) {
2618                             mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
2619                                     warningBytes, limitBytes, lastWarningSnooze,
2620                                     lastLimitSnooze, metered, inferred));
2621                         }
2622                     } else if (TAG_UID_POLICY.equals(tag)) {
2623                         final int uid = readIntAttribute(in, ATTR_UID);
2624                         final int policy = readIntAttribute(in, ATTR_POLICY);
2625 
2626                         if (UserHandle.isApp(uid)) {
2627                             setUidPolicyUncheckedUL(uid, policy, false);
2628                         } else {
2629                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
2630                         }
2631                     } else if (TAG_APP_POLICY.equals(tag)) {
2632                         final int appId = readIntAttribute(in, ATTR_APP_ID);
2633                         final int policy = readIntAttribute(in, ATTR_POLICY);
2634 
2635                         // TODO: set for other users during upgrade
2636                         // app policy is deprecated so this is only used in pre system user split.
2637                         final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
2638                         if (UserHandle.isApp(uid)) {
2639                             setUidPolicyUncheckedUL(uid, policy, false);
2640                         } else {
2641                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
2642                         }
2643                     } else if (TAG_WHITELIST.equals(tag)) {
2644                         insideAllowlist = true;
2645                     } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) {
2646                         final int uid = readIntAttribute(in, ATTR_UID);
2647                         restrictBackgroundAllowedUids.append(uid, true);
2648                     } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) {
2649                         final int uid = readIntAttribute(in, ATTR_UID);
2650                         mRestrictBackgroundAllowlistRevokedUids.put(uid, true);
2651                     }
2652                 } else if (type == END_TAG) {
2653                     if (TAG_WHITELIST.equals(tag)) {
2654                         insideAllowlist = false;
2655                     }
2656 
2657                 }
2658             }
2659 
2660             final int size = restrictBackgroundAllowedUids.size();
2661             for (int i = 0; i < size; i++) {
2662                 final int uid = restrictBackgroundAllowedUids.keyAt(i);
2663                 final int policy = mUidPolicy.get(uid, POLICY_NONE);
2664                 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid + " because its policy is " + uidPoliciesToString(policy))2665                     Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid
2666                             + " because its policy is " + uidPoliciesToString(policy));
2667                     continue;
2668                 }
2669                 if (UserHandle.isApp(uid)) {
2670                     final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
2671                     if (LOGV)
Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy))2672                         Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
setUidPolicyUncheckedUL(uid, newPolicy, false)2673                     setUidPolicyUncheckedUL(uid, newPolicy, false);
2674                 } else {
Slog.w(TAG, "unable to update policy on UID " + uid)2675                     Slog.w(TAG, "unable to update policy on UID " + uid);
2676                 }
2677             }
2678 
2679         } catch (FileNotFoundException e) {
2680             // missing policy is okay, probably first boot
2681             upgradeDefaultBackgroundDataUL();
2682         } catch (Exception e) {
2683             Log.wtf(TAG, "problem reading network policy", e);
2684         } finally {
2685             IoUtils.closeQuietly(fis);
2686         }
2687     }
2688 
2689     /**
2690      * Upgrade legacy background data flags, notifying listeners of one last
2691      * change to always-true.
2692      */
2693     private void upgradeDefaultBackgroundDataUL() {
2694         // This method is only called when we're unable to find the network policy flag, which
2695         // usually happens on first boot of a new device and not one that has received an OTA.
2696 
2697         // Seed from the default value configured for this device.
2698         mLoadedRestrictBackground = Settings.Global.getInt(
2699                 mContext.getContentResolver(), Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 0) == 1;
2700 
2701         // NOTE: We used to read the legacy setting here :
2702         //
2703         // final int legacyFlagValue = Settings.Secure.getInt(
2704         //        mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..);
2705         //
2706         // This is no longer necessary because we will never upgrade directly from Gingerbread
2707         // to O+. Devices upgrading from ICS onwards to O will have a netpolicy.xml file that
2708         // contains the correct value that we will continue to use.
2709     }
2710 
2711     /**
2712      * Perform upgrade step of moving any user-defined meterness overrides over
2713      * into {@link WifiConfiguration}.
2714      */
2715     private void upgradeWifiMeteredOverride() {
2716         final ArrayMap<String, Boolean> wifiNetworkKeys = new ArrayMap<>();
2717         synchronized (mNetworkPoliciesSecondLock) {
2718             for (int i = 0; i < mNetworkPolicy.size();) {
2719                 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2720                 if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
2721                         && !policy.inferred) {
2722                     mNetworkPolicy.removeAt(i);
2723                     final Set<String> keys = policy.template.getWifiNetworkKeys();
2724                     wifiNetworkKeys.put(keys.isEmpty() ? null : keys.iterator().next(),
2725                             policy.metered);
2726                 } else {
2727                     i++;
2728                 }
2729             }
2730         }
2731 
2732         if (wifiNetworkKeys.isEmpty()) {
2733             return;
2734         }
2735         final WifiManager wm = mContext.getSystemService(WifiManager.class);
2736         final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2737         for (int i = 0; i < configs.size(); ++i) {
2738             final WifiConfiguration config = configs.get(i);
2739             for (String key : config.getAllNetworkKeys()) {
2740                 final Boolean metered = wifiNetworkKeys.get(key);
2741                 if (metered != null) {
2742                     Slog.d(TAG, "Found network " + key + "; upgrading metered hint");
2743                     config.meteredOverride = metered
2744                             ? WifiConfiguration.METERED_OVERRIDE_METERED
2745                             : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
2746                     wm.updateNetwork(config);
2747                     break;
2748                 }
2749             }
2750         }
2751 
2752         synchronized (mUidRulesFirstLock) {
2753             synchronized (mNetworkPoliciesSecondLock) {
2754                 writePolicyAL();
2755             }
2756         }
2757     }
2758 
2759     @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
2760     void writePolicyAL() {
2761         if (LOGV) Slog.v(TAG, "writePolicyAL()");
2762 
2763         FileOutputStream fos = null;
2764         try {
2765             fos = mPolicyFile.startWrite();
2766 
2767             TypedXmlSerializer out = Xml.resolveSerializer(fos);
2768             out.startDocument(null, true);
2769 
2770             out.startTag(null, TAG_POLICY_LIST);
2771             writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
2772             writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
2773 
2774             // write all known network policies
2775             for (int i = 0; i < mNetworkPolicy.size(); i++) {
2776                 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2777                 final NetworkTemplate template = policy.template;
2778                 if (!NetworkPolicy.isTemplatePersistable(template)) continue;
2779 
2780                 out.startTag(null, TAG_NETWORK_POLICY);
2781                 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
2782                 final String subscriberId = template.getSubscriberIds().isEmpty() ? null
2783                         : template.getSubscriberIds().iterator().next();
2784                 if (subscriberId != null) {
2785                     out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
2786                 }
2787                 final int subscriberIdMatchRule = template.getSubscriberIds().isEmpty()
2788                         ? NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
2789                         : NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
2790                 writeIntAttribute(out, ATTR_SUBSCRIBER_ID_MATCH_RULE, subscriberIdMatchRule);
2791                 if (!template.getWifiNetworkKeys().isEmpty()) {
2792                     out.attribute(null, ATTR_NETWORK_ID,
2793                             template.getWifiNetworkKeys().iterator().next());
2794                 }
2795                 writeIntAttribute(out, ATTR_TEMPLATE_METERED,
2796                         template.getMeteredness());
2797                 writeStringAttribute(out, ATTR_CYCLE_START,
2798                         RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
2799                 writeStringAttribute(out, ATTR_CYCLE_END,
2800                         RecurrenceRule.convertZonedDateTime(policy.cycleRule.end));
2801                 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2802                         RecurrenceRule.convertPeriod(policy.cycleRule.period));
2803                 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
2804                 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
2805                 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
2806                 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
2807                 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
2808                 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
2809                 out.endTag(null, TAG_NETWORK_POLICY);
2810             }
2811 
2812             // write all known uid policies
2813             for (int i = 0; i < mUidPolicy.size(); i++) {
2814                 final int uid = mUidPolicy.keyAt(i);
2815                 final int policy = mUidPolicy.valueAt(i);
2816 
2817                 // skip writing empty policies
2818                 if (policy == POLICY_NONE) continue;
2819 
2820                 out.startTag(null, TAG_UID_POLICY);
2821                 writeIntAttribute(out, ATTR_UID, uid);
2822                 writeIntAttribute(out, ATTR_POLICY, policy);
2823                 out.endTag(null, TAG_UID_POLICY);
2824             }
2825 
2826             out.endTag(null, TAG_POLICY_LIST);
2827 
2828             // write all allowlists
2829             out.startTag(null, TAG_WHITELIST);
2830 
2831             // revoked restrict background allowlist
2832             int size = mRestrictBackgroundAllowlistRevokedUids.size();
2833             for (int i = 0; i < size; i++) {
2834                 final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i);
2835                 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2836                 writeIntAttribute(out, ATTR_UID, uid);
2837                 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2838             }
2839 
2840             out.endTag(null, TAG_WHITELIST);
2841 
2842             out.endDocument();
2843 
2844             mPolicyFile.finishWrite(fos);
2845         } catch (IOException e) {
2846             if (fos != null) {
2847                 mPolicyFile.failWrite(fos);
2848             }
2849         }
2850     }
2851 
2852     @Override
2853     public void setUidPolicy(int uid, int policy) {
2854         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2855 
2856         if (!UserHandle.isApp(uid)) {
2857             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2858         }
2859         synchronized (mUidRulesFirstLock) {
2860             final long token = Binder.clearCallingIdentity();
2861             try {
2862                 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2863                 if (oldPolicy != policy) {
2864                     setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2865                     mLogger.uidPolicyChanged(uid, oldPolicy, policy);
2866                 }
2867             } finally {
2868                 Binder.restoreCallingIdentity(token);
2869             }
2870         }
2871     }
2872 
2873     @Override
2874     public void addUidPolicy(int uid, int policy) {
2875         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2876 
2877         if (!UserHandle.isApp(uid)) {
2878             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2879         }
2880 
2881         synchronized (mUidRulesFirstLock) {
2882             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2883             policy |= oldPolicy;
2884             if (oldPolicy != policy) {
2885                 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2886                 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
2887             }
2888         }
2889     }
2890 
2891     @Override
2892     public void removeUidPolicy(int uid, int policy) {
2893         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2894 
2895         if (!UserHandle.isApp(uid)) {
2896             throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2897         }
2898 
2899         synchronized (mUidRulesFirstLock) {
2900             final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2901             policy = oldPolicy & ~policy;
2902             if (oldPolicy != policy) {
2903                 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2904                 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
2905             }
2906         }
2907     }
2908 
2909     @GuardedBy("mUidRulesFirstLock")
2910     private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
2911         setUidPolicyUncheckedUL(uid, policy, false);
2912 
2913         final boolean notifyApp;
2914         if (!isUidValidForAllowlistRulesUL(uid)) {
2915             notifyApp = false;
2916         } else {
2917             final boolean wasDenied = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
2918             final boolean isDenied = policy == POLICY_REJECT_METERED_BACKGROUND;
2919             final boolean wasAllowed = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
2920             final boolean isAllowed = policy == POLICY_ALLOW_METERED_BACKGROUND;
2921             final boolean wasBlocked = wasDenied || (mRestrictBackground && !wasAllowed);
2922             final boolean isBlocked = isDenied || (mRestrictBackground && !isAllowed);
2923             if ((wasAllowed && (!isAllowed || isDenied))
2924                     && mDefaultRestrictBackgroundAllowlistUids.get(uid)
2925                     && !mRestrictBackgroundAllowlistRevokedUids.get(uid)) {
2926                 if (LOGD)
2927                     Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background allowlist");
2928                 mRestrictBackgroundAllowlistRevokedUids.append(uid, true);
2929             }
2930             notifyApp = wasBlocked != isBlocked;
2931         }
2932         mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2933                 .sendToTarget();
2934         if (persist) {
2935             synchronized (mNetworkPoliciesSecondLock) {
2936                 writePolicyAL();
2937             }
2938         }
2939     }
2940 
2941     @GuardedBy("mUidRulesFirstLock")
2942     private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
2943         if (policy == POLICY_NONE) {
2944             mUidPolicy.delete(uid);
2945         } else {
2946             mUidPolicy.put(uid, policy);
2947         }
2948 
2949         // uid policy changed, recompute rules and persist policy.
2950         updateRulesForDataUsageRestrictionsUL(uid);
2951         if (persist) {
2952             synchronized (mNetworkPoliciesSecondLock) {
2953                 writePolicyAL();
2954             }
2955         }
2956     }
2957 
2958     @Override
2959     public int getUidPolicy(int uid) {
2960         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2961 
2962         synchronized (mUidRulesFirstLock) {
2963             return mUidPolicy.get(uid, POLICY_NONE);
2964         }
2965     }
2966 
2967     @Override
2968     public int[] getUidsWithPolicy(int policy) {
2969         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2970 
2971         int[] uids = new int[0];
2972         synchronized (mUidRulesFirstLock) {
2973             for (int i = 0; i < mUidPolicy.size(); i++) {
2974                 final int uid = mUidPolicy.keyAt(i);
2975                 final int uidPolicy = mUidPolicy.valueAt(i);
2976                 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
2977                         (uidPolicy & policy) != 0) {
2978                     uids = appendInt(uids, uid);
2979                 }
2980             }
2981         }
2982         return uids;
2983     }
2984 
2985     /**
2986      * Removes any persistable state associated with given {@link UserHandle}, persisting
2987      * if any changes that are made.
2988      */
2989     @GuardedBy("mUidRulesFirstLock")
2990     boolean removeUserStateUL(int userId, boolean writePolicy, boolean updateGlobalRules) {
2991 
2992         mLogger.removingUserState(userId);
2993         boolean changed = false;
2994 
2995         // Remove entries from revoked default restricted background UID allowlist
2996         for (int i = mRestrictBackgroundAllowlistRevokedUids.size() - 1; i >= 0; i--) {
2997             final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i);
2998             if (UserHandle.getUserId(uid) == userId) {
2999                 mRestrictBackgroundAllowlistRevokedUids.removeAt(i);
3000                 changed = true;
3001             }
3002         }
3003 
3004         // Remove associated UID policies
3005         int[] uids = new int[0];
3006         for (int i = 0; i < mUidPolicy.size(); i++) {
3007             final int uid = mUidPolicy.keyAt(i);
3008             if (UserHandle.getUserId(uid) == userId) {
3009                 uids = appendInt(uids, uid);
3010             }
3011         }
3012 
3013         if (uids.length > 0) {
3014             for (int uid : uids) {
3015                 mUidPolicy.delete(uid);
3016             }
3017             changed = true;
3018         }
3019         synchronized (mNetworkPoliciesSecondLock) {
3020             if (updateGlobalRules) {
3021                 updateRulesForGlobalChangeAL(true);
3022             }
3023             if (writePolicy && changed) {
3024                 writePolicyAL();
3025             }
3026         }
3027         return changed;
3028     }
3029 
3030     private boolean checkAnyPermissionOf(String... permissions) {
3031         for (String permission : permissions) {
3032             if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
3033                 return true;
3034             }
3035         }
3036         return false;
3037     }
3038 
3039     private void enforceAnyPermissionOf(String... permissions) {
3040         if (!checkAnyPermissionOf(permissions)) {
3041             throw new SecurityException("Requires one of the following permissions: "
3042                     + String.join(", ", permissions) + ".");
3043         }
3044     }
3045 
3046     @Override
3047     public void registerListener(@NonNull INetworkPolicyListener listener) {
3048         Objects.requireNonNull(listener);
3049         // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
3050         //  have declared OBSERVE_NETWORK_POLICY.
3051         enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
3052         mListeners.register(listener);
3053         // TODO: Send callbacks to the newly registered listener
3054     }
3055 
3056     @Override
3057     public void unregisterListener(@NonNull INetworkPolicyListener listener) {
3058         Objects.requireNonNull(listener);
3059         // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
3060         //  have declared OBSERVE_NETWORK_POLICY.
3061         enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
3062         mListeners.unregister(listener);
3063     }
3064 
3065     @Override
3066     public void setNetworkPolicies(NetworkPolicy[] policies) {
3067         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3068 
3069         final long token = Binder.clearCallingIdentity();
3070         try {
3071             synchronized (mUidRulesFirstLock) {
3072                 synchronized (mNetworkPoliciesSecondLock) {
3073                     normalizePoliciesNL(policies);
3074                     handleNetworkPoliciesUpdateAL(false);
3075                 }
3076             }
3077         } finally {
3078             Binder.restoreCallingIdentity(token);
3079         }
3080     }
3081 
3082     void addNetworkPolicyAL(NetworkPolicy policy) {
3083         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
3084         policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
3085         setNetworkPolicies(policies);
3086     }
3087 
3088     @Override
3089     public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
3090         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3091         try {
3092             mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
3093             // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
3094             // permission
3095         } catch (SecurityException e) {
3096             mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
3097 
3098             if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
3099                     callingPackage) != AppOpsManager.MODE_ALLOWED) {
3100                 return new NetworkPolicy[0];
3101             }
3102         }
3103 
3104         synchronized (mNetworkPoliciesSecondLock) {
3105             final int size = mNetworkPolicy.size();
3106             final NetworkPolicy[] policies = new NetworkPolicy[size];
3107             for (int i = 0; i < size; i++) {
3108                 policies[i] = mNetworkPolicy.valueAt(i);
3109             }
3110             return policies;
3111         }
3112     }
3113 
3114     @GuardedBy("mNetworkPoliciesSecondLock")
3115     private void normalizePoliciesNL() {
3116         normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
3117     }
3118 
3119     @GuardedBy("mNetworkPoliciesSecondLock")
3120     private void normalizePoliciesNL(NetworkPolicy[] policies) {
3121         mNetworkPolicy.clear();
3122         for (NetworkPolicy policy : policies) {
3123             if (policy == null) {
3124                 continue;
3125             }
3126             // When two normalized templates conflict, prefer the most
3127             // restrictive policy
3128             policy.template = normalizeTemplate(policy.template, mMergedSubscriberIds);
3129             final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
3130             if (existing == null || existing.compareTo(policy) > 0) {
3131                 if (existing != null) {
3132                     Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
3133                 }
3134                 mNetworkPolicy.put(policy.template, policy);
3135             }
3136         }
3137     }
3138 
3139     /**
3140      * Examine the given template and normalize it.
3141      * We pick the "lowest" merged subscriber as the primary
3142      * for key purposes, and expand the template to match all other merged
3143      * subscribers.
3144      *
3145      * There can be multiple merged subscriberIds for multi-SIM devices.
3146      *
3147      * <p>
3148      * For example, given an incoming template matching B, and the currently
3149      * active merge set [A,B], we'd return a new template that primarily matches
3150      * A, but also matches B.
3151      */
3152     @VisibleForTesting(visibility = PRIVATE)
3153     static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template,
3154             @NonNull List<String[]> mergedList) {
3155         // Now there are several types of network which uses Subscriber Id to store network
3156         // information. For instance:
3157         // 1. A merged carrier wifi network which has TYPE_WIFI with a Subscriber Id.
3158         // 2. A typical cellular network could have TYPE_MOBILE with a Subscriber Id.
3159 
3160         if (template.getSubscriberIds().isEmpty()) return template;
3161 
3162         for (final String[] merged : mergedList) {
3163             // In some rare cases (e.g. b/243015487), merged subscriberId list might contain
3164             // duplicated items. Deduplication for better error handling.
3165             final ArraySet mergedSet = new ArraySet(merged);
3166             if (mergedSet.size() != merged.length) {
3167                 Log.wtf(TAG, "Duplicated merged list detected: " + Arrays.toString(merged));
3168             }
3169             // TODO: Handle incompatible subscriberIds if that happens in practice.
3170             for (final String subscriberId : template.getSubscriberIds()) {
3171                 if (com.android.net.module.util.CollectionUtils.contains(merged, subscriberId)) {
3172                     // Requested template subscriber is part of the merged group; return
3173                     // a template that matches all merged subscribers.
3174                     return new NetworkTemplate.Builder(template.getMatchRule())
3175                             .setWifiNetworkKeys(template.getWifiNetworkKeys())
3176                             .setSubscriberIds(mergedSet)
3177                             .setMeteredness(template.getMeteredness())
3178                             .build();
3179                 }
3180             }
3181         }
3182 
3183         return template;
3184     }
3185 
3186     @Override
3187     public void snoozeLimit(NetworkTemplate template) {
3188         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3189 
3190         final long token = Binder.clearCallingIdentity();
3191         try {
3192             performSnooze(template, TYPE_LIMIT);
3193         } finally {
3194             Binder.restoreCallingIdentity(token);
3195         }
3196     }
3197 
3198     void performSnooze(NetworkTemplate template, int type) {
3199         final long currentTime = mClock.millis();
3200         synchronized (mUidRulesFirstLock) {
3201             synchronized (mNetworkPoliciesSecondLock) {
3202                 // find and snooze local policy that matches
3203                 final NetworkPolicy policy = mNetworkPolicy.get(template);
3204                 if (policy == null) {
3205                     throw new IllegalArgumentException("unable to find policy for " + template);
3206                 }
3207 
3208                 switch (type) {
3209                     case TYPE_WARNING:
3210                         policy.lastWarningSnooze = currentTime;
3211                         break;
3212                     case TYPE_LIMIT:
3213                         policy.lastLimitSnooze = currentTime;
3214                         break;
3215                     case TYPE_RAPID:
3216                         policy.lastRapidSnooze = currentTime;
3217                         break;
3218                     default:
3219                         throw new IllegalArgumentException("unexpected type");
3220                 }
3221 
3222                 handleNetworkPoliciesUpdateAL(true);
3223             }
3224         }
3225     }
3226 
3227     @Override
3228     public void setRestrictBackground(boolean restrictBackground) {
3229         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
3230         try {
3231             mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3232             final int callingUid = Binder.getCallingUid();
3233             final long token = Binder.clearCallingIdentity();
3234             try {
3235                 synchronized (mUidRulesFirstLock) {
3236                     setRestrictBackgroundUL(restrictBackground, "uid:" + callingUid);
3237                 }
3238             } finally {
3239                 Binder.restoreCallingIdentity(token);
3240             }
3241         } finally {
3242             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3243         }
3244     }
3245 
3246     @GuardedBy("mUidRulesFirstLock")
3247     private void setRestrictBackgroundUL(boolean restrictBackground, String reason) {
3248         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL");
3249         try {
3250             if (restrictBackground == mRestrictBackground) {
3251                 // Ideally, UI should never allow this scenario...
3252                 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground);
3253                 return;
3254             }
3255             Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground + "; reason: " + reason);
3256             final boolean oldRestrictBackground = mRestrictBackground;
3257             mRestrictBackground = restrictBackground;
3258             // Must allow foreground apps before turning data saver mode on.
3259             // TODO: there is no need to iterate through all apps here, just those in the foreground,
3260             // so it could call AM to get the UIDs of such apps, and iterate through them instead.
3261             updateRulesForRestrictBackgroundUL();
3262             try {
3263                 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
3264                     Slog.e(TAG,
3265                             "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
3266                     mRestrictBackground = oldRestrictBackground;
3267                     // TODO: if it knew the foreground apps (see TODO above), it could call
3268                     // updateRulesForRestrictBackgroundUL() again to restore state.
3269                     return;
3270                 }
3271             } catch (RemoteException e) {
3272                 // ignored; service lives in system_server
3273             }
3274 
3275             sendRestrictBackgroundChangedMsg();
3276             mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
3277 
3278             if (mRestrictBackgroundLowPowerMode) {
3279                 mRestrictBackgroundChangedInBsm = true;
3280             }
3281             synchronized (mNetworkPoliciesSecondLock) {
3282                 updateNotificationsNL();
3283                 writePolicyAL();
3284             }
3285         } finally {
3286             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3287         }
3288     }
3289 
3290     private void sendRestrictBackgroundChangedMsg() {
3291         mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED);
3292         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0)
3293                 .sendToTarget();
3294     }
3295 
3296     @Override
3297     public int getRestrictBackgroundByCaller() {
3298         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
3299         return getRestrictBackgroundStatusInternal(Binder.getCallingUid());
3300     }
3301 
3302     @Override
3303     public int getRestrictBackgroundStatus(int uid) {
3304         PermissionUtils.enforceNetworkStackPermission(mContext);
3305         return getRestrictBackgroundStatusInternal(uid);
3306     }
3307 
3308     private int getRestrictBackgroundStatusInternal(int uid) {
3309         synchronized (mUidRulesFirstLock) {
3310             // Must clear identity because getUidPolicy() is restricted to system.
3311             final long token = Binder.clearCallingIdentity();
3312             final int policy;
3313             try {
3314                 policy = getUidPolicy(uid);
3315             } finally {
3316                 Binder.restoreCallingIdentity(token);
3317             }
3318             if (policy == POLICY_REJECT_METERED_BACKGROUND) {
3319                 // App is restricted.
3320                 return RESTRICT_BACKGROUND_STATUS_ENABLED;
3321             }
3322             if (!mRestrictBackground) {
3323                 return RESTRICT_BACKGROUND_STATUS_DISABLED;
3324             }
3325             return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
3326                     ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
3327                     : RESTRICT_BACKGROUND_STATUS_ENABLED;
3328         }
3329     }
3330 
3331     @Override
3332     public boolean getRestrictBackground() {
3333         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3334 
3335         synchronized (mUidRulesFirstLock) {
3336             return mRestrictBackground;
3337         }
3338     }
3339 
3340     @Override
3341     public void setDeviceIdleMode(boolean enabled) {
3342         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3343         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
3344         try {
3345             synchronized (mUidRulesFirstLock) {
3346                 if (mDeviceIdleMode == enabled) {
3347                     return;
3348                 }
3349                 mDeviceIdleMode = enabled;
3350                 mLogger.deviceIdleModeEnabled(enabled);
3351                 if (mSystemReady) {
3352                     // Device idle change means we need to rebuild rules for all
3353                     // known apps, so do a global refresh.
3354                     handleDeviceIdleModeChangedUL(enabled);
3355                 }
3356             }
3357             if (enabled) {
3358                 EventLogTags.writeDeviceIdleOnPhase("net");
3359             } else {
3360                 EventLogTags.writeDeviceIdleOffPhase("net");
3361             }
3362         } finally {
3363             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3364         }
3365     }
3366 
3367     @Override
3368     public void setWifiMeteredOverride(String networkId, int meteredOverride) {
3369         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3370         final long token = Binder.clearCallingIdentity();
3371         try {
3372             final WifiManager wm = mContext.getSystemService(WifiManager.class);
3373             final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
3374             for (WifiConfiguration config : configs) {
3375                 if (Objects.equals(resolveNetworkId(config), networkId)) {
3376                     config.meteredOverride = meteredOverride;
3377                     wm.updateNetwork(config);
3378                 }
3379             }
3380         } finally {
3381             Binder.restoreCallingIdentity(token);
3382         }
3383     }
3384 
3385     private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) {
3386         // Verify they're not lying about package name
3387         mAppOps.checkPackage(callingUid, callingPackage);
3388 
3389         final PersistableBundle config;
3390         final TelephonyManager tm;
3391         final long token = Binder.clearCallingIdentity();
3392         try {
3393             config = mCarrierConfigManager.getConfigForSubId(subId);
3394             tm = mContext.getSystemService(TelephonyManager.class);
3395         } finally {
3396             Binder.restoreCallingIdentity(token);
3397         }
3398 
3399         // First check: does caller have carrier privilege?
3400         if (tm != null && tm.hasCarrierPrivileges(subId)) {
3401             return;
3402         }
3403 
3404         // Second check: has the CarrierService delegated access?
3405         if (config != null) {
3406             final String overridePackage = config
3407                     .getString(CarrierConfigManager.KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING, null);
3408             if (!TextUtils.isEmpty(overridePackage)
3409                     && Objects.equals(overridePackage, callingPackage)) {
3410                 return;
3411             }
3412         }
3413 
3414         // Third check: is caller the fallback/default CarrierService?
3415         final String defaultPackage = mCarrierConfigManager.getDefaultCarrierServicePackageName();
3416         if (!TextUtils.isEmpty(defaultPackage)
3417                 && Objects.equals(defaultPackage, callingPackage)) {
3418             return;
3419         }
3420 
3421         // Fourth check: is caller a testing app?
3422         final String testPackage = SystemProperties.get(PROP_SUB_PLAN_OWNER + "." + subId, null);
3423         if (!TextUtils.isEmpty(testPackage)
3424                 && Objects.equals(testPackage, callingPackage)) {
3425             return;
3426         }
3427 
3428         // Fifth check: is caller a legacy testing app?
3429         final String legacyTestPackage = SystemProperties.get("fw.sub_plan_owner." + subId, null);
3430         if (!TextUtils.isEmpty(legacyTestPackage)
3431                 && Objects.equals(legacyTestPackage, callingPackage)) {
3432             return;
3433         }
3434 
3435         // Final check: does the caller hold a permission?
3436         mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
3437     }
3438 
3439     private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
3440         // nothing to check if no plans
3441         if (plans.length == 0) {
3442             Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans.");
3443             return;
3444         }
3445 
3446         final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes();
3447         final ArraySet<Integer> allNetworksSet = new ArraySet<>();
3448         addAll(allNetworksSet, allNetworkTypes);
3449 
3450         final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>();
3451         boolean hasGeneralPlan = false;
3452         for (int i = 0; i < plans.length; i++) {
3453             final int[] planNetworkTypes = plans[i].getNetworkTypes();
3454             final ArraySet<Integer> planNetworksSet = new ArraySet<>();
3455             for (int j = 0; j < planNetworkTypes.length; j++) {
3456                 // ensure all network types are valid
3457                 if (allNetworksSet.contains(planNetworkTypes[j])) {
3458                     // ensure no duplicate network types in the same SubscriptionPlan
3459                     if (!planNetworksSet.add(planNetworkTypes[j])) {
3460                         throw new IllegalArgumentException(
3461                                 "Subscription plan contains duplicate network types.");
3462                     }
3463                 } else {
3464                     throw new IllegalArgumentException("Invalid network type: "
3465                             + planNetworkTypes[j]);
3466                 }
3467             }
3468 
3469             if (planNetworkTypes.length == allNetworkTypes.length) {
3470                 hasGeneralPlan = true;
3471             } else {
3472                 // ensure no network type applies to multiple plans
3473                 if (!addAll(applicableNetworkTypes, planNetworkTypes)) {
3474                     throw new IllegalArgumentException(
3475                             "Multiple subscription plans defined for a single network type.");
3476                 }
3477             }
3478         }
3479 
3480         // ensure at least one plan applies for every network type
3481         if (!hasGeneralPlan) {
3482             throw new IllegalArgumentException(
3483                     "No generic subscription plan that applies to all network types.");
3484         }
3485     }
3486 
3487     /**
3488      * Adds all of the {@code elements} to the {@code set}.
3489      *
3490      * @return {@code false} if any element is not added because the set already has the value.
3491      */
3492     private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) {
3493         boolean result = true;
3494         for (int i = 0; i < elements.length; i++) {
3495             result &= set.add(elements[i]);
3496         }
3497         return result;
3498     }
3499 
3500     /**
3501      * Get subscription plan for the given networkTemplate.
3502      *
3503      * @param template the networkTemplate to get the subscription plan for.
3504      */
3505     @Override
3506     public SubscriptionPlan getSubscriptionPlan(@NonNull NetworkTemplate template) {
3507         enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3508         synchronized (mNetworkPoliciesSecondLock) {
3509             final int subId = findRelevantSubIdNL(template);
3510             return getPrimarySubscriptionPlanLocked(subId);
3511         }
3512     }
3513 
3514     /**
3515      * Notifies that the specified {@link NetworkStatsProvider} has reached its quota
3516      * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
3517      * {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
3518      */
3519     @Override
3520     public void notifyStatsProviderWarningOrLimitReached() {
3521         enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3522         // This API may be called before the system is ready.
3523         synchronized (mNetworkPoliciesSecondLock) {
3524             if (!mSystemReady) return;
3525         }
3526         mHandler.obtainMessage(MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED).sendToTarget();
3527     }
3528 
3529     @Override
3530     public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
3531         enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3532 
3533         final String fake = SystemProperties.get("fw.fake_plan");
3534         if (!TextUtils.isEmpty(fake)) {
3535             final List<SubscriptionPlan> plans = new ArrayList<>();
3536             if ("month_hard".equals(fake)) {
3537                 plans.add(SubscriptionPlan.Builder
3538                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3539                         .setTitle("G-Mobile")
3540                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3541                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3542                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
3543                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3544                         .build());
3545                 plans.add(SubscriptionPlan.Builder
3546                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3547                         .setTitle("G-Mobile Happy")
3548                         .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3549                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3550                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3551                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3552                         .build());
3553                 plans.add(SubscriptionPlan.Builder
3554                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3555                         .setTitle("G-Mobile, Charged after limit")
3556                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3557                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3558                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3559                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3560                         .build());
3561             } else if ("month_soft".equals(fake)) {
3562                 plans.add(SubscriptionPlan.Builder
3563                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3564                         .setTitle("G-Mobile is the carriers name who this plan belongs to")
3565                         .setSummary("Crazy unlimited bandwidth plan with incredibly long title "
3566                                 + "that should be cut off to prevent UI from looking terrible")
3567                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3568                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3569                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
3570                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3571                         .build());
3572                 plans.add(SubscriptionPlan.Builder
3573                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3574                         .setTitle("G-Mobile, Throttled after limit")
3575                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3576                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3577                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3578                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3579                         .build());
3580                 plans.add(SubscriptionPlan.Builder
3581                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3582                         .setTitle("G-Mobile, No data connection after limit")
3583                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3584                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3585                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3586                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3587                         .build());
3588 
3589             } else if ("month_over".equals(fake)) {
3590                 plans.add(SubscriptionPlan.Builder
3591                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3592                         .setTitle("G-Mobile is the carriers name who this plan belongs to")
3593                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3594                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3595                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(6),
3596                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3597                         .build());
3598                 plans.add(SubscriptionPlan.Builder
3599                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3600                         .setTitle("G-Mobile, Throttled after limit")
3601                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3602                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3603                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3604                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3605                         .build());
3606                 plans.add(SubscriptionPlan.Builder
3607                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3608                         .setTitle("G-Mobile, No data connection after limit")
3609                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3610                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3611                         .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
3612                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3613                         .build());
3614 
3615             } else if ("month_none".equals(fake)) {
3616                 plans.add(SubscriptionPlan.Builder
3617                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3618                         .setTitle("G-Mobile")
3619                         .build());
3620             } else if ("prepaid".equals(fake)) {
3621                 plans.add(SubscriptionPlan.Builder
3622                         .createNonrecurring(ZonedDateTime.now().minusDays(20),
3623                                 ZonedDateTime.now().plusDays(10))
3624                         .setTitle("G-Mobile")
3625                         .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
3626                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3627                         .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
3628                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3629                         .build());
3630             } else if ("prepaid_crazy".equals(fake)) {
3631                 plans.add(SubscriptionPlan.Builder
3632                         .createNonrecurring(ZonedDateTime.now().minusDays(20),
3633                                 ZonedDateTime.now().plusDays(10))
3634                         .setTitle("G-Mobile Anytime")
3635                         .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
3636                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3637                         .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
3638                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3639                         .build());
3640                 plans.add(SubscriptionPlan.Builder
3641                         .createNonrecurring(ZonedDateTime.now().minusDays(10),
3642                                 ZonedDateTime.now().plusDays(20))
3643                         .setTitle("G-Mobile Nickel Nights")
3644                         .setSummary("5¢/GB between 1-5AM")
3645                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
3646                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3647                         .setDataUsage(DataUnit.MEBIBYTES.toBytes(15),
3648                                 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
3649                         .build());
3650                 plans.add(SubscriptionPlan.Builder
3651                         .createNonrecurring(ZonedDateTime.now().minusDays(10),
3652                                 ZonedDateTime.now().plusDays(20))
3653                         .setTitle("G-Mobile Bonus 3G")
3654                         .setSummary("Unlimited 3G data")
3655                         .setDataLimit(DataUnit.GIBIBYTES.toBytes(1),
3656                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3657                         .setDataUsage(DataUnit.MEBIBYTES.toBytes(300),
3658                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3659                         .build());
3660             } else if ("unlimited".equals(fake)) {
3661                 plans.add(SubscriptionPlan.Builder
3662                         .createNonrecurring(ZonedDateTime.now().minusDays(20),
3663                                 ZonedDateTime.now().plusDays(10))
3664                         .setTitle("G-Mobile Awesome")
3665                         .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3666                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3667                         .setDataUsage(DataUnit.MEBIBYTES.toBytes(50),
3668                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3669                         .build());
3670             }
3671             return plans.toArray(new SubscriptionPlan[plans.size()]);
3672         }
3673 
3674         synchronized (mNetworkPoliciesSecondLock) {
3675             // Only give out plan details to the package that defined them,
3676             // so that we don't risk leaking plans between apps. We always
3677             // let in core system components (like the Settings app).
3678             final String ownerPackage = mSubscriptionPlansOwner.get(subId);
3679             if (Objects.equals(ownerPackage, callingPackage)
3680                     || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)
3681                     || (UserHandle.getCallingAppId() == android.os.Process.PHONE_UID)) {
3682                 return mSubscriptionPlans.get(subId);
3683             } else {
3684                 Log.w(TAG, "Not returning plans because caller " + callingPackage
3685                         + " doesn't match owner " + ownerPackage);
3686                 return null;
3687             }
3688         }
3689     }
3690 
3691     @Override
3692     public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans,
3693             long expirationDurationMillis, String callingPackage) {
3694         enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3695         enforceSubscriptionPlanValidity(plans);
3696 
3697         for (SubscriptionPlan plan : plans) {
3698             Objects.requireNonNull(plan);
3699         }
3700 
3701         final long token = Binder.clearCallingIdentity();
3702         try {
3703             setSubscriptionPlansInternal(subId, plans, expirationDurationMillis, callingPackage);
3704         } finally {
3705             Binder.restoreCallingIdentity(token);
3706         }
3707     }
3708 
3709     private void setSubscriptionPlansInternal(int subId, SubscriptionPlan[] plans,
3710             long expirationDurationMillis, String callingPackage) {
3711         synchronized (mUidRulesFirstLock) {
3712             synchronized (mNetworkPoliciesSecondLock) {
3713                 mSubscriptionPlans.put(subId, plans);
3714                 mSubscriptionPlansOwner.put(subId, callingPackage);
3715 
3716                 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
3717                 if (subscriberId != null) {
3718                     ensureActiveCarrierPolicyAL(subId, subscriberId);
3719                     maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
3720                 } else {
3721                     Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
3722                 }
3723 
3724                 handleNetworkPoliciesUpdateAL(true);
3725 
3726                 final Intent intent = new Intent(
3727                         SubscriptionManager.ACTION_SUBSCRIPTION_PLANS_CHANGED);
3728                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3729                 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3730                 mContext.sendBroadcast(intent,
3731                         android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS);
3732                 mHandler.sendMessage(mHandler.obtainMessage(
3733                         MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans));
3734                 final int setPlansId = mSetSubscriptionPlansIdCounter++;
3735                 mSetSubscriptionPlansIds.put(subId, setPlansId);
3736                 if (expirationDurationMillis > 0) {
3737                     mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_SUBSCRIPTION_PLANS,
3738                             subId, setPlansId, callingPackage), expirationDurationMillis);
3739                 }
3740             }
3741         }
3742     }
3743 
3744     /**
3745      * Only visible for testing purposes. This doesn't give any access to
3746      * existing plans; it simply lets the debug package define new plans.
3747      */
3748     void setSubscriptionPlansOwner(int subId, String packageName) {
3749         mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
3750         SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName);
3751     }
3752 
3753     @Override
3754     public String getSubscriptionPlansOwner(int subId) {
3755         if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) {
3756             throw new SecurityException();
3757         }
3758 
3759         synchronized (mNetworkPoliciesSecondLock) {
3760             return mSubscriptionPlansOwner.get(subId);
3761         }
3762     }
3763 
3764     @Override
3765     public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
3766             int[] networkTypes, long expirationDurationMillis, String callingPackage) {
3767         enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3768 
3769         final ArraySet<Integer> allNetworksSet = new ArraySet<>();
3770         addAll(allNetworksSet, TelephonyManager.getAllNetworkTypes());
3771         final IntArray applicableNetworks = new IntArray();
3772 
3773         // ensure all network types are valid
3774         for (int networkType : networkTypes) {
3775             if (allNetworksSet.contains(networkType)) {
3776                 applicableNetworks.add(networkType);
3777             } else {
3778                 Log.d(TAG, "setSubscriptionOverride removing invalid network type: " + networkType);
3779             }
3780         }
3781 
3782         // We can only override when carrier told us about plans. For the unmetered case,
3783         // allow override without having plans defined.
3784         synchronized (mNetworkPoliciesSecondLock) {
3785             final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
3786             if (overrideMask != SUBSCRIPTION_OVERRIDE_UNMETERED && plan == null
3787                     || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
3788                 throw new IllegalStateException(
3789                         "Must provide valid SubscriptionPlan to enable overriding");
3790             }
3791         }
3792 
3793         // Only allow overrides when feature is enabled. However, we always
3794         // allow disabling of overrides for safety reasons.
3795         final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
3796                 NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
3797         if (overrideEnabled || overrideValue == 0) {
3798             SomeArgs args = SomeArgs.obtain();
3799             args.arg1 = subId;
3800             args.arg2 = overrideMask;
3801             args.arg3 = overrideValue;
3802             args.arg4 = applicableNetworks.toArray();
3803             mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args));
3804             if (expirationDurationMillis > 0) {
3805                 args.arg3 = 0;
3806                 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args),
3807                         expirationDurationMillis);
3808             }
3809         }
3810     }
3811 
3812     /**
3813      * Get multipath preference value for the given network.
3814      */
3815     public int getMultipathPreference(Network network) {
3816         PermissionUtils.enforceNetworkStackPermission(mContext);
3817         final Integer preference = mMultipathPolicyTracker.getMultipathPreference(network);
3818         if (preference != null) {
3819             return preference;
3820         }
3821         return 0;
3822     }
3823 
3824     @NeverCompile // Avoid size overhead of debugging code.
3825     @Override
3826     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
3827         if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
3828 
3829         final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
3830 
3831         final ArraySet<String> argSet = new ArraySet<String>(args.length);
3832         for (String arg : args) {
3833             argSet.add(arg);
3834         }
3835 
3836         synchronized (mUidRulesFirstLock) {
3837             synchronized (mNetworkPoliciesSecondLock) {
3838                 if (argSet.contains("--unsnooze")) {
3839                     for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
3840                         mNetworkPolicy.valueAt(i).clearSnooze();
3841                     }
3842 
3843                     handleNetworkPoliciesUpdateAL(true);
3844 
3845                     fout.println("Cleared snooze timestamps");
3846                     return;
3847                 }
3848 
3849                 fout.print("System ready: "); fout.println(mSystemReady);
3850                 fout.print("Restrict background: "); fout.println(mRestrictBackground);
3851                 fout.print("Restrict power: "); fout.println(mRestrictPower);
3852                 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
3853                 fout.print("Restricted networking mode: "); fout.println(mRestrictedNetworkingMode);
3854                 fout.print("Low Power Standby mode: "); fout.println(mLowPowerStandbyActive);
3855                 synchronized (mMeteredIfacesLock) {
3856                     fout.print("Metered ifaces: ");
3857                     fout.println(mMeteredIfaces);
3858                 }
3859 
3860                 fout.println();
3861                 fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode);
3862                 fout.println("mRestrictBackgroundBeforeBsm: " + mRestrictBackgroundBeforeBsm);
3863                 fout.println("mLoadedRestrictBackground: " + mLoadedRestrictBackground);
3864                 fout.println("mRestrictBackgroundChangedInBsm: " + mRestrictBackgroundChangedInBsm);
3865 
3866                 fout.println();
3867                 fout.println("Network policies:");
3868                 fout.increaseIndent();
3869                 for (int i = 0; i < mNetworkPolicy.size(); i++) {
3870                     fout.println(mNetworkPolicy.valueAt(i).toString());
3871                 }
3872                 fout.decreaseIndent();
3873 
3874                 fout.println();
3875                 fout.println("Subscription plans:");
3876                 fout.increaseIndent();
3877                 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
3878                     final int subId = mSubscriptionPlans.keyAt(i);
3879                     fout.println("Subscriber ID " + subId + ":");
3880                     fout.increaseIndent();
3881                     final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
3882                     if (!ArrayUtils.isEmpty(plans)) {
3883                         for (SubscriptionPlan plan : plans) {
3884                             fout.println(plan);
3885                         }
3886                     }
3887                     fout.decreaseIndent();
3888                 }
3889                 fout.decreaseIndent();
3890 
3891                 fout.println();
3892                 fout.println("Active subscriptions:");
3893                 fout.increaseIndent();
3894                 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
3895                     final int subId = mSubIdToSubscriberId.keyAt(i);
3896                     final String subscriberId = mSubIdToSubscriberId.valueAt(i);
3897 
3898                     fout.println(subId + "="
3899                             + NetworkIdentityUtils.scrubSubscriberId(subscriberId));
3900                 }
3901                 fout.decreaseIndent();
3902 
3903                 fout.println();
3904                 for (String[] mergedSubscribers : mMergedSubscriberIds) {
3905                     fout.println("Merged subscriptions: " + Arrays.toString(
3906                             NetworkIdentityUtils.scrubSubscriberIds(mergedSubscribers)));
3907                 }
3908 
3909                 fout.println();
3910                 fout.println("Policy for UIDs:");
3911                 fout.increaseIndent();
3912                 int size = mUidPolicy.size();
3913                 for (int i = 0; i < size; i++) {
3914                     final int uid = mUidPolicy.keyAt(i);
3915                     final int policy = mUidPolicy.valueAt(i);
3916                     fout.print("UID=");
3917                     fout.print(uid);
3918                     fout.print(" policy=");
3919                     fout.print(uidPoliciesToString(policy));
3920                     fout.println();
3921                 }
3922                 fout.decreaseIndent();
3923 
3924                 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3925                 if (size > 0) {
3926                     fout.println("Power save whitelist (except idle) app ids:");
3927                     fout.increaseIndent();
3928                     for (int i = 0; i < size; i++) {
3929                         fout.print("UID=");
3930                         fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3931                         fout.print(": ");
3932                         fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
3933                         fout.println();
3934                     }
3935                     fout.decreaseIndent();
3936                 }
3937 
3938                 size = mPowerSaveWhitelistAppIds.size();
3939                 if (size > 0) {
3940                     fout.println("Power save whitelist app ids:");
3941                     fout.increaseIndent();
3942                     for (int i = 0; i < size; i++) {
3943                         fout.print("UID=");
3944                         fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
3945                         fout.print(": ");
3946                         fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
3947                         fout.println();
3948                     }
3949                     fout.decreaseIndent();
3950                 }
3951 
3952                 size = mAppIdleTempWhitelistAppIds.size();
3953                 if (size > 0) {
3954                     fout.println("App idle whitelist app ids:");
3955                     fout.increaseIndent();
3956                     for (int i = 0; i < size; i++) {
3957                         fout.print("UID=");
3958                         fout.print(mAppIdleTempWhitelistAppIds.keyAt(i));
3959                         fout.print(": ");
3960                         fout.print(mAppIdleTempWhitelistAppIds.valueAt(i));
3961                         fout.println();
3962                     }
3963                     fout.decreaseIndent();
3964                 }
3965 
3966                 size = mDefaultRestrictBackgroundAllowlistUids.size();
3967                 if (size > 0) {
3968                     fout.println("Default restrict background allowlist uids:");
3969                     fout.increaseIndent();
3970                     for (int i = 0; i < size; i++) {
3971                         fout.print("UID=");
3972                         fout.print(mDefaultRestrictBackgroundAllowlistUids.keyAt(i));
3973                         fout.println();
3974                     }
3975                     fout.decreaseIndent();
3976                 }
3977 
3978                 size = mRestrictBackgroundAllowlistRevokedUids.size();
3979                 if (size > 0) {
3980                     fout.println("Default restrict background allowlist uids revoked by users:");
3981                     fout.increaseIndent();
3982                     for (int i = 0; i < size; i++) {
3983                         fout.print("UID=");
3984                         fout.print(mRestrictBackgroundAllowlistRevokedUids.keyAt(i));
3985                         fout.println();
3986                     }
3987                     fout.decreaseIndent();
3988                 }
3989 
3990                 size = mLowPowerStandbyAllowlistUids.size();
3991                 if (size > 0) {
3992                     fout.println("Low Power Standby allowlist uids:");
3993                     fout.increaseIndent();
3994                     for (int i = 0; i < size; i++) {
3995                         fout.print("UID=");
3996                         fout.print(mLowPowerStandbyAllowlistUids.keyAt(i));
3997                         fout.println();
3998                     }
3999                     fout.decreaseIndent();
4000                 }
4001 
4002                 final SparseBooleanArray knownUids = new SparseBooleanArray();
4003                 collectKeys(mUidState, knownUids);
4004                 synchronized (mUidBlockedState) {
4005                     collectKeys(mUidBlockedState, knownUids);
4006                 }
4007 
4008                 fout.println("Status for all known UIDs:");
4009                 fout.increaseIndent();
4010                 size = knownUids.size();
4011                 for (int i = 0; i < size; i++) {
4012                     final int uid = knownUids.keyAt(i);
4013                     fout.print("UID=");
4014                     fout.print(uid);
4015 
4016                     final UidState uidState = mUidState.get(uid);
4017                     if (uidState == null) {
4018                         fout.print(" state={null}");
4019                     } else {
4020                         fout.print(" state=");
4021                         fout.print(uidState.toString());
4022                     }
4023 
4024                     synchronized (mUidBlockedState) {
4025                         final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
4026                         if (uidBlockedState == null) {
4027                             fout.print(" blocked_state={null}");
4028                         } else {
4029                             fout.print(" blocked_state=");
4030                             fout.print(uidBlockedState);
4031                         }
4032                     }
4033                     fout.println();
4034                 }
4035                 fout.decreaseIndent();
4036 
4037                 fout.println("Admin restricted uids for metered data:");
4038                 fout.increaseIndent();
4039                 size = mMeteredRestrictedUids.size();
4040                 for (int i = 0; i < size; ++i) {
4041                     fout.print("u" + mMeteredRestrictedUids.keyAt(i) + ": ");
4042                     fout.println(mMeteredRestrictedUids.valueAt(i));
4043                 }
4044                 fout.decreaseIndent();
4045 
4046                 fout.println();
4047                 mStatLogger.dump(fout);
4048 
4049                 mLogger.dumpLogs(fout);
4050             }
4051         }
4052         fout.println();
4053         mMultipathPolicyTracker.dump(fout);
4054     }
4055 
4056     @Override
4057     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
4058             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
4059             @NonNull String[] args) {
4060         return new NetworkPolicyManagerShellCommand(mContext, this).exec(this,
4061                 in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args);
4062     }
4063 
4064     void setDebugUid(int uid) {
4065         mLogger.setDebugUid(uid);
4066     }
4067 
4068     @VisibleForTesting
4069     boolean isUidForeground(int uid) {
4070         synchronized (mUidRulesFirstLock) {
4071             return isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid));
4072         }
4073     }
4074 
4075     @GuardedBy("mUidRulesFirstLock")
4076     private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
4077         final UidState uidState = mUidState.get(uid);
4078         return isProcStateAllowedWhileOnRestrictBackground(uidState);
4079     }
4080 
4081     @GuardedBy("mUidRulesFirstLock")
4082     private boolean isUidForegroundOnRestrictPowerUL(int uid) {
4083         final UidState uidState = mUidState.get(uid);
4084         return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState);
4085     }
4086 
4087     @GuardedBy("mUidRulesFirstLock")
4088     private boolean isUidTop(int uid) {
4089         final UidState uidState = mUidState.get(uid);
4090         return isProcStateAllowedWhileInLowPowerStandby(uidState);
4091     }
4092 
4093     /**
4094      * Process state of UID changed; if needed, will trigger
4095      * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
4096      * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated.
4097      */
4098     @GuardedBy("mUidRulesFirstLock")
4099     private boolean updateUidStateUL(int uid, int procState, long procStateSeq,
4100             @ProcessCapability int capability) {
4101         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
4102         try {
4103             final UidState oldUidState = mUidState.get(uid);
4104             if (oldUidState != null && procStateSeq < oldUidState.procStateSeq) {
4105                 if (LOGV) {
4106                     Slog.v(TAG, "Ignoring older uid state updates; uid=" + uid
4107                             + ",procState=" + procStateToString(procState) + ",seq=" + procStateSeq
4108                             + ",cap=" + capability + ",oldUidState=" + oldUidState);
4109                 }
4110                 return false;
4111             }
4112             if (oldUidState == null || oldUidState.procState != procState
4113                     || oldUidState.capability != capability) {
4114                 final UidState newUidState = new UidState(uid, procState, procStateSeq, capability);
4115                 // state changed, push updated rules
4116                 mUidState.put(uid, newUidState);
4117                 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState);
4118                 boolean allowedWhileIdleOrPowerSaveModeChanged =
4119                         isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
4120                                 != isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState);
4121                 if (allowedWhileIdleOrPowerSaveModeChanged) {
4122                     updateRuleForAppIdleUL(uid, procState);
4123                     if (mDeviceIdleMode) {
4124                         updateRuleForDeviceIdleUL(uid);
4125                     }
4126                     if (mRestrictPower) {
4127                         updateRuleForRestrictPowerUL(uid);
4128                     }
4129                     updateRulesForPowerRestrictionsUL(uid, procState);
4130                 }
4131                 if (mLowPowerStandbyActive) {
4132                     boolean allowedInLpsChanged =
4133                             isProcStateAllowedWhileInLowPowerStandby(oldUidState)
4134                                     != isProcStateAllowedWhileInLowPowerStandby(newUidState);
4135                     if (allowedInLpsChanged) {
4136                         if (!allowedWhileIdleOrPowerSaveModeChanged) {
4137                             updateRulesForPowerRestrictionsUL(uid, procState);
4138                         }
4139                         updateRuleForLowPowerStandbyUL(uid);
4140                     }
4141                 }
4142                 return true;
4143             }
4144         } finally {
4145             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4146         }
4147         return false;
4148     }
4149 
4150     @GuardedBy("mUidRulesFirstLock")
4151     private boolean removeUidStateUL(int uid) {
4152         final int index = mUidState.indexOfKey(uid);
4153         if (index >= 0) {
4154             final UidState oldUidState = mUidState.valueAt(index);
4155             mUidState.removeAt(index);
4156             if (oldUidState != null) {
4157                 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, null);
4158                 if (mDeviceIdleMode) {
4159                     updateRuleForDeviceIdleUL(uid);
4160                 }
4161                 if (mRestrictPower) {
4162                     updateRuleForRestrictPowerUL(uid);
4163                 }
4164                 updateRulesForPowerRestrictionsUL(uid);
4165                 if (mLowPowerStandbyActive) {
4166                     updateRuleForLowPowerStandbyUL(uid);
4167                 }
4168                 return true;
4169             }
4170         }
4171         return false;
4172     }
4173 
4174     // adjust stats accounting based on foreground status
4175     private void updateNetworkStats(int uid, boolean uidForeground) {
4176         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4177             Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4178                     "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B"));
4179         }
4180         try {
4181             mNetworkStats.noteUidForeground(uid, uidForeground);
4182         } finally {
4183             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4184         }
4185     }
4186 
4187     private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid,
4188             @Nullable UidState oldUidState, @Nullable UidState newUidState) {
4189         final boolean oldForeground =
4190                 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
4191         final boolean newForeground =
4192                 isProcStateAllowedWhileOnRestrictBackground(newUidState);
4193         if (oldForeground != newForeground) {
4194             updateRulesForDataUsageRestrictionsUL(uid);
4195         }
4196     }
4197 
4198     @VisibleForTesting
4199     boolean isRestrictedModeEnabled() {
4200         synchronized (mUidRulesFirstLock) {
4201             return mRestrictedNetworkingMode;
4202         }
4203     }
4204 
4205     /**
4206      * updates restricted mode state / access for all apps
4207      * Called on initialization and when restricted mode is enabled / disabled.
4208      */
4209     @VisibleForTesting
4210     @GuardedBy("mUidRulesFirstLock")
4211     void updateRestrictedModeAllowlistUL() {
4212         mUidFirewallRestrictedModeRules.clear();
4213         forEachUid("updateRestrictedModeAllowlist", uid -> {
4214             synchronized (mUidRulesFirstLock) {
4215                 final int effectiveBlockedReasons = updateBlockedReasonsForRestrictedModeUL(
4216                         uid);
4217                 final int newFirewallRule = getRestrictedModeFirewallRule(effectiveBlockedReasons);
4218 
4219                 // setUidFirewallRulesUL will allowlist all uids that are passed to it, so only add
4220                 // non-default rules.
4221                 if (newFirewallRule != FIREWALL_RULE_DEFAULT) {
4222                     mUidFirewallRestrictedModeRules.append(uid, newFirewallRule);
4223                 }
4224             }
4225         });
4226         if (mRestrictedNetworkingMode) {
4227             // firewall rules only need to be set when this mode is being enabled.
4228             setUidFirewallRulesUL(FIREWALL_CHAIN_RESTRICTED, mUidFirewallRestrictedModeRules);
4229         }
4230         enableFirewallChainUL(FIREWALL_CHAIN_RESTRICTED, mRestrictedNetworkingMode);
4231     }
4232 
4233     // updates restricted mode state / access for a single app / uid.
4234     @VisibleForTesting
4235     @GuardedBy("mUidRulesFirstLock")
4236     void updateRestrictedModeForUidUL(int uid) {
4237         final int effectiveBlockedReasons = updateBlockedReasonsForRestrictedModeUL(uid);
4238 
4239         // if restricted networking mode is on, and the app has an access exemption, the uid rule
4240         // will not change, but the firewall rule will have to be updated.
4241         if (mRestrictedNetworkingMode) {
4242             // Note: setUidFirewallRule also updates mUidFirewallRestrictedModeRules.
4243             // In this case, default firewall rules can also be added.
4244             setUidFirewallRuleUL(FIREWALL_CHAIN_RESTRICTED, uid,
4245                     getRestrictedModeFirewallRule(effectiveBlockedReasons));
4246         }
4247     }
4248 
4249     @GuardedBy("mUidRulesFirstLock")
4250     private int updateBlockedReasonsForRestrictedModeUL(int uid) {
4251         final boolean hasRestrictedModeAccess = hasRestrictedModeAccess(uid);
4252         final int oldEffectiveBlockedReasons;
4253         final int newEffectiveBlockedReasons;
4254         final int uidRules;
4255         synchronized (mUidBlockedState) {
4256             final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid(
4257                     mUidBlockedState, uid);
4258             oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
4259             if (mRestrictedNetworkingMode) {
4260                 uidBlockedState.blockedReasons |= BLOCKED_REASON_RESTRICTED_MODE;
4261             } else {
4262                 uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
4263             }
4264             if (hasRestrictedModeAccess) {
4265                 uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
4266             } else {
4267                 uidBlockedState.allowedReasons &= ~ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
4268             }
4269             uidBlockedState.updateEffectiveBlockedReasons();
4270 
4271             newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
4272             uidRules = oldEffectiveBlockedReasons == newEffectiveBlockedReasons
4273                     ? RULE_NONE
4274                     : uidBlockedState.deriveUidRules();
4275         }
4276         if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) {
4277             handleBlockedReasonsChanged(uid,
4278                     newEffectiveBlockedReasons, oldEffectiveBlockedReasons);
4279 
4280             postUidRulesChangedMsg(uid, uidRules);
4281         }
4282         return newEffectiveBlockedReasons;
4283     }
4284 
4285     private static int getRestrictedModeFirewallRule(int effectiveBlockedReasons) {
4286         if ((effectiveBlockedReasons & BLOCKED_REASON_RESTRICTED_MODE) != 0) {
4287             // rejected in restricted mode, this is the default behavior.
4288             return FIREWALL_RULE_DEFAULT;
4289         } else {
4290             return FIREWALL_RULE_ALLOW;
4291         }
4292     }
4293 
4294     private boolean hasRestrictedModeAccess(int uid) {
4295         try {
4296             // TODO: this needs to be kept in sync with
4297             // PermissionMonitor#hasRestrictedNetworkPermission
4298             return mIPm.checkUidPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, uid)
4299                     == PERMISSION_GRANTED
4300                     || mIPm.checkUidPermission(NETWORK_STACK, uid) == PERMISSION_GRANTED
4301                     || mIPm.checkUidPermission(PERMISSION_MAINLINE_NETWORK_STACK, uid)
4302                     == PERMISSION_GRANTED;
4303         } catch (RemoteException e) {
4304             return false;
4305         }
4306     }
4307 
4308     @GuardedBy("mUidRulesFirstLock")
4309     void updateRulesForPowerSaveUL() {
4310         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
4311         try {
4312             updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
4313                     mUidFirewallPowerSaveRules);
4314         } finally {
4315             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4316         }
4317     }
4318 
4319     @GuardedBy("mUidRulesFirstLock")
4320     void updateRuleForRestrictPowerUL(int uid) {
4321         updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
4322     }
4323 
4324     @GuardedBy("mUidRulesFirstLock")
4325     void updateRulesForDeviceIdleUL() {
4326         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
4327         try {
4328             updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
4329                     mUidFirewallDozableRules);
4330         } finally {
4331             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4332         }
4333     }
4334 
4335     @GuardedBy("mUidRulesFirstLock")
4336     void updateRuleForDeviceIdleUL(int uid) {
4337         updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
4338     }
4339 
4340     // NOTE: since both fw_dozable and fw_powersave uses the same map
4341     // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
4342     @GuardedBy("mUidRulesFirstLock")
4343     private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
4344             SparseIntArray rules) {
4345         if (enabled) {
4346             // Sync the whitelists before enabling the chain.  We don't care about the rules if
4347             // we are disabling the chain.
4348             final SparseIntArray uidRules = rules;
4349             uidRules.clear();
4350             final List<UserInfo> users = mUserManager.getUsers();
4351             for (int ui = users.size() - 1; ui >= 0; ui--) {
4352                 UserInfo user = users.get(ui);
4353                 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
4354                 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
4355                 if (chain == FIREWALL_CHAIN_POWERSAVE) {
4356                     updateRulesForWhitelistedAppIds(uidRules,
4357                             mPowerSaveWhitelistExceptIdleAppIds, user.id);
4358                 }
4359             }
4360             for (int i = mUidState.size() - 1; i >= 0; i--) {
4361                 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
4362                     uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
4363                 }
4364             }
4365             setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);
4366         } else {
4367             setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);
4368         }
4369     }
4370 
4371     private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
4372             final SparseBooleanArray whitelistedAppIds, int userId) {
4373         for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
4374             if (whitelistedAppIds.valueAt(i)) {
4375                 final int appId = whitelistedAppIds.keyAt(i);
4376                 final int uid = UserHandle.getUid(userId, appId);
4377                 uidRules.put(uid, FIREWALL_RULE_ALLOW);
4378             }
4379         }
4380     }
4381 
4382     @GuardedBy("mUidRulesFirstLock")
4383     void updateRulesForLowPowerStandbyUL() {
4384         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForLowPowerStandbyUL");
4385         try {
4386             if (mLowPowerStandbyActive) {
4387                 mUidFirewallLowPowerStandbyModeRules.clear();
4388                 for (int i = mUidState.size() - 1; i >= 0; i--) {
4389                     final int uid = mUidState.keyAt(i);
4390                     final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid);
4391                     if (hasInternetPermissionUL(uid) && (effectiveBlockedReasons
4392                                     & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) {
4393                         mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW);
4394                     }
4395                 }
4396                 setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY,
4397                         mUidFirewallLowPowerStandbyModeRules, CHAIN_TOGGLE_ENABLE);
4398             } else {
4399                 setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, null, CHAIN_TOGGLE_DISABLE);
4400             }
4401         } finally {
4402             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4403         }
4404     }
4405 
4406     @GuardedBy("mUidRulesFirstLock")
4407     void updateRuleForLowPowerStandbyUL(int uid) {
4408         if (!hasInternetPermissionUL(uid)) {
4409             return;
4410         }
4411 
4412         final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid);
4413         if (mUidState.contains(uid)
4414                 && (effectiveBlockedReasons & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) {
4415             mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW);
4416             setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_ALLOW);
4417         } else {
4418             mUidFirewallLowPowerStandbyModeRules.delete(uid);
4419             setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT);
4420         }
4421     }
4422 
4423     /**
4424      * Returns whether a uid is allowlisted from power saving restrictions (eg: Battery Saver, Doze
4425      * mode, and app idle).
4426      *
4427      * @param deviceIdleMode if true then we don't consider
4428      *        {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
4429      *        allowlisted.
4430      */
4431     @GuardedBy("mUidRulesFirstLock")
4432     private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) {
4433         final int appId = UserHandle.getAppId(uid);
4434         boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
4435                 || mPowerSaveWhitelistAppIds.get(appId);
4436         if (!deviceIdleMode) {
4437             isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid);
4438         }
4439         return isWhitelisted;
4440     }
4441 
4442     /**
4443      * Returns whether a uid is allowlisted from power saving restrictions, except Device idle
4444      * (eg: Battery Saver and app idle).
4445      */
4446     @GuardedBy("mUidRulesFirstLock")
4447     private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) {
4448         final int appId = UserHandle.getAppId(uid);
4449         return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
4450     }
4451 
4452     /**
4453      * Returns whether a uid is allowlisted from low power standby restrictions.
4454      */
4455     @GuardedBy("mUidRulesFirstLock")
4456     private boolean isAllowlistedFromLowPowerStandbyUL(int uid) {
4457         return mLowPowerStandbyAllowlistUids.get(uid);
4458     }
4459 
4460     // NOTE: since both fw_dozable and fw_powersave uses the same map
4461     // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
4462     @GuardedBy("mUidRulesFirstLock")
4463     private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
4464         if (enabled) {
4465             final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid,
4466                     chain == FIREWALL_CHAIN_DOZABLE);
4467             if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
4468                 setUidFirewallRuleUL(chain, uid, FIREWALL_RULE_ALLOW);
4469             } else {
4470                 setUidFirewallRuleUL(chain, uid, FIREWALL_RULE_DEFAULT);
4471             }
4472         }
4473     }
4474 
4475     @GuardedBy("mUidRulesFirstLock")
4476     void updateRulesForAppIdleUL() {
4477         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
4478         try {
4479             final SparseIntArray uidRules = mUidFirewallStandbyRules;
4480             uidRules.clear();
4481 
4482             // Fully update the app idle firewall chain.
4483             final List<UserInfo> users = mUserManager.getUsers();
4484             for (int ui = users.size() - 1; ui >= 0; ui--) {
4485                 UserInfo user = users.get(ui);
4486                 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
4487                 for (int uid : idleUids) {
4488                     if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
4489                         // quick check: if this uid doesn't have INTERNET permission, it
4490                         // doesn't have network access anyway, so it is a waste to mess
4491                         // with it here.
4492                         if (hasInternetPermissionUL(uid) && !isUidForegroundOnRestrictPowerUL(uid)) {
4493                             uidRules.put(uid, FIREWALL_RULE_DENY);
4494                         }
4495                     }
4496                 }
4497             }
4498 
4499             setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
4500         } finally {
4501             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4502         }
4503     }
4504 
4505     @GuardedBy("mUidRulesFirstLock")
4506     void updateRuleForAppIdleUL(int uid, int uidProcessState) {
4507         if (!isUidValidForDenylistRulesUL(uid)) return;
4508 
4509         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4510             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
4511         }
4512         try {
4513             int appId = UserHandle.getAppId(uid);
4514             if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid, uidProcessState)
4515                     && !isUidForegroundOnRestrictPowerUL(uid)) {
4516                 setUidFirewallRuleUL(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
4517                 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid);
4518             } else {
4519                 setUidFirewallRuleUL(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
4520                 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT");
4521             }
4522         } finally {
4523             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4524         }
4525     }
4526 
4527     /**
4528      * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
4529      * changed.
4530      */
4531     @GuardedBy("mUidRulesFirstLock")
4532     private void updateRulesForAppIdleParoleUL() {
4533         final boolean paroled = mAppStandby.isInParole();
4534         final boolean enableChain = !paroled;
4535 
4536         int ruleCount = mUidFirewallStandbyRules.size();
4537         final SparseIntArray blockedUids = new SparseIntArray();
4538         for (int i = 0; i < ruleCount; i++) {
4539             final int uid = mUidFirewallStandbyRules.keyAt(i);
4540             if (!isUidValidForDenylistRulesUL(uid)) {
4541                 continue;
4542             }
4543             final int blockedReasons = getBlockedReasons(uid);
4544             if (!enableChain && (blockedReasons & ~BLOCKED_METERED_REASON_MASK)
4545                     == BLOCKED_REASON_NONE) {
4546                 // Chain isn't enabled and the uid had no restrictions to begin with.
4547                 continue;
4548             }
4549             final boolean isUidIdle = !paroled && isUidIdle(uid);
4550             if (isUidIdle && !mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid))
4551                     && !isUidForegroundOnRestrictPowerUL(uid)) {
4552                 mUidFirewallStandbyRules.put(uid, FIREWALL_RULE_DENY);
4553                 blockedUids.put(uid, FIREWALL_RULE_DENY);
4554             } else {
4555                 mUidFirewallStandbyRules.put(uid, FIREWALL_RULE_DEFAULT);
4556             }
4557             updateRulesForPowerRestrictionsUL(uid, isUidIdle);
4558         }
4559         setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, blockedUids,
4560                 enableChain ? CHAIN_TOGGLE_ENABLE : CHAIN_TOGGLE_DISABLE);
4561     }
4562 
4563     /**
4564      * Update rules that might be changed by {@link #mRestrictBackground},
4565      * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
4566      */
4567     @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
4568     private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
4569         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4570             Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4571                     "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
4572         }
4573         try {
4574             updateRulesForAppIdleUL();
4575             updateRulesForRestrictPowerUL();
4576             updateRulesForRestrictBackgroundUL();
4577             updateRestrictedModeAllowlistUL();
4578 
4579             // If the set of restricted networks may have changed, re-evaluate those.
4580             if (restrictedNetworksChanged) {
4581                 normalizePoliciesNL();
4582                 updateNetworkRulesNL();
4583             }
4584         } finally {
4585             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4586         }
4587     }
4588 
4589     @GuardedBy("mUidRulesFirstLock")
4590     private void handleDeviceIdleModeChangedUL(boolean enabled) {
4591         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
4592         try {
4593             updateRulesForDeviceIdleUL();
4594             if (enabled) {
4595                 forEachUid("updateRulesForRestrictPower", uid -> {
4596                     synchronized (mUidRulesFirstLock) {
4597                         updateRulesForPowerRestrictionsUL(uid);
4598                     }
4599                 });
4600             } else {
4601                 // TODO: Note that we could handle the case of enabling-doze state similar
4602                 // to this but first, we need to update how we listen to uid state changes
4603                 // so that we always get a callback when a process moves from a NONEXISTENT state
4604                 // to a "background" state.
4605                 handleDeviceIdleModeDisabledUL();
4606             }
4607         } finally {
4608             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4609         }
4610     }
4611 
4612     @GuardedBy("mUidRulesFirstLock")
4613     private void handleDeviceIdleModeDisabledUL() {
4614         Trace.traceBegin(TRACE_TAG_NETWORK, "handleDeviceIdleModeDisabledUL");
4615         try {
4616             final SparseArray<SomeArgs> uidStateUpdates = new SparseArray<>();
4617             synchronized (mUidBlockedState) {
4618                 final int size = mUidBlockedState.size();
4619                 for (int i = 0; i < size; ++i) {
4620                     final int uid = mUidBlockedState.keyAt(i);
4621                     final UidBlockedState uidBlockedState = mUidBlockedState.valueAt(i);
4622                     if ((uidBlockedState.blockedReasons & BLOCKED_REASON_DOZE) == 0) {
4623                         continue;
4624                     }
4625                     uidBlockedState.blockedReasons &= ~BLOCKED_REASON_DOZE;
4626                     final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
4627                     uidBlockedState.updateEffectiveBlockedReasons();
4628                     if (LOGV) {
4629                         Log.v(TAG, "handleDeviceIdleModeDisabled(" + uid + "); "
4630                                 + "newUidBlockedState=" + uidBlockedState
4631                                 + ", oldEffectiveBlockedReasons=" + oldEffectiveBlockedReasons);
4632                     }
4633                     if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
4634                         final SomeArgs someArgs = SomeArgs.obtain();
4635                         someArgs.argi1 = oldEffectiveBlockedReasons;
4636                         someArgs.argi2 = uidBlockedState.effectiveBlockedReasons;
4637                         someArgs.argi3 = uidBlockedState.deriveUidRules();
4638                         uidStateUpdates.append(uid, someArgs);
4639                         // TODO: Update the state for all changed uids together.
4640                         mActivityManagerInternal.onUidBlockedReasonsChanged(uid,
4641                                 uidBlockedState.effectiveBlockedReasons);
4642                     }
4643                 }
4644             }
4645             if (uidStateUpdates.size() != 0) {
4646                 mHandler.obtainMessage(MSG_UIDS_BLOCKED_REASONS_CHANGED, uidStateUpdates)
4647                         .sendToTarget();
4648             }
4649         } finally {
4650             Trace.traceEnd(TRACE_TAG_NETWORK);
4651         }
4652     }
4653 
4654     // TODO: rename / document to make it clear these are global (not app-specific) rules
4655     @GuardedBy("mUidRulesFirstLock")
4656     private void updateRulesForRestrictPowerUL() {
4657         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
4658         try {
4659             updateRulesForDeviceIdleUL();
4660             updateRulesForPowerSaveUL();
4661             forEachUid("updateRulesForRestrictPower",
4662                     uid -> updateRulesForPowerRestrictionsUL(uid));
4663         } finally {
4664             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4665         }
4666     }
4667 
4668     @GuardedBy("mUidRulesFirstLock")
4669     private void updateRulesForRestrictBackgroundUL() {
4670         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
4671         try {
4672             forEachUid("updateRulesForRestrictBackground",
4673                     uid -> updateRulesForDataUsageRestrictionsUL(uid));
4674         } finally {
4675             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4676         }
4677     }
4678 
4679     private void forEachUid(String tag, IntConsumer consumer) {
4680         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4681             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "forEachUid-" + tag);
4682         }
4683         try {
4684             // update rules for all installed applications
4685             final List<UserInfo> users;
4686 
4687             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
4688             try {
4689                 users = mUserManager.getUsers();
4690             } finally {
4691                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4692             }
4693             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "iterate-uids");
4694             try {
4695                 final PackageManagerInternal packageManagerInternal = LocalServices.getService(
4696                         PackageManagerInternal.class);
4697                 final int usersSize = users.size();
4698                 for (int i = 0; i < usersSize; ++i) {
4699                     final int userId = users.get(i).id;
4700                     final SparseBooleanArray sharedAppIdsHandled = new SparseBooleanArray();
4701                     packageManagerInternal.forEachInstalledPackage(androidPackage -> {
4702                         final int appId = androidPackage.getUid();
4703                         if (androidPackage.getSharedUserId() != null) {
4704                             if (sharedAppIdsHandled.indexOfKey(appId) < 0) {
4705                                 sharedAppIdsHandled.put(appId, true);
4706                             } else {
4707                                 return;
4708                             }
4709                         }
4710                         final int uid = UserHandle.getUid(userId, appId);
4711                         consumer.accept(uid);
4712                     }, userId);
4713                 }
4714             } finally {
4715                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4716             }
4717         } finally {
4718             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4719         }
4720     }
4721 
4722     @GuardedBy("mUidRulesFirstLock")
4723     private void updateRulesForTempWhitelistChangeUL(int appId) {
4724         final List<UserInfo> users = mUserManager.getUsers();
4725         final int numUsers = users.size();
4726         for (int i = 0; i < numUsers; i++) {
4727             final UserInfo user = users.get(i);
4728             int uid = UserHandle.getUid(user.id, appId);
4729             // Update external firewall rules.
4730             updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
4731             updateRuleForDeviceIdleUL(uid);
4732             updateRuleForRestrictPowerUL(uid);
4733             // Update internal rules.
4734             updateRulesForPowerRestrictionsUL(uid);
4735         }
4736     }
4737 
4738     // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
4739     // methods below could be merged into a isUidValidForRules() method.
4740     @GuardedBy("mUidRulesFirstLock")
4741     private boolean isUidValidForDenylistRulesUL(int uid) {
4742         // allow rules on specific system services, and any apps
4743         if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
4744                 || isUidValidForAllowlistRulesUL(uid)) {
4745             return true;
4746         }
4747 
4748         return false;
4749     }
4750 
4751     @GuardedBy("mUidRulesFirstLock")
4752     private boolean isUidValidForAllowlistRulesUL(int uid) {
4753         return UserHandle.isApp(uid) && hasInternetPermissionUL(uid);
4754     }
4755 
4756     /**
4757      * Set whether or not an app should be allowlisted for network access while in app idle. Other
4758      * power saving restrictions may still apply.
4759      */
4760     @VisibleForTesting
4761     void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
4762         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
4763 
4764         synchronized (mUidRulesFirstLock) {
4765             if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) {
4766                 // No change.
4767                 return;
4768             }
4769 
4770             final long token = Binder.clearCallingIdentity();
4771             try {
4772                 mLogger.appIdleWlChanged(uid, shouldWhitelist);
4773                 if (shouldWhitelist) {
4774                     mAppIdleTempWhitelistAppIds.put(uid, true);
4775                 } else {
4776                     mAppIdleTempWhitelistAppIds.delete(uid);
4777                 }
4778                 updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
4779                 updateRulesForPowerRestrictionsUL(uid);
4780             } finally {
4781                 Binder.restoreCallingIdentity(token);
4782             }
4783         }
4784     }
4785 
4786     /** Return the list of UIDs currently in the app idle allowlist. */
4787     @VisibleForTesting
4788     int[] getAppIdleWhitelist() {
4789         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
4790 
4791         synchronized (mUidRulesFirstLock) {
4792             final int len = mAppIdleTempWhitelistAppIds.size();
4793             int[] uids = new int[len];
4794             for (int i = 0; i < len; ++i) {
4795                 uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i);
4796             }
4797             return uids;
4798         }
4799     }
4800 
4801     /** Returns if the UID is currently considered idle. */
4802     @VisibleForTesting
4803     boolean isUidIdle(int uid) {
4804         return isUidIdle(uid, PROCESS_STATE_UNKNOWN);
4805     }
4806 
4807     private boolean isUidIdle(int uid, int uidProcessState) {
4808         synchronized (mUidRulesFirstLock) {
4809             if (uidProcessState != PROCESS_STATE_UNKNOWN && isProcStateConsideredInteraction(
4810                     uidProcessState)) {
4811                 return false;
4812             }
4813             if (mAppIdleTempWhitelistAppIds.get(uid)) {
4814                 // UID is temporarily allowlisted.
4815                 return false;
4816             }
4817         }
4818 
4819         final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
4820         final int userId = UserHandle.getUserId(uid);
4821 
4822         if (packages != null) {
4823             for (String packageName : packages) {
4824                 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
4825                     return false;
4826                 }
4827             }
4828         }
4829         return true;
4830     }
4831 
4832     /**
4833      * Checks if an uid has INTERNET permissions.
4834      * <p>
4835      * Useful for the cases where the lack of network access can simplify the rules.
4836      */
4837     @GuardedBy("mUidRulesFirstLock")
4838     private boolean hasInternetPermissionUL(int uid) {
4839         try {
4840             if (mInternetPermissionMap.get(uid)) {
4841                 return true;
4842             }
4843             // If the cache shows that uid doesn't have internet permission,
4844             // then always re-check with PackageManager just to be safe.
4845             final boolean hasPermission = mIPm.checkUidPermission(Manifest.permission.INTERNET,
4846                     uid) == PackageManager.PERMISSION_GRANTED;
4847             mInternetPermissionMap.put(uid, hasPermission);
4848             return hasPermission;
4849         } catch (RemoteException e) {
4850             // ignored; service lives in system_server
4851         }
4852         return true;
4853     }
4854 
4855     /**
4856      * Clears all state - internal and external - associated with an UID.
4857      */
4858     @GuardedBy("mUidRulesFirstLock")
4859     private void onUidDeletedUL(int uid) {
4860         // First cleanup in-memory state synchronously...
4861         synchronized (mUidBlockedState) {
4862             mUidBlockedState.delete(uid);
4863         }
4864         mUidState.delete(uid);
4865         mActivityManagerInternal.onUidBlockedReasonsChanged(uid, BLOCKED_REASON_NONE);
4866         mUidPolicy.delete(uid);
4867         mUidFirewallStandbyRules.delete(uid);
4868         mUidFirewallDozableRules.delete(uid);
4869         mUidFirewallPowerSaveRules.delete(uid);
4870         mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
4871         mPowerSaveWhitelistAppIds.delete(uid);
4872         mPowerSaveTempWhitelistAppIds.delete(uid);
4873         mAppIdleTempWhitelistAppIds.delete(uid);
4874         mUidFirewallRestrictedModeRules.delete(uid);
4875         mUidFirewallLowPowerStandbyModeRules.delete(uid);
4876         synchronized (mUidStateCallbackInfos) {
4877             mUidStateCallbackInfos.remove(uid);
4878         }
4879 
4880         // ...then update iptables asynchronously.
4881         mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
4882     }
4883 
4884     /**
4885      * Applies network rules to bandwidth and firewall controllers based on uid policy.
4886      *
4887      * <p>There are currently 4 types of restriction rules:
4888      * <ul>
4889      * <li>Doze mode
4890      * <li>App idle mode
4891      * <li>Battery Saver Mode (also referred as power save).
4892      * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
4893      * </ul>
4894      *
4895      * <p>This method changes both the external firewall rules and the internal state.
4896      */
4897     @GuardedBy("mUidRulesFirstLock")
4898     private void updateRestrictionRulesForUidUL(int uid) {
4899         // Methods below only changes the firewall rules for the power-related modes.
4900         updateRuleForDeviceIdleUL(uid);
4901         updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
4902         updateRuleForRestrictPowerUL(uid);
4903 
4904         // If the uid has the necessary permissions, then it should be added to the restricted mode
4905         // firewall allowlist.
4906         updateRestrictedModeForUidUL(uid);
4907 
4908         // Update internal state for power-related modes.
4909         updateRulesForPowerRestrictionsUL(uid);
4910 
4911         // Update firewall and internal rules for Data Saver Mode.
4912         updateRulesForDataUsageRestrictionsUL(uid);
4913     }
4914 
4915     /**
4916      * Applies network rules to bandwidth controllers based on process state and user-defined
4917      * restrictions (allowlist / denylist).
4918      *
4919      * <p>
4920      * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
4921      * networks:
4922      * <ul>
4923      * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (denylist).
4924      * <li>@{code bw_happy_box}: UIDs added to this chain have access (allowlist), unless they're
4925      *     also in denylist.
4926      * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
4927      *     no UIDs other than those in allowlist will have access.
4928      * <ul>
4929      *
4930      * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
4931      * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundAllowlistedUid(int)} /
4932      * {@link #removeRestrictBackgroundDenylistedUid(int)} methods (for denylist and allowlist
4933      * respectively): these methods set the proper internal state (denylist / allowlist), then call
4934      * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
4935      * {@link INetworkManagementService}, but this method should also be called in events (like
4936      * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
4937      * following rules should also be applied:
4938      *
4939      * <ul>
4940      * <li>When Data Saver mode is on, the foreground app should be temporarily added to
4941      *     {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
4942      * <li>If the foreground app was restricted by the user (i.e. has the policy
4943      *     {@code POLICY_REJECT_METERED_BACKGROUND}), it should be temporarily removed from
4944      *     {@code bw_penalty_box}.
4945      * <li>When the app leaves foreground state, the temporary changes above should be reverted.
4946      * </ul>
4947      *
4948      * <p>For optimization, the rules are only applied on user apps that have internet access
4949      * permission, since there is no need to change the {@code iptables} rule if the app does not
4950      * have permission to use the internet.
4951      *
4952      * <p>The {@link #mUidBlockedState} map is used to define the transition of states of an UID.
4953      *
4954      */
4955     private void updateRulesForDataUsageRestrictionsUL(int uid) {
4956         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4957             Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4958                     "updateRulesForDataUsageRestrictionsUL: " + uid);
4959         }
4960         try {
4961             updateRulesForDataUsageRestrictionsULInner(uid);
4962         } finally {
4963             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4964         }
4965     }
4966 
4967     @GuardedBy("mUidRulesFirstLock")
4968     private void updateRulesForDataUsageRestrictionsULInner(int uid) {
4969         if (!isUidValidForAllowlistRulesUL(uid)) {
4970             if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
4971             return;
4972         }
4973 
4974         final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
4975         final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
4976         final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
4977 
4978         final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
4979         final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
4980 
4981         int newBlockedReasons = BLOCKED_REASON_NONE;
4982         int newAllowedReasons = ALLOWED_REASON_NONE;
4983         newBlockedReasons |= (isRestrictedByAdmin ? BLOCKED_METERED_REASON_ADMIN_DISABLED : 0);
4984         newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0);
4985         newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0);
4986 
4987         newAllowedReasons |= (isSystem(uid) ? ALLOWED_METERED_REASON_SYSTEM : 0);
4988         newAllowedReasons |= (isForeground ? ALLOWED_METERED_REASON_FOREGROUND : 0);
4989         newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0);
4990 
4991         final int oldEffectiveBlockedReasons;
4992         final int newEffectiveBlockedReasons;
4993         final int oldAllowedReasons;
4994         final int uidRules;
4995         synchronized (mUidBlockedState) {
4996             final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid(
4997                     mUidBlockedState, uid);
4998             final UidBlockedState previousUidBlockedState = getOrCreateUidBlockedStateForUid(
4999                     mTmpUidBlockedState, uid);
5000             previousUidBlockedState.copyFrom(uidBlockedState);
5001 
5002             uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
5003                     & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
5004             uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
5005                     & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
5006             uidBlockedState.updateEffectiveBlockedReasons();
5007 
5008             oldEffectiveBlockedReasons = previousUidBlockedState.effectiveBlockedReasons;
5009             newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
5010             oldAllowedReasons = previousUidBlockedState.allowedReasons;
5011             uidRules = (oldEffectiveBlockedReasons == newEffectiveBlockedReasons)
5012                     ? RULE_NONE : uidBlockedState.deriveUidRules();
5013 
5014             if (LOGV) {
5015                 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
5016                         + ": isForeground=" + isForeground
5017                         + ", isDenied=" + isDenied
5018                         + ", isAllowed=" + isAllowed
5019                         + ", isRestrictedByAdmin=" + isRestrictedByAdmin
5020                         + ", oldBlockedState=" + previousUidBlockedState
5021                         + ", newBlockedState=" + uidBlockedState
5022                         + ", newBlockedMeteredReasons=" + blockedReasonsToString(newBlockedReasons)
5023                         + ", newAllowedMeteredReasons=" + allowedReasonsToString(
5024                                 newAllowedReasons));
5025             }
5026         }
5027         if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) {
5028             handleBlockedReasonsChanged(uid,
5029                     newEffectiveBlockedReasons, oldEffectiveBlockedReasons);
5030 
5031             postUidRulesChangedMsg(uid, uidRules);
5032         }
5033 
5034         // Note that the conditionals below are for avoiding unnecessary calls to netd.
5035         // TODO: Measure the performance for doing a no-op call to netd so that we can
5036         // remove the conditionals to simplify the logic below. We can also further reduce
5037         // some calls to netd if they turn out to be costly.
5038         final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED
5039                 | BLOCKED_METERED_REASON_USER_RESTRICTED;
5040         if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE
5041                 || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) {
5042             setMeteredNetworkDenylist(uid,
5043                     (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE);
5044         }
5045         final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND
5046                 | ALLOWED_METERED_REASON_USER_EXEMPTED;
5047         if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE
5048                 || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) {
5049             setMeteredNetworkAllowlist(uid,
5050                     (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE);
5051         }
5052     }
5053 
5054     /**
5055      * Updates the power-related part of the {@link #mUidBlockedState} for a given map, and
5056      * notify external listeners in case of change.
5057      * <p>
5058      * There are 3 power-related rules that affects whether an app has background access on
5059      * non-metered networks, and when the condition applies and the UID is not allowed for power
5060      * restriction, it's added to the equivalent firewall chain:
5061      * <ul>
5062      * <li>App is idle: {@code fw_standby} firewall chain.
5063      * <li>Device is idle: {@code fw_dozable} firewall chain.
5064      * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
5065      * </ul>
5066      * <p>
5067      * This method updates the power-related part of the {@link #mUidBlockedState} for a given
5068      * uid based on these modes, the UID process state (foreground or not), and the UID
5069      * allowlist state.
5070      * <p>
5071      * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
5072      */
5073     @GuardedBy("mUidRulesFirstLock")
5074     private void updateRulesForPowerRestrictionsUL(int uid) {
5075         updateRulesForPowerRestrictionsUL(uid, PROCESS_STATE_UNKNOWN);
5076     }
5077 
5078     @GuardedBy("mUidRulesFirstLock")
5079     private void updateRulesForPowerRestrictionsUL(int uid, int uidProcState) {
5080         updateRulesForPowerRestrictionsUL(uid, isUidIdle(uid, uidProcState));
5081     }
5082 
5083     /**
5084      * Similar to above but ignores idle state if app standby is currently disabled by parole.
5085      *
5086      * @param uid the uid of the app to update rules for
5087      * @param oldUidRules the current rules for the uid, in order to determine if there's a change
5088      * @param isUidIdle whether uid is idle or not
5089      */
5090     @GuardedBy("mUidRulesFirstLock")
5091     private void updateRulesForPowerRestrictionsUL(int uid, boolean isUidIdle) {
5092         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
5093             Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
5094                     "updateRulesForPowerRestrictionsUL: " + uid + "/"
5095                             + (isUidIdle ? "I" : "-"));
5096         }
5097         try {
5098             updateRulesForPowerRestrictionsULInner(uid, isUidIdle);
5099         } finally {
5100             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
5101         }
5102     }
5103 
5104     @GuardedBy("mUidRulesFirstLock")
5105     private void updateRulesForPowerRestrictionsULInner(int uid, boolean isUidIdle) {
5106         if (!isUidValidForDenylistRulesUL(uid)) {
5107             if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
5108             return;
5109         }
5110 
5111         final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
5112         final boolean isTop = isUidTop(uid);
5113 
5114         final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
5115 
5116         final int oldEffectiveBlockedReasons;
5117         final int newEffectiveBlockedReasons;
5118         final int uidRules;
5119         synchronized (mUidBlockedState) {
5120             final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid(
5121                     mUidBlockedState, uid);
5122             final UidBlockedState previousUidBlockedState = getOrCreateUidBlockedStateForUid(
5123                     mTmpUidBlockedState, uid);
5124             previousUidBlockedState.copyFrom(uidBlockedState);
5125 
5126             int newBlockedReasons = BLOCKED_REASON_NONE;
5127             int newAllowedReasons = ALLOWED_REASON_NONE;
5128             newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0);
5129             newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0);
5130             newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0);
5131             newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
5132             newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
5133 
5134             newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
5135             newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
5136             newAllowedReasons |= (isTop ? ALLOWED_REASON_TOP : 0);
5137             newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
5138                     ? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
5139             newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
5140                     ? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
5141             newAllowedReasons |= (uidBlockedState.allowedReasons
5142                     & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
5143             newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid))
5144                     ? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0;
5145 
5146             uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
5147                     & BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
5148             uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
5149                     & ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
5150             uidBlockedState.updateEffectiveBlockedReasons();
5151 
5152             if (LOGV) {
5153                 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
5154                         + ", isIdle: " + isUidIdle
5155                         + ", mRestrictPower: " + mRestrictPower
5156                         + ", mDeviceIdleMode: " + mDeviceIdleMode
5157                         + ", isForeground=" + isForeground
5158                         + ", isTop=" + isTop
5159                         + ", isWhitelisted=" + isWhitelisted
5160                         + ", oldUidBlockedState=" + previousUidBlockedState
5161                         + ", newUidBlockedState=" + uidBlockedState);
5162             }
5163 
5164             oldEffectiveBlockedReasons = previousUidBlockedState.effectiveBlockedReasons;
5165             newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
5166             uidRules = oldEffectiveBlockedReasons == newEffectiveBlockedReasons
5167                     ? RULE_NONE
5168                     : uidBlockedState.deriveUidRules();
5169         }
5170         if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) {
5171             handleBlockedReasonsChanged(uid,
5172                     newEffectiveBlockedReasons,
5173                     oldEffectiveBlockedReasons);
5174 
5175             postUidRulesChangedMsg(uid, uidRules);
5176         }
5177     }
5178 
5179     private class NetPolicyAppIdleStateChangeListener extends AppIdleStateChangeListener {
5180         @Override
5181         public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
5182                 int reason) {
5183             try {
5184                 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
5185                         PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
5186                 synchronized (mUidRulesFirstLock) {
5187                     mLogger.appIdleStateChanged(uid, idle);
5188                     updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
5189                     updateRulesForPowerRestrictionsUL(uid);
5190                 }
5191             } catch (NameNotFoundException nnfe) {
5192             }
5193         }
5194 
5195         @Override
5196         public void onParoleStateChanged(boolean isParoleOn) {
5197             synchronized (mUidRulesFirstLock) {
5198                 mLogger.paroleStateChanged(isParoleOn);
5199                 updateRulesForAppIdleParoleUL();
5200             }
5201         }
5202     }
5203 
5204     private void handleBlockedReasonsChanged(int uid, int newEffectiveBlockedReasons,
5205             int oldEffectiveBlockedReasons) {
5206         mActivityManagerInternal.onUidBlockedReasonsChanged(uid, newEffectiveBlockedReasons);
5207         postBlockedReasonsChangedMsg(uid, newEffectiveBlockedReasons, oldEffectiveBlockedReasons);
5208     }
5209 
5210     private void postBlockedReasonsChangedMsg(int uid, int newEffectiveBlockedReasons,
5211             int oldEffectiveBlockedReasons) {
5212         mHandler.obtainMessage(MSG_UID_BLOCKED_REASON_CHANGED, uid,
5213                 newEffectiveBlockedReasons, oldEffectiveBlockedReasons)
5214                 .sendToTarget();
5215     }
5216 
5217     private void postUidRulesChangedMsg(int uid, int uidRules) {
5218         mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules)
5219                 .sendToTarget();
5220     }
5221 
5222     private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
5223         try {
5224             listener.onUidRulesChanged(uid, uidRules);
5225         } catch (RemoteException ignored) {
5226             // Ignore if there is an error sending the callback to the client.
5227         }
5228     }
5229 
5230     private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
5231             String[] meteredIfaces) {
5232         try {
5233             listener.onMeteredIfacesChanged(meteredIfaces);
5234         } catch (RemoteException ignored) {
5235             // Ignore if there is an error sending the callback to the client.
5236         }
5237     }
5238 
5239     private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
5240             boolean restrictBackground) {
5241         try {
5242             listener.onRestrictBackgroundChanged(restrictBackground);
5243         } catch (RemoteException ignored) {
5244             // Ignore if there is an error sending the callback to the client.
5245         }
5246     }
5247 
5248     private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
5249             int uidPolicies) {
5250         try {
5251             listener.onUidPoliciesChanged(uid, uidPolicies);
5252         } catch (RemoteException ignored) {
5253             // Ignore if there is an error sending the callback to the client.
5254         }
5255     }
5256 
5257     private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
5258             int overrideMask, int overrideValue, int[] networkTypes) {
5259         try {
5260             listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
5261         } catch (RemoteException ignored) {
5262             // Ignore if there is an error sending the callback to the client.
5263         }
5264     }
5265 
5266     private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
5267             SubscriptionPlan[] plans) {
5268         try {
5269             listener.onSubscriptionPlansChanged(subId, plans);
5270         } catch (RemoteException ignored) {
5271             // Ignore if there is an error sending the callback to the client.
5272         }
5273     }
5274 
5275     private void dispatchBlockedReasonChanged(INetworkPolicyListener listener, int uid,
5276             int oldBlockedReasons, int newBlockedReasons) {
5277         try {
5278             listener.onBlockedReasonChanged(uid, oldBlockedReasons, newBlockedReasons);
5279         } catch (RemoteException ignored) {
5280             // Ignore if there is an error sending the callback to the client.
5281         }
5282     }
5283 
5284     private final Handler.Callback mHandlerCallback = new Handler.Callback() {
5285         @Override
5286         public boolean handleMessage(Message msg) {
5287             switch (msg.what) {
5288                 case MSG_RULES_CHANGED: {
5289                     final int uid = msg.arg1;
5290                     final int uidRules = msg.arg2;
5291                     if (LOGV) {
5292                         Slog.v(TAG, "Dispatching rules=" + uidRulesToString(uidRules)
5293                                 + " for uid=" + uid);
5294                     }
5295                     final int length = mListeners.beginBroadcast();
5296                     for (int i = 0; i < length; i++) {
5297                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5298                         dispatchUidRulesChanged(listener, uid, uidRules);
5299                     }
5300                     mListeners.finishBroadcast();
5301                     return true;
5302                 }
5303                 case MSG_METERED_IFACES_CHANGED: {
5304                     final String[] meteredIfaces = (String[]) msg.obj;
5305                     final int length = mListeners.beginBroadcast();
5306                     for (int i = 0; i < length; i++) {
5307                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5308                         dispatchMeteredIfacesChanged(listener, meteredIfaces);
5309                     }
5310                     mListeners.finishBroadcast();
5311                     return true;
5312                 }
5313                 case MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED: {
5314                     mNetworkStats.forceUpdate();
5315 
5316                     synchronized (mNetworkPoliciesSecondLock) {
5317                         // Some providers might hit the limit reached event prior to others. Thus,
5318                         // re-calculate and update interface quota for every provider is needed.
5319                         updateNetworkRulesNL();
5320                         updateNetworkEnabledNL();
5321                         updateNotificationsNL();
5322                     }
5323                     return true;
5324                 }
5325                 case MSG_LIMIT_REACHED: {
5326                     final String iface = (String) msg.obj;
5327                     synchronized (mMeteredIfacesLock) {
5328                         // fast return if not needed.
5329                         if (!mMeteredIfaces.contains(iface)) {
5330                             return true;
5331                         }
5332                     }
5333 
5334                     // force stats update to make sure the service have the numbers that caused
5335                     // alert to trigger.
5336                     mNetworkStats.forceUpdate();
5337 
5338                     synchronized (mNetworkPoliciesSecondLock) {
5339                         updateNetworkRulesNL();
5340                         updateNetworkEnabledNL();
5341                         updateNotificationsNL();
5342                     }
5343                     return true;
5344                 }
5345                 case MSG_RESTRICT_BACKGROUND_CHANGED: {
5346                     final boolean restrictBackground = msg.arg1 != 0;
5347                     final int length = mListeners.beginBroadcast();
5348                     for (int i = 0; i < length; i++) {
5349                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5350                         dispatchRestrictBackgroundChanged(listener, restrictBackground);
5351                     }
5352                     mListeners.finishBroadcast();
5353                     final Intent intent =
5354                             new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
5355                     intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
5356                     mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
5357                     return true;
5358                 }
5359                 case MSG_POLICIES_CHANGED: {
5360                     final int uid = msg.arg1;
5361                     final int policy = msg.arg2;
5362                     final Boolean notifyApp = (Boolean) msg.obj;
5363                     // First notify internal listeners...
5364                     final int length = mListeners.beginBroadcast();
5365                     for (int i = 0; i < length; i++) {
5366                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5367                         dispatchUidPoliciesChanged(listener, uid, policy);
5368                     }
5369                     mListeners.finishBroadcast();
5370                     // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
5371                     if (notifyApp.booleanValue()) {
5372                         broadcastRestrictBackgroundChanged(uid, notifyApp);
5373                     }
5374                     return true;
5375                 }
5376                 case MSG_ADVISE_PERSIST_THRESHOLD: {
5377                     final long lowestRule = (Long) msg.obj;
5378                     // make sure stats are recorded frequently enough; we aim
5379                     // for 2MB threshold for 2GB/month rules.
5380                     final long persistThreshold = lowestRule / 1000;
5381                     // TODO: Sync internal naming with the API surface.
5382                     mNetworkStats.setDefaultGlobalAlert(persistThreshold);
5383                     return true;
5384                 }
5385                 case MSG_UPDATE_INTERFACE_QUOTAS: {
5386                     final IfaceQuotas val = (IfaceQuotas) msg.obj;
5387                     // TODO: Consider set a new limit before removing the original one.
5388                     removeInterfaceLimit(val.iface);
5389                     setInterfaceLimit(val.iface, val.limit);
5390                     mNetworkStats.setStatsProviderWarningAndLimitAsync(val.iface, val.warning,
5391                             val.limit);
5392                     return true;
5393                 }
5394                 case MSG_REMOVE_INTERFACE_QUOTAS: {
5395                     final String iface = (String) msg.obj;
5396                     removeInterfaceLimit(iface);
5397                     mNetworkStats.setStatsProviderWarningAndLimitAsync(iface, QUOTA_UNLIMITED,
5398                             QUOTA_UNLIMITED);
5399                     return true;
5400                 }
5401                 case MSG_RESET_FIREWALL_RULES_BY_UID: {
5402                     resetUidFirewallRules(msg.arg1);
5403                     return true;
5404                 }
5405                 case MSG_SUBSCRIPTION_OVERRIDE: {
5406                     final SomeArgs args = (SomeArgs) msg.obj;
5407                     final int subId = (int) args.arg1;
5408                     final int overrideMask = (int) args.arg2;
5409                     final int overrideValue = (int) args.arg3;
5410                     final int[] networkTypes = (int[]) args.arg4;
5411                     final int length = mListeners.beginBroadcast();
5412                     for (int i = 0; i < length; i++) {
5413                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5414                         dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue,
5415                                 networkTypes);
5416                     }
5417                     mListeners.finishBroadcast();
5418                     return true;
5419                 }
5420                 case MSG_METERED_RESTRICTED_PACKAGES_CHANGED: {
5421                     final int userId = msg.arg1;
5422                     final Set<String> packageNames = (Set<String>) msg.obj;
5423                     setMeteredRestrictedPackagesInternal(packageNames, userId);
5424                     return true;
5425                 }
5426                 case MSG_SET_NETWORK_TEMPLATE_ENABLED: {
5427                     final NetworkTemplate template = (NetworkTemplate) msg.obj;
5428                     final boolean enabled = msg.arg1 != 0;
5429                     setNetworkTemplateEnabledInner(template, enabled);
5430                     return true;
5431                 }
5432                 case MSG_SUBSCRIPTION_PLANS_CHANGED: {
5433                     final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj;
5434                     final int subId = msg.arg1;
5435                     final int length = mListeners.beginBroadcast();
5436                     for (int i = 0; i < length; i++) {
5437                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5438                         dispatchSubscriptionPlansChanged(listener, subId, plans);
5439                     }
5440                     mListeners.finishBroadcast();
5441                     return true;
5442                 }
5443                 case MSG_CLEAR_SUBSCRIPTION_PLANS: {
5444                     synchronized (mUidRulesFirstLock) {
5445                         synchronized (mNetworkPoliciesSecondLock) {
5446                             int subId = msg.arg1;
5447                             if (msg.arg2 == mSetSubscriptionPlansIds.get(subId)) {
5448                                 if (LOGD) Slog.d(TAG, "Clearing expired subscription plans.");
5449                                 setSubscriptionPlansInternal(subId, new SubscriptionPlan[]{},
5450                                         0 /* expirationDurationMillis */,
5451                                         (String) msg.obj /* callingPackage */);
5452                             } else {
5453                                 if (LOGD) Slog.d(TAG, "Ignoring stale CLEAR_SUBSCRIPTION_PLANS.");
5454                             }
5455                         }
5456                     }
5457                     return true;
5458                 }
5459                 case MSG_UID_BLOCKED_REASON_CHANGED: {
5460                     final int uid = msg.arg1;
5461                     final int newBlockedReasons = msg.arg2;
5462                     final int oldBlockedReasons = (int) msg.obj;
5463                     final int length = mListeners.beginBroadcast();
5464                     for (int i = 0; i < length; i++) {
5465                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5466                         dispatchBlockedReasonChanged(listener, uid,
5467                                 oldBlockedReasons, newBlockedReasons);
5468                     }
5469                     mListeners.finishBroadcast();
5470                     return true;
5471                 }
5472                 case MSG_UIDS_BLOCKED_REASONS_CHANGED: {
5473                     final SparseArray<SomeArgs> uidStateUpdates = (SparseArray<SomeArgs>) msg.obj;
5474                     final int uidsSize = uidStateUpdates.size();
5475                     final int listenersSize = mListeners.beginBroadcast();
5476                     for (int i = 0; i < listenersSize; ++i) {
5477                         final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
5478                         for (int uidIndex = 0; uidIndex < uidsSize; ++uidIndex) {
5479                             final int uid = uidStateUpdates.keyAt(uidIndex);
5480                             final SomeArgs someArgs = uidStateUpdates.valueAt(uidIndex);
5481                             final int oldBlockedReasons = someArgs.argi1;
5482                             final int newBlockedReasons = someArgs.argi2;
5483                             final int uidRules = someArgs.argi3;
5484 
5485                             dispatchBlockedReasonChanged(listener, uid,
5486                                     oldBlockedReasons, newBlockedReasons);
5487                             if (LOGV) {
5488                                 Slog.v(TAG, "Dispatching rules=" + uidRulesToString(uidRules)
5489                                         + " for uid=" + uid);
5490                             }
5491                             dispatchUidRulesChanged(listener, uid, uidRules);
5492                         }
5493                     }
5494                     mListeners.finishBroadcast();
5495 
5496                     for (int uidIndex = 0; uidIndex < uidsSize; ++uidIndex) {
5497                         uidStateUpdates.valueAt(uidIndex).recycle();
5498                     }
5499                     return true;
5500                 }
5501                 default: {
5502                     return false;
5503                 }
5504             }
5505         }
5506     };
5507 
5508     private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
5509         @Override
5510         public boolean handleMessage(Message msg) {
5511             switch (msg.what) {
5512                 case UID_MSG_STATE_CHANGED: {
5513                     handleUidChanged((UidStateCallbackInfo) msg.obj);
5514                     return true;
5515                 }
5516                 case UID_MSG_GONE: {
5517                     final int uid = msg.arg1;
5518                     handleUidGone(uid);
5519                     return true;
5520                 }
5521                 default: {
5522                     return false;
5523                 }
5524             }
5525         }
5526     };
5527 
5528     void handleUidChanged(@NonNull UidStateCallbackInfo uidStateCallbackInfo) {
5529         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
5530         try {
5531             boolean updated;
5532             final int uid;
5533             final int procState;
5534             final long procStateSeq;
5535             final int capability;
5536             synchronized (mUidRulesFirstLock) {
5537                 synchronized (mUidStateCallbackInfos) {
5538                     uid = uidStateCallbackInfo.uid;
5539                     procState = uidStateCallbackInfo.procState;
5540                     procStateSeq = uidStateCallbackInfo.procStateSeq;
5541                     capability = uidStateCallbackInfo.capability;
5542                     uidStateCallbackInfo.isPending = false;
5543                 }
5544 
5545                 // We received a uid state change callback, add it to the history so that it
5546                 // will be useful for debugging.
5547                 mLogger.uidStateChanged(uid, procState, procStateSeq, capability);
5548                 // Now update the network policy rules as per the updated uid state.
5549                 updated = updateUidStateUL(uid, procState, procStateSeq, capability);
5550                 // Updating the network rules is done, so notify AMS about this.
5551                 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
5552             }
5553             // Do this without the lock held. handleUidChanged() and handleUidGone() are
5554             // called from the handler, so there's no multi-threading issue.
5555             if (updated) {
5556                 updateNetworkStats(uid, isProcStateAllowedWhileOnRestrictBackground(procState));
5557             }
5558         } finally {
5559             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
5560         }
5561     }
5562 
5563     void handleUidGone(int uid) {
5564         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
5565         try {
5566             boolean updated;
5567             synchronized (mUidRulesFirstLock) {
5568                 updated = removeUidStateUL(uid);
5569             }
5570             // Do this without the lock held. handleUidChanged() and handleUidGone() are
5571             // called from the handler, so there's no multi-threading issue.
5572             if (updated) {
5573                 updateNetworkStats(uid, false);
5574             }
5575         } finally {
5576             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
5577         }
5578     }
5579 
5580     private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
5581         final PackageManager pm = mContext.getPackageManager();
5582         final String[] packages = pm.getPackagesForUid(uid);
5583         if (packages != null) {
5584             final int userId = UserHandle.getUserId(uid);
5585             for (String packageName : packages) {
5586                 final Intent intent =
5587                         new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
5588                 intent.setPackage(packageName);
5589                 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
5590                 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
5591             }
5592         }
5593     }
5594 
5595     private static final class IfaceQuotas {
5596         @NonNull public final String iface;
5597         // Warning and limit bytes of interface qutoas, could be QUOTA_UNLIMITED or Long.MAX_VALUE
5598         // if not set. 0 is not acceptable since kernel doesn't like 0-byte rules.
5599         public final long warning;
5600         public final long limit;
5601 
5602         private IfaceQuotas(@NonNull String iface, long warning, long limit) {
5603             this.iface = iface;
5604             this.warning = warning;
5605             this.limit = limit;
5606         }
5607     }
5608 
5609     private void setInterfaceQuotasAsync(@NonNull String iface,
5610             long warningBytes, long limitBytes) {
5611         mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTAS,
5612                 new IfaceQuotas(iface, warningBytes, limitBytes)).sendToTarget();
5613     }
5614 
5615     private void setInterfaceLimit(String iface, long limitBytes) {
5616         try {
5617             // For legacy design the data warning is covered by global alert, where the
5618             // kernel will notify upper layer for a small amount of change of traffic
5619             // statistics. Thus, passing warning is not needed.
5620             mNetworkManager.setInterfaceQuota(iface, limitBytes);
5621         } catch (IllegalStateException e) {
5622             Log.wtf(TAG, "problem setting interface quota", e);
5623         } catch (RemoteException e) {
5624             // ignored; service lives in system_server
5625         }
5626     }
5627 
5628     private void removeInterfaceQuotasAsync(String iface) {
5629         mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTAS, iface).sendToTarget();
5630     }
5631 
5632     private void removeInterfaceLimit(String iface) {
5633         try {
5634             mNetworkManager.removeInterfaceQuota(iface);
5635         } catch (IllegalStateException e) {
5636             Log.wtf(TAG, "problem removing interface quota", e);
5637         } catch (RemoteException e) {
5638             // ignored; service lives in system_server
5639         }
5640     }
5641 
5642     private void setMeteredNetworkDenylist(int uid, boolean enable) {
5643         if (LOGV) Slog.v(TAG, "setMeteredNetworkDenylist " + uid + ": " + enable);
5644         try {
5645             mNetworkManager.setUidOnMeteredNetworkDenylist(uid, enable);
5646             mLogger.meteredDenylistChanged(uid, enable);
5647             if (Process.isApplicationUid(uid)) {
5648                 final int sdkSandboxUid = Process.toSdkSandboxUid(uid);
5649                 mNetworkManager.setUidOnMeteredNetworkDenylist(sdkSandboxUid, enable);
5650                 mLogger.meteredDenylistChanged(sdkSandboxUid, enable);
5651             }
5652         } catch (IllegalStateException e) {
5653             Log.wtf(TAG, "problem setting denylist (" + enable + ") rules for " + uid, e);
5654         } catch (RemoteException e) {
5655             // ignored; service lives in system_server
5656         }
5657     }
5658 
5659     private void setMeteredNetworkAllowlist(int uid, boolean enable) {
5660         if (LOGV) Slog.v(TAG, "setMeteredNetworkAllowlist " + uid + ": " + enable);
5661         try {
5662             mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, enable);
5663             mLogger.meteredAllowlistChanged(uid, enable);
5664             if (Process.isApplicationUid(uid)) {
5665                 final int sdkSandboxUid = Process.toSdkSandboxUid(uid);
5666                 mNetworkManager.setUidOnMeteredNetworkAllowlist(sdkSandboxUid, enable);
5667                 mLogger.meteredAllowlistChanged(sdkSandboxUid, enable);
5668             }
5669         } catch (IllegalStateException e) {
5670             Log.wtf(TAG, "problem setting allowlist (" + enable + ") rules for " + uid, e);
5671         } catch (RemoteException e) {
5672             // ignored; service lives in system_server
5673         }
5674     }
5675 
5676     private static final int CHAIN_TOGGLE_NONE = 0;
5677     private static final int CHAIN_TOGGLE_ENABLE = 1;
5678     private static final int CHAIN_TOGGLE_DISABLE = 2;
5679     @Retention(RetentionPolicy.SOURCE)
5680     @IntDef(flag = false, value = {
5681             CHAIN_TOGGLE_NONE,
5682             CHAIN_TOGGLE_ENABLE,
5683             CHAIN_TOGGLE_DISABLE
5684     })
5685     public @interface ChainToggleType {
5686     }
5687 
5688     /**
5689      * Calls {@link #setUidFirewallRulesUL(int, SparseIntArray)} and
5690      * {@link #enableFirewallChainUL(int, boolean)} synchronously.
5691      *
5692      * @param chain firewall chain.
5693      * @param uidRules new UID rules; if {@code null}, only toggles chain state.
5694      * @param toggle whether the chain should be enabled, disabled, or not changed.
5695      */
5696     @GuardedBy("mUidRulesFirstLock")
5697     private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,
5698             @ChainToggleType int toggle) {
5699         if (uidRules != null) {
5700             setUidFirewallRulesUL(chain, uidRules);
5701         }
5702         if (toggle != CHAIN_TOGGLE_NONE) {
5703             enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
5704         }
5705     }
5706 
5707     private void addSdkSandboxUidsIfNeeded(SparseIntArray uidRules) {
5708         final int size = uidRules.size();
5709         final SparseIntArray sdkSandboxUids = new SparseIntArray();
5710         for (int index = 0; index < size; index++) {
5711             final int uid = uidRules.keyAt(index);
5712             final int rule = uidRules.valueAt(index);
5713             if (Process.isApplicationUid(uid)) {
5714                 sdkSandboxUids.put(Process.toSdkSandboxUid(uid), rule);
5715             }
5716         }
5717 
5718         for (int index = 0; index < sdkSandboxUids.size(); index++) {
5719             final int uid = sdkSandboxUids.keyAt(index);
5720             final int rule = sdkSandboxUids.valueAt(index);
5721             uidRules.put(uid, rule);
5722         }
5723     }
5724 
5725     /**
5726      * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
5727      * here to netd.  It will clean up dead rules and make sure the target chain only contains rules
5728      * specified here.
5729      */
5730     private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
5731         addSdkSandboxUidsIfNeeded(uidRules);
5732         try {
5733             int size = uidRules.size();
5734             int[] uids = new int[size];
5735             int[] rules = new int[size];
5736             for(int index = size - 1; index >= 0; --index) {
5737                 uids[index] = uidRules.keyAt(index);
5738                 rules[index] = uidRules.valueAt(index);
5739             }
5740             mNetworkManager.setFirewallUidRules(chain, uids, rules);
5741             mLogger.firewallRulesChanged(chain, uids, rules);
5742         } catch (IllegalStateException e) {
5743             Log.wtf(TAG, "problem setting firewall uid rules", e);
5744         } catch (RemoteException e) {
5745             // ignored; service lives in system_server
5746         }
5747     }
5748 
5749     /**
5750      * Add or remove a uid to the firewall denylist for all network ifaces.
5751      */
5752     @GuardedBy("mUidRulesFirstLock")
5753     private void setUidFirewallRuleUL(int chain, int uid, int rule) {
5754         if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
5755             Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
5756                     "setUidFirewallRuleUL: " + chain + "/" + uid + "/" + rule);
5757         }
5758         try {
5759             if (chain == FIREWALL_CHAIN_DOZABLE) {
5760                 mUidFirewallDozableRules.put(uid, rule);
5761             } else if (chain == FIREWALL_CHAIN_STANDBY) {
5762                 mUidFirewallStandbyRules.put(uid, rule);
5763             } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
5764                 mUidFirewallPowerSaveRules.put(uid, rule);
5765             } else if (chain == FIREWALL_CHAIN_RESTRICTED) {
5766                 mUidFirewallRestrictedModeRules.put(uid, rule);
5767             } else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) {
5768                 mUidFirewallLowPowerStandbyModeRules.put(uid, rule);
5769             }
5770 
5771             try {
5772                 mNetworkManager.setFirewallUidRule(chain, uid, rule);
5773                 mLogger.uidFirewallRuleChanged(chain, uid, rule);
5774                 if (Process.isApplicationUid(uid)) {
5775                     final int sdkSandboxUid = Process.toSdkSandboxUid(uid);
5776                     mNetworkManager.setFirewallUidRule(chain, sdkSandboxUid, rule);
5777                     mLogger.uidFirewallRuleChanged(chain, sdkSandboxUid, rule);
5778                 }
5779             } catch (IllegalStateException e) {
5780                 Log.wtf(TAG, "problem setting firewall uid rules", e);
5781             } catch (RemoteException e) {
5782                 // ignored; service lives in system_server
5783             }
5784         } finally {
5785             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
5786         }
5787     }
5788 
5789     /**
5790      * Add or remove a uid to the firewall denylist for all network ifaces.
5791      */
5792     @GuardedBy("mUidRulesFirstLock")
5793     private void enableFirewallChainUL(int chain, boolean enable) {
5794         if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
5795                 mFirewallChainStates.get(chain) == enable) {
5796             // All is the same, nothing to do.
5797             return;
5798         }
5799         mFirewallChainStates.put(chain, enable);
5800         try {
5801             mNetworkManager.setFirewallChainEnabled(chain, enable);
5802             mLogger.firewallChainEnabled(chain, enable);
5803         } catch (IllegalStateException e) {
5804             Log.wtf(TAG, "problem enable firewall chain", e);
5805         } catch (RemoteException e) {
5806             // ignored; service lives in system_server
5807         }
5808     }
5809 
5810     /**
5811      * Resets all firewall rules associated with an UID.
5812      */
5813     private void resetUidFirewallRules(int uid) {
5814         try {
5815             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid,
5816                     FIREWALL_RULE_DEFAULT);
5817             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid,
5818                     FIREWALL_RULE_DEFAULT);
5819             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid,
5820                     FIREWALL_RULE_DEFAULT);
5821             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, uid,
5822                     FIREWALL_RULE_DEFAULT);
5823             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid,
5824                     FIREWALL_RULE_DEFAULT);
5825             mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
5826             mLogger.meteredAllowlistChanged(uid, false);
5827             mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
5828             mLogger.meteredDenylistChanged(uid, false);
5829         } catch (IllegalStateException e) {
5830             Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
5831         } catch (RemoteException e) {
5832             // ignored; service lives in system_server
5833         }
5834         if (Process.isApplicationUid(uid)) {
5835             resetUidFirewallRules(Process.toSdkSandboxUid(uid));
5836         }
5837     }
5838 
5839     @Deprecated
5840     private long getTotalBytes(NetworkTemplate template, long start, long end) {
5841         // Skip if not ready. NetworkStatsService will block public API calls until it is
5842         // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
5843         if (!mStatsCallback.isAnyCallbackReceived()) return 0;
5844         return mDeps.getNetworkTotalBytes(template, start, end);
5845     }
5846 
5847     private boolean isBandwidthControlEnabled() {
5848         final long token = Binder.clearCallingIdentity();
5849         try {
5850             return mNetworkManager.isBandwidthControlEnabled();
5851         } catch (RemoteException e) {
5852             // ignored; service lives in system_server
5853             return false;
5854         } finally {
5855             Binder.restoreCallingIdentity(token);
5856         }
5857     }
5858 
5859     private static Intent buildSnoozeWarningIntent(NetworkTemplate template, String targetPackage) {
5860         final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
5861         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
5862         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5863         intent.setPackage(targetPackage);
5864         return intent;
5865     }
5866 
5867     private static Intent buildSnoozeRapidIntent(NetworkTemplate template, String targetPackage) {
5868         final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
5869         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
5870         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5871         intent.setPackage(targetPackage);
5872         return intent;
5873     }
5874 
5875     private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) {
5876         final Intent intent = new Intent();
5877         intent.setComponent(ComponentName.unflattenFromString(
5878                 res.getString(R.string.config_networkOverLimitComponent)));
5879         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5880         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5881         return intent;
5882     }
5883 
5884     private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) {
5885         final Intent intent = new Intent();
5886         intent.setComponent(ComponentName.unflattenFromString(
5887                 res.getString(R.string.config_dataUsageSummaryComponent)));
5888         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5889         intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5890         return intent;
5891     }
5892 
5893     @VisibleForTesting
5894     void addIdleHandler(IdleHandler handler) {
5895         mHandler.getLooper().getQueue().addIdleHandler(handler);
5896     }
5897 
5898     @GuardedBy("mUidRulesFirstLock")
5899     @VisibleForTesting
5900     void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
5901         if (mRestrictBackgroundLowPowerMode == result.batterySaverEnabled) {
5902             // Nothing changed. Nothing to do.
5903             return;
5904         }
5905         mRestrictBackgroundLowPowerMode = result.batterySaverEnabled;
5906 
5907         boolean restrictBackground = mRestrictBackgroundLowPowerMode;
5908         boolean shouldInvokeRestrictBackground;
5909         // store the temporary mRestrictBackgroundChangedInBsm and update it at the end.
5910         boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
5911 
5912         if (mRestrictBackgroundLowPowerMode) {
5913             // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
5914             // turn it on.
5915             shouldInvokeRestrictBackground = !mRestrictBackground;
5916             mRestrictBackgroundBeforeBsm = mRestrictBackground;
5917             localRestrictBgChangedInBsm = false;
5918         } else {
5919             // Try to restore the restrictBackground if it doesn't change in bsm
5920             shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
5921             restrictBackground = mRestrictBackgroundBeforeBsm;
5922         }
5923 
5924         if (shouldInvokeRestrictBackground) {
5925             setRestrictBackgroundUL(restrictBackground, "low_power");
5926         }
5927 
5928         // Change it at last so setRestrictBackground() won't affect this variable
5929         mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
5930     }
5931 
5932     private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
5933         final int size = source.size();
5934         for (int i = 0; i < size; i++) {
5935             target.put(source.keyAt(i), true);
5936         }
5937     }
5938 
5939     private static <T> void collectKeys(SparseArray<T> source, SparseBooleanArray target) {
5940         final int size = source.size();
5941         for (int i = 0; i < size; i++) {
5942             target.put(source.keyAt(i), true);
5943         }
5944     }
5945 
5946     @Override
5947     public void factoryReset(String subscriber) {
5948         mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
5949 
5950         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
5951             return;
5952         }
5953 
5954         // Turn carrier/mobile data limit off
5955         NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
5956         NetworkTemplate templateCarrier = subscriber != null
5957                 ? buildTemplateCarrierMetered(subscriber) : null;
5958         NetworkTemplate templateMobile = subscriber != null
5959                 ? new NetworkTemplate.Builder(MATCH_MOBILE)
5960                 .setSubscriberIds(Set.of(subscriber))
5961                 .setMeteredness(android.net.NetworkStats.METERED_YES)
5962                 .build() : null;
5963         for (NetworkPolicy policy : policies) {
5964             //  All policies loaded from disk will be carrier templates, and setting will also only
5965             //  set carrier templates, but we clear mobile templates just in case one is set by
5966             //  some other caller
5967             if (policy.template.equals(templateCarrier) || policy.template.equals(templateMobile)) {
5968                 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
5969                 policy.inferred = false;
5970                 policy.clearSnooze();
5971             }
5972         }
5973         setNetworkPolicies(policies);
5974 
5975         // Turn restrict background data off
5976         setRestrictBackground(false);
5977 
5978         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
5979             // Remove app's "restrict background data" flag
5980             for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
5981                 setUidPolicy(uid, POLICY_NONE);
5982             }
5983         }
5984     }
5985 
5986     @Override
5987     public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
5988         final long startTime = mStatLogger.getTime();
5989 
5990         mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
5991         int blockedReasons;
5992         synchronized (mUidBlockedState) {
5993             final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
5994             blockedReasons = uidBlockedState == null
5995                     ? BLOCKED_REASON_NONE : uidBlockedState.effectiveBlockedReasons;
5996             if (!isNetworkMetered) {
5997                 blockedReasons &= ~BLOCKED_METERED_REASON_MASK;
5998             }
5999             mLogger.networkBlocked(uid, uidBlockedState);
6000         }
6001 
6002         mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
6003 
6004         return blockedReasons != BLOCKED_REASON_NONE;
6005     }
6006 
6007     @Override
6008     public boolean isUidRestrictedOnMeteredNetworks(int uid) {
6009         mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
6010         synchronized (mUidBlockedState) {
6011             final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
6012             int blockedReasons = uidBlockedState == null
6013                     ? BLOCKED_REASON_NONE : uidBlockedState.effectiveBlockedReasons;
6014             blockedReasons &= BLOCKED_METERED_REASON_MASK;
6015             return blockedReasons != BLOCKED_REASON_NONE;
6016         }
6017     }
6018 
6019     private static boolean isSystem(int uid) {
6020         return uid < Process.FIRST_APPLICATION_UID;
6021     }
6022 
6023     private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
6024 
6025         @Override
6026         public void resetUserState(int userId) {
6027             synchronized (mUidRulesFirstLock) {
6028                 boolean changed = removeUserStateUL(userId, false, true);
6029                 changed = addDefaultRestrictBackgroundAllowlistUidsUL(userId) || changed;
6030                 if (changed) {
6031                     synchronized (mNetworkPoliciesSecondLock) {
6032                         writePolicyAL();
6033                     }
6034                 }
6035             }
6036         }
6037 
6038         @Override
6039         public void onTempPowerSaveWhitelistChange(int appId, boolean added,
6040                 @ReasonCode int reasonCode, @Nullable String reason) {
6041             synchronized (mUidRulesFirstLock) {
6042                 if (!mSystemReady) {
6043                     return;
6044                 }
6045                 mLogger.tempPowerSaveWlChanged(appId, added, reasonCode, reason);
6046                 if (added) {
6047                     mPowerSaveTempWhitelistAppIds.put(appId, true);
6048                 } else {
6049                     mPowerSaveTempWhitelistAppIds.delete(appId);
6050                 }
6051                 updateRulesForTempWhitelistChangeUL(appId);
6052             }
6053         }
6054 
6055         @Override
6056         public SubscriptionPlan getSubscriptionPlan(Network network) {
6057             synchronized (mNetworkPoliciesSecondLock) {
6058                 final int subId = getSubIdLocked(network);
6059                 return getPrimarySubscriptionPlanLocked(subId);
6060             }
6061         }
6062 
6063         @Override
6064         public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
6065             final long quotaBytes;
6066             synchronized (mNetworkPoliciesSecondLock) {
6067                 quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
6068                         OPPORTUNISTIC_QUOTA_UNKNOWN);
6069             }
6070             if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
6071                 return OPPORTUNISTIC_QUOTA_UNKNOWN;
6072             }
6073 
6074             if (quotaType == QUOTA_TYPE_JOBS) {
6075                 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
6076                         NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
6077             } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
6078                 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
6079                         NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
6080             } else {
6081                 return OPPORTUNISTIC_QUOTA_UNKNOWN;
6082             }
6083         }
6084 
6085         @Override
6086         public void onAdminDataAvailable() {
6087             mAdminDataAvailableLatch.countDown();
6088         }
6089 
6090         @Override
6091         public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
6092             NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist);
6093         }
6094 
6095         @Override
6096         public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) {
6097             setMeteredRestrictedPackagesInternal(packageNames, userId);
6098         }
6099 
6100         @Override
6101         public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) {
6102             mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
6103                     userId, 0, packageNames).sendToTarget();
6104         }
6105 
6106         @Override
6107         public void setLowPowerStandbyActive(boolean active) {
6108             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setLowPowerStandbyActive");
6109             try {
6110                 synchronized (mUidRulesFirstLock) {
6111                     if (mLowPowerStandbyActive == active) {
6112                         return;
6113                     }
6114                     mLowPowerStandbyActive = active;
6115                     synchronized (mNetworkPoliciesSecondLock) {
6116                         if (!mSystemReady) return;
6117                     }
6118 
6119                     forEachUid("updateRulesForRestrictPower",
6120                             uid -> updateRulesForPowerRestrictionsUL(uid));
6121                     updateRulesForLowPowerStandbyUL();
6122                 }
6123             } finally {
6124                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
6125             }
6126         }
6127 
6128         @Override
6129         public void setLowPowerStandbyAllowlist(int[] uids) {
6130             synchronized (mUidRulesFirstLock) {
6131                 final SparseBooleanArray changedUids = new SparseBooleanArray();
6132                 for (int i = 0; i < mLowPowerStandbyAllowlistUids.size(); i++) {
6133                     final int oldUid = mLowPowerStandbyAllowlistUids.keyAt(i);
6134                     if (!ArrayUtils.contains(uids, oldUid)) {
6135                         changedUids.put(oldUid, true);
6136                     }
6137                 }
6138 
6139                 for (int i = 0; i < changedUids.size(); i++) {
6140                     final int deletedUid = changedUids.keyAt(i);
6141                     mLowPowerStandbyAllowlistUids.delete(deletedUid);
6142                 }
6143 
6144                 for (int newUid : uids) {
6145                     if (mLowPowerStandbyAllowlistUids.indexOfKey(newUid) < 0) {
6146                         changedUids.append(newUid, true);
6147                         mLowPowerStandbyAllowlistUids.append(newUid, true);
6148                     }
6149                 }
6150 
6151                 if (!mLowPowerStandbyActive) {
6152                     return;
6153                 }
6154 
6155                 synchronized (mNetworkPoliciesSecondLock) {
6156                     if (!mSystemReady) return;
6157                 }
6158 
6159                 for (int i = 0; i < changedUids.size(); i++) {
6160                     final int changedUid = changedUids.keyAt(i);
6161                     updateRulesForPowerRestrictionsUL(changedUid);
6162                     updateRuleForLowPowerStandbyUL(changedUid);
6163                 }
6164             }
6165         }
6166     }
6167 
6168     private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
6169         synchronized (mUidRulesFirstLock) {
6170             final Set<Integer> newRestrictedUids = new ArraySet<>();
6171             for (String packageName : packageNames) {
6172                 final int uid = getUidForPackage(packageName, userId);
6173                 if (uid >= 0) {
6174                     newRestrictedUids.add(uid);
6175                 }
6176             }
6177             final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId);
6178             mMeteredRestrictedUids.put(userId, newRestrictedUids);
6179             handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids);
6180             mLogger.meteredRestrictedPkgsChanged(newRestrictedUids);
6181         }
6182     }
6183 
6184     private int getUidForPackage(String packageName, int userId) {
6185         try {
6186             return mContext.getPackageManager().getPackageUidAsUser(packageName,
6187                     PackageManager.MATCH_KNOWN_PACKAGES, userId);
6188         } catch (NameNotFoundException e) {
6189             return -1;
6190         }
6191     }
6192 
6193     @GuardedBy("mNetworkPoliciesSecondLock")
6194     private int getSubIdLocked(Network network) {
6195         return mNetIdToSubId.get(network.getNetId(), INVALID_SUBSCRIPTION_ID);
6196     }
6197 
6198     @GuardedBy("mNetworkPoliciesSecondLock")
6199     private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) {
6200         final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
6201         if (!ArrayUtils.isEmpty(plans)) {
6202             for (SubscriptionPlan plan : plans) {
6203                 if (plan.getCycleRule().isRecurring()) {
6204                     // Recurring plans will always have an active cycle
6205                     return plan;
6206                 } else {
6207                     // Non-recurring plans need manual test for active cycle
6208                     final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
6209                     if (cycle.contains(ZonedDateTime.now(mClock))) {
6210                         return plan;
6211                     }
6212                 }
6213             }
6214         }
6215         return null;
6216     }
6217 
6218     /**
6219      * This will only ever be called once - during device boot.
6220      */
6221     private void waitForAdminData() {
6222         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
6223             ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch,
6224                     WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data");
6225         }
6226     }
6227 
6228     private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids,
6229             Set<Integer> newRestrictedUids) {
6230         if (!mNetworkManagerReady) {
6231             return;
6232         }
6233         if (oldRestrictedUids == null) {
6234             for (int uid : newRestrictedUids) {
6235                 updateRulesForDataUsageRestrictionsUL(uid);
6236             }
6237             return;
6238         }
6239         for (int uid : oldRestrictedUids) {
6240             if (!newRestrictedUids.contains(uid)) {
6241                 updateRulesForDataUsageRestrictionsUL(uid);
6242             }
6243         }
6244         for (int uid : newRestrictedUids) {
6245             if (!oldRestrictedUids.contains(uid)) {
6246                 updateRulesForDataUsageRestrictionsUL(uid);
6247             }
6248         }
6249     }
6250 
6251     @GuardedBy("mUidRulesFirstLock")
6252     private boolean isRestrictedByAdminUL(int uid) {
6253         final Set<Integer> restrictedUids = mMeteredRestrictedUids.get(
6254                 UserHandle.getUserId(uid));
6255         return restrictedUids != null && restrictedUids.contains(uid);
6256     }
6257 
6258     private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle,
6259             String key, boolean defaultValue) {
6260         return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
6261     }
6262 
6263     private static UidBlockedState getOrCreateUidBlockedStateForUid(
6264             SparseArray<UidBlockedState> uidBlockedStates, int uid) {
6265         UidBlockedState uidBlockedState = uidBlockedStates.get(uid);
6266         if (uidBlockedState == null) {
6267             uidBlockedState = new UidBlockedState();
6268             uidBlockedStates.put(uid, uidBlockedState);
6269         }
6270         return uidBlockedState;
6271     }
6272 
6273     private int getEffectiveBlockedReasons(int uid) {
6274         synchronized (mUidBlockedState) {
6275             final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
6276             return uidBlockedState == null
6277                     ? BLOCKED_REASON_NONE
6278                     : uidBlockedState.effectiveBlockedReasons;
6279         }
6280     }
6281 
6282     private int getBlockedReasons(int uid) {
6283         synchronized (mUidBlockedState) {
6284             final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
6285             return uidBlockedState == null
6286                     ? BLOCKED_REASON_NONE
6287                     : uidBlockedState.blockedReasons;
6288         }
6289     }
6290 
6291     @VisibleForTesting
6292     static final class UidBlockedState {
6293         public int blockedReasons;
6294         public int allowedReasons;
6295         public int effectiveBlockedReasons;
6296 
6297         private UidBlockedState(int blockedReasons, int allowedReasons,
6298                 int effectiveBlockedReasons) {
6299             this.blockedReasons = blockedReasons;
6300             this.allowedReasons = allowedReasons;
6301             this.effectiveBlockedReasons = effectiveBlockedReasons;
6302         }
6303 
6304         UidBlockedState() {
6305             this(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE, BLOCKED_REASON_NONE);
6306         }
6307 
6308         void updateEffectiveBlockedReasons() {
6309             if (LOGV && blockedReasons == BLOCKED_REASON_NONE) {
6310                 Log.v(TAG, "updateEffectiveBlockedReasons(): no blocked reasons");
6311             }
6312             effectiveBlockedReasons = getEffectiveBlockedReasons(blockedReasons, allowedReasons);
6313             if (LOGV) {
6314                 Log.v(TAG, "updateEffectiveBlockedReasons()"
6315                         + ": blockedReasons=" + Integer.toBinaryString(blockedReasons)
6316                         + ", effectiveReasons=" + Integer.toBinaryString(effectiveBlockedReasons));
6317             }
6318         }
6319 
6320         @VisibleForTesting
6321         static int getEffectiveBlockedReasons(int blockedReasons, int allowedReasons) {
6322             int effectiveBlockedReasons = blockedReasons;
6323             // If the uid is not subject to any blocked reasons, then return early
6324             if (blockedReasons == BLOCKED_REASON_NONE) {
6325                 return effectiveBlockedReasons;
6326             }
6327             if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
6328                 effectiveBlockedReasons &= ALLOWED_METERED_REASON_MASK;
6329             }
6330             if ((allowedReasons & ALLOWED_METERED_REASON_SYSTEM) != 0) {
6331                 effectiveBlockedReasons &= ~ALLOWED_METERED_REASON_MASK;
6332             }
6333             if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) {
6334                 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
6335                 effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
6336                 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
6337             }
6338             if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) {
6339                 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
6340                 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
6341             }
6342             if ((allowedReasons & ALLOWED_REASON_TOP) != 0) {
6343                 effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY;
6344             }
6345             if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) {
6346                 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
6347                 effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
6348                 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
6349             }
6350             if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) {
6351                 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
6352                 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
6353             }
6354             if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) {
6355                 effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
6356             }
6357             if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
6358                 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
6359             }
6360             if ((allowedReasons & ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST) != 0) {
6361                 effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY;
6362             }
6363 
6364             return effectiveBlockedReasons;
6365         }
6366 
6367         static int getAllowedReasonsForProcState(int procState) {
6368             if (procState > NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE) {
6369                 return ALLOWED_REASON_NONE;
6370             } else if (procState <= NetworkPolicyManager.TOP_THRESHOLD_STATE) {
6371                 return ALLOWED_REASON_TOP | ALLOWED_REASON_FOREGROUND
6372                         | ALLOWED_METERED_REASON_FOREGROUND;
6373             } else {
6374                 return ALLOWED_REASON_FOREGROUND | ALLOWED_METERED_REASON_FOREGROUND;
6375             }
6376         }
6377 
6378         @Override
6379         public String toString() {
6380             return toString(blockedReasons, allowedReasons, effectiveBlockedReasons);
6381         }
6382 
6383         public static String toString(int blockedReasons, int allowedReasons,
6384                 int effectiveBlockedReasons) {
6385             final StringBuilder sb = new StringBuilder();
6386             sb.append("{");
6387             sb.append("blocked=").append(blockedReasonsToString(blockedReasons)).append(",");
6388             sb.append("allowed=").append(allowedReasonsToString(allowedReasons)).append(",");
6389             sb.append("effective=").append(blockedReasonsToString(effectiveBlockedReasons));
6390             sb.append("}");
6391             return sb.toString();
6392         }
6393 
6394         private static final int[] BLOCKED_REASONS = {
6395                 BLOCKED_REASON_BATTERY_SAVER,
6396                 BLOCKED_REASON_DOZE,
6397                 BLOCKED_REASON_APP_STANDBY,
6398                 BLOCKED_REASON_RESTRICTED_MODE,
6399                 BLOCKED_REASON_LOW_POWER_STANDBY,
6400                 BLOCKED_METERED_REASON_DATA_SAVER,
6401                 BLOCKED_METERED_REASON_USER_RESTRICTED,
6402                 BLOCKED_METERED_REASON_ADMIN_DISABLED,
6403         };
6404 
6405         private static final int[] ALLOWED_REASONS = {
6406                 ALLOWED_REASON_SYSTEM,
6407                 ALLOWED_REASON_FOREGROUND,
6408                 ALLOWED_REASON_TOP,
6409                 ALLOWED_REASON_POWER_SAVE_ALLOWLIST,
6410                 ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST,
6411                 ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS,
6412                 ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST,
6413                 ALLOWED_METERED_REASON_USER_EXEMPTED,
6414                 ALLOWED_METERED_REASON_SYSTEM,
6415                 ALLOWED_METERED_REASON_FOREGROUND,
6416         };
6417 
6418         private static String blockedReasonToString(int blockedReason) {
6419             switch (blockedReason) {
6420                 case BLOCKED_REASON_NONE:
6421                     return "NONE";
6422                 case BLOCKED_REASON_BATTERY_SAVER:
6423                     return "BATTERY_SAVER";
6424                 case BLOCKED_REASON_DOZE:
6425                     return "DOZE";
6426                 case BLOCKED_REASON_APP_STANDBY:
6427                     return "APP_STANDBY";
6428                 case BLOCKED_REASON_RESTRICTED_MODE:
6429                     return "RESTRICTED_MODE";
6430                 case BLOCKED_REASON_LOW_POWER_STANDBY:
6431                     return "LOW_POWER_STANDBY";
6432                 case BLOCKED_METERED_REASON_DATA_SAVER:
6433                     return "DATA_SAVER";
6434                 case BLOCKED_METERED_REASON_USER_RESTRICTED:
6435                     return "METERED_USER_RESTRICTED";
6436                 case BLOCKED_METERED_REASON_ADMIN_DISABLED:
6437                     return "METERED_ADMIN_DISABLED";
6438                 default:
6439                     Slog.wtfStack(TAG, "Unknown blockedReason: " + blockedReason);
6440                     return String.valueOf(blockedReason);
6441             }
6442         }
6443 
6444         private static String allowedReasonToString(int allowedReason) {
6445             switch (allowedReason) {
6446                 case ALLOWED_REASON_NONE:
6447                     return "NONE";
6448                 case ALLOWED_REASON_SYSTEM:
6449                     return "SYSTEM";
6450                 case ALLOWED_REASON_FOREGROUND:
6451                     return "FOREGROUND";
6452                 case ALLOWED_REASON_TOP:
6453                     return "TOP";
6454                 case ALLOWED_REASON_POWER_SAVE_ALLOWLIST:
6455                     return "POWER_SAVE_ALLOWLIST";
6456                 case ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST:
6457                     return "POWER_SAVE_EXCEPT_IDLE_ALLOWLIST";
6458                 case ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS:
6459                     return "RESTRICTED_MODE_PERMISSIONS";
6460                 case ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST:
6461                     return "LOW_POWER_STANDBY_ALLOWLIST";
6462                 case ALLOWED_METERED_REASON_USER_EXEMPTED:
6463                     return "METERED_USER_EXEMPTED";
6464                 case ALLOWED_METERED_REASON_SYSTEM:
6465                     return "METERED_SYSTEM";
6466                 case ALLOWED_METERED_REASON_FOREGROUND:
6467                     return "METERED_FOREGROUND";
6468                 default:
6469                     Slog.wtfStack(TAG, "Unknown allowedReason: " + allowedReason);
6470                     return String.valueOf(allowedReason);
6471             }
6472         }
6473 
6474         public static String blockedReasonsToString(int blockedReasons) {
6475             if (blockedReasons == BLOCKED_REASON_NONE) {
6476                 return blockedReasonToString(BLOCKED_REASON_NONE);
6477             }
6478             final StringBuilder sb = new StringBuilder();
6479             for (int reason : BLOCKED_REASONS) {
6480                 if ((blockedReasons & reason) != 0) {
6481                     sb.append(sb.length() == 0 ? "" : "|");
6482                     sb.append(blockedReasonToString(reason));
6483                     blockedReasons &= ~reason;
6484                 }
6485             }
6486             if (blockedReasons != 0) {
6487                 sb.append(sb.length() == 0 ? "" : "|");
6488                 sb.append(String.valueOf(blockedReasons));
6489                 Slog.wtfStack(TAG, "Unknown blockedReasons: " + blockedReasons);
6490             }
6491             return sb.toString();
6492         }
6493 
6494         public static String allowedReasonsToString(int allowedReasons) {
6495             if (allowedReasons == ALLOWED_REASON_NONE) {
6496                 return allowedReasonToString(ALLOWED_REASON_NONE);
6497             }
6498             final StringBuilder sb = new StringBuilder();
6499             for (int reason : ALLOWED_REASONS) {
6500                 if ((allowedReasons & reason) != 0) {
6501                     sb.append(sb.length() == 0 ? "" : "|");
6502                     sb.append(allowedReasonToString(reason));
6503                     allowedReasons &= ~reason;
6504                 }
6505             }
6506             if (allowedReasons != 0) {
6507                 sb.append(sb.length() == 0 ? "" : "|");
6508                 sb.append(String.valueOf(allowedReasons));
6509                 Slog.wtfStack(TAG, "Unknown allowedReasons: " + allowedReasons);
6510             }
6511             return sb.toString();
6512         }
6513 
6514         public void copyFrom(UidBlockedState uidBlockedState) {
6515             blockedReasons = uidBlockedState.blockedReasons;
6516             allowedReasons = uidBlockedState.allowedReasons;
6517             effectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
6518         }
6519 
6520         public int deriveUidRules() {
6521             int uidRule = RULE_NONE;
6522             if ((effectiveBlockedReasons & BLOCKED_REASON_RESTRICTED_MODE) != 0) {
6523                 uidRule |= RULE_REJECT_RESTRICTED_MODE;
6524             }
6525 
6526             int powerBlockedReasons = BLOCKED_REASON_APP_STANDBY
6527                     | BLOCKED_REASON_DOZE
6528                     | BLOCKED_REASON_BATTERY_SAVER
6529                     | BLOCKED_REASON_LOW_POWER_STANDBY;
6530             if ((effectiveBlockedReasons & powerBlockedReasons) != 0) {
6531                 uidRule |= RULE_REJECT_ALL;
6532             } else if ((blockedReasons & powerBlockedReasons) != 0) {
6533                 uidRule |= RULE_ALLOW_ALL;
6534             }
6535 
6536             // UidRule doesn't include RestrictBackground (DataSaver) state, so not including in
6537             // metered blocked reasons below.
6538             int meteredBlockedReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED
6539                     | BLOCKED_METERED_REASON_USER_RESTRICTED;
6540             if ((effectiveBlockedReasons & meteredBlockedReasons) != 0) {
6541                 uidRule |= RULE_REJECT_METERED;
6542             } else if ((blockedReasons & BLOCKED_METERED_REASON_USER_RESTRICTED) != 0
6543                     && (allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) {
6544                 uidRule |= RULE_TEMPORARY_ALLOW_METERED;
6545             } else if ((blockedReasons & BLOCKED_METERED_REASON_DATA_SAVER) != 0) {
6546                 if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
6547                     uidRule |= RULE_ALLOW_ALL;
6548                 } else if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) {
6549                     uidRule |= RULE_TEMPORARY_ALLOW_METERED;
6550                 }
6551             }
6552             if (LOGV) {
6553                 Slog.v(TAG, "uidBlockedState=" + this
6554                         + " -> uidRule=" + uidRulesToString(uidRule));
6555             }
6556             return uidRule;
6557         }
6558     }
6559 
6560     private static class NotificationId {
6561         private final String mTag;
6562         private final int mId;
6563 
6564         NotificationId(NetworkPolicy policy, int type) {
6565             mTag = buildNotificationTag(policy, type);
6566             mId = type;
6567         }
6568 
6569         @Override
6570         public boolean equals(Object o) {
6571             if (this == o) return true;
6572             if (!(o instanceof NotificationId)) return false;
6573             NotificationId that = (NotificationId) o;
6574             return Objects.equals(mTag, that.mTag);
6575         }
6576 
6577         @Override
6578         public int hashCode() {
6579             return Objects.hash(mTag);
6580         }
6581 
6582         /**
6583          * Build unique tag that identifies an active {@link NetworkPolicy}
6584          * notification of a specific type, like {@link #TYPE_LIMIT}.
6585          */
6586         private String buildNotificationTag(NetworkPolicy policy, int type) {
6587             return TAG + ":" + policy.template.hashCode() + ":" + type;
6588         }
6589 
6590         public String getTag() {
6591             return mTag;
6592         }
6593 
6594         public int getId() {
6595             return mId;
6596         }
6597     }
6598 }
6599