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