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