OSDN Git Service

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