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