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