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