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