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