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