2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server.net;
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;
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;
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;
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;
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;
232 import libcore.io.IoUtils;
233 import libcore.util.EmptyArray;
235 import org.xmlpull.v1.XmlPullParser;
236 import org.xmlpull.v1.XmlSerializer;
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;
264 * Service that maintains low-level network policy rules, using
265 * {@link NetworkStatsService} statistics to drive those rules.
267 * Derives active rules by combining a given policy with other system status,
268 * and delivers to listeners, such as {@link ConnectivityManager}, for
272 * This class uses 2-3 locks to synchronize state:
274 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
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
283 * As such, methods that require synchronization have the following prefixes:
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..
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;
297 * No opportunistic quota could be calculated from user data plan or data settings.
299 public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1;
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;
315 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
317 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
319 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
321 public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID;
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";
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";
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";
368 * Indicates the maximum wait time for admin data to be available;
370 private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
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;
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;
390 private static final int UID_MSG_STATE_CHANGED = 100;
391 private static final int UID_MSG_GONE = 101;
393 private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";
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;
404 private IConnectivityManager mConnManager;
405 private PowerManagerInternal mPowerManagerInternal;
406 private IDeviceIdleController mDeviceIdleController;
407 @GuardedBy("mUidRulesFirstLock")
408 private PowerSaveState mRestrictBackgroundPowerState;
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;
414 // Denotes the status of restrict background read from disk.
415 private boolean mLoadedRestrictBackground;
417 // See main javadoc for instructions on how to use these locks.
418 final Object mUidRulesFirstLock = new Object();
419 final Object mNetworkPoliciesSecondLock = new Object();
421 @GuardedBy("allLocks") volatile boolean mSystemReady;
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;
429 private final boolean mSuppressDefaultPolicy;
431 private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
433 /** Defined network policies. */
434 @GuardedBy("mNetworkPoliciesSecondLock")
435 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
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<>();
444 /** Map from subId to daily opportunistic quota. */
445 @GuardedBy("mNetworkPoliciesSecondLock")
446 final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray();
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();
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();
460 /** Set of states for the child firewall chains. True if the chain is active. */
461 @GuardedBy("mUidRulesFirstLock")
462 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
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
469 @GuardedBy("mUidRulesFirstLock")
470 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
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
477 @GuardedBy("mUidRulesFirstLock")
478 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
480 @GuardedBy("mUidRulesFirstLock")
481 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
484 * UIDs that have been initially white-listed by system to avoid restricted background.
486 @GuardedBy("mUidRulesFirstLock")
487 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
488 new SparseBooleanArray();
491 * UIDs that have been initially white-listed by system to avoid restricted background,
492 * but later revoked by user.
494 @GuardedBy("mUidRulesFirstLock")
495 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
496 new SparseBooleanArray();
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<>();
505 /** Set of currently active {@link Notification} tags. */
506 @GuardedBy("mNetworkPoliciesSecondLock")
507 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
509 /** Foreground at UID granularity. */
510 @GuardedBy("mUidRulesFirstLock")
511 final SparseIntArray mUidState = new SparseIntArray();
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();
520 /** Map from netId to subId as of last update */
521 @GuardedBy("mNetworkPoliciesSecondLock")
522 private final SparseIntArray mNetIdToSubId = new SparseIntArray();
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;
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.
535 @GuardedBy("mUidRulesFirstLock")
536 private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>();
538 private final RemoteCallbackList<INetworkPolicyListener>
539 mListeners = new RemoteCallbackList<>();
541 final Handler mHandler;
543 public final Handler mUidEventHandler;
545 private final ServiceThread mUidEventThread;
547 @GuardedBy("allLocks")
548 private final AtomicFile mPolicyFile;
550 private final AppOpsManager mAppOps;
552 private final IPackageManager mIPm;
554 private ActivityManagerInternal mActivityManagerInternal;
556 private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
558 // TODO: keep whitelist of system-critical services that should never have
559 // rules enforced, such as system, phone, and radio UIDs.
561 // TODO: migrate notifications to SystemUI
565 int UPDATE_NETWORK_ENABLED = 0;
566 int IS_UID_NETWORKING_BLOCKED = 1;
568 int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
571 public final StatLogger mStatLogger = new StatLogger(new String[] {
572 "updateNetworkEnabledNL()",
573 "isUidNetworkingBlocked()",
576 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
577 INetworkManagementService networkManagement) {
578 this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
579 getDefaultClock(), getDefaultSystemDir(), false);
582 private static @NonNull File getDefaultSystemDir() {
583 return new File(Environment.getDataDirectory(), "system");
586 private static @NonNull Clock getDefaultClock() {
587 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
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);
604 HandlerThread thread = new HandlerThread(TAG);
606 mHandler = new Handler(thread.getLooper(), mHandlerCallback);
608 // We create another thread for the UID events, which are more time-critical.
609 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
611 mUidEventThread.start();
612 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
614 mSuppressDefaultPolicy = suppressDefaultPolicy;
616 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
618 mAppOps = context.getSystemService(AppOpsManager.class);
620 // Expose private service for system components to use.
621 LocalServices.addService(NetworkPolicyManagerInternal.class,
622 new NetworkPolicyManagerInternalImpl());
625 public void bindConnectivityManager(IConnectivityManager connManager) {
626 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
629 void updatePowerSaveWhitelistUL() {
631 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
632 mPowerSaveWhitelistExceptIdleAppIds.clear();
633 if (whitelist != null) {
634 for (int uid : whitelist) {
635 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
638 whitelist = mDeviceIdleController.getAppIdWhitelist();
639 mPowerSaveWhitelistAppIds.clear();
640 if (whitelist != null) {
641 for (int uid : whitelist) {
642 mPowerSaveWhitelistAppIds.put(uid, true);
645 } catch (RemoteException e) {
650 * Whitelists pre-defined apps for restrict background, but only if the user didn't already
651 * revoke the whitelist.
653 * @return whether any uid has been whitelisted.
655 boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
656 final List<UserInfo> users = mUserManager.getUsers();
657 final int numberUsers = users.size();
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;
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);
675 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
676 + " and user " + userId);
677 final ApplicationInfo app;
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.
685 if (!app.isPrivilegedApp()) {
686 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
687 + "skipping non-privileged app " + pkg);
690 final int uid = UserHandle.getUid(userId, app.uid);
691 mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
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)) {
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);
707 private void initService(CountDownLatch initCompleteSignal) {
708 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
709 final int oldPriority = Process.getThreadPriority(Process.myTid());
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");
718 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
719 mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
721 synchronized (mUidRulesFirstLock) {
722 synchronized (mNetworkPoliciesSecondLock) {
723 updatePowerSaveWhitelistUL();
724 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
725 mPowerManagerInternal.registerLowPowerModeObserver(
726 new PowerManagerInternal.LowPowerModeListener() {
728 public int getServiceType() {
729 return ServiceType.NETWORK_FIREWALL;
733 public void onLowPowerModeChanged(PowerSaveState result) {
734 final boolean enabled = result.batterySaverEnabled;
736 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
738 synchronized (mUidRulesFirstLock) {
739 if (mRestrictPower != enabled) {
740 mRestrictPower = enabled;
741 updateRulesForRestrictPowerUL();
746 mRestrictPower = mPowerManagerInternal.getLowPowerState(
747 ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
753 // read policy from disk
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;
765 mPowerManagerInternal.registerLowPowerModeObserver(
766 new PowerManagerInternal.LowPowerModeListener() {
768 public int getServiceType() {
769 return ServiceType.DATA_SAVER;
773 public void onLowPowerModeChanged(PowerSaveState result) {
774 synchronized (mUidRulesFirstLock) {
775 updateRestrictBackgroundByLowPowerModeUL(result);
780 if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
784 setRestrictBackgroundUL(mLoadedRestrictBackground);
785 updateRulesForGlobalChangeAL(false);
786 updateNotificationsNL();
790 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
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
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);
805 // watch for network interfaces to be claimed
806 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
807 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
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);
815 // listen for UID changes to update policy
816 mContext.registerReceiver(
817 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
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);
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);
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);
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);
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);
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);
850 // listen for meteredness changes
851 mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
852 new NetworkRequest.Builder().build(), mNetworkCallback);
854 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
856 // Listen for subscriber changes
857 mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
858 new OnSubscriptionsChangedListener(mHandler.getLooper()) {
860 public void onSubscriptionsChanged() {
861 updateNetworksInternal();
865 // tell systemReady() that the service has been initialized
866 initCompleteSignal.countDown();
868 // Restore the default priority after init is done
869 Process.setThreadPriority(oldPriority);
870 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
874 public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
875 final CountDownLatch initCompleteSignal = new CountDownLatch(1);
876 mHandler.post(() -> initService(initCompleteSignal));
877 return initCompleteSignal;
880 public void systemReady(CountDownLatch initCompleteSignal) {
881 // wait for initService to complete
883 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
884 throw new IllegalStateException("Service " + TAG +" init timeout");
886 } catch (InterruptedException e) {
887 Thread.currentThread().interrupt();
888 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
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();
898 @Override public void onUidGone(int uid, boolean disabled) {
899 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
902 @Override public void onUidActive(int uid) {
905 @Override public void onUidIdle(int uid, boolean disabled) {
908 @Override public void onUidCachedChanged(int uid, boolean cached) {
912 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
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();
924 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
926 public void onReceive(Context context, Intent intent) {
927 // on background handler thread, and PACKAGE_ADDED is protected
929 final String action = intent.getAction();
930 final int uid = intent.getIntExtra(EXTRA_UID, -1);
931 if (uid == -1) return;
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);
944 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
946 public void onReceive(Context context, Intent intent) {
947 // on background handler thread, and UID_REMOVED is protected
949 final int uid = intent.getIntExtra(EXTRA_UID, -1);
950 if (uid == -1) return;
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) {
956 synchronized (mNetworkPoliciesSecondLock) {
963 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
965 public void onReceive(Context context, Intent intent) {
966 // on background handler thread, and USER_ADDED and USER_REMOVED
967 // broadcasts are protected
969 final String action = intent.getAction();
970 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
971 if (userId == -1) return;
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);
987 // Update global restrict for that user
988 synchronized (mNetworkPoliciesSecondLock) {
989 updateRulesForGlobalChangeAL(true);
998 * Receiver that watches for {@link INetworkStatsService} updates, which we
999 * use to check against {@link NetworkPolicy#warningBytes}.
1001 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
1003 public void onReceive(Context context, Intent intent) {
1004 // on background handler thread, and verified
1005 // READ_NETWORK_USAGE_HISTORY permission above.
1007 synchronized (mNetworkPoliciesSecondLock) {
1008 updateNetworkEnabledNL();
1009 updateNotificationsNL();
1015 * Receiver that watches for {@link Notification} control of
1016 * {@link #mRestrictBackground}.
1018 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
1020 public void onReceive(Context context, Intent intent) {
1021 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1022 // permission above.
1024 setRestrictBackground(false);
1029 * Receiver that watches for {@link Notification} control of
1030 * {@link NetworkPolicy#lastWarningSnooze}.
1032 final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
1034 public void onReceive(Context context, Intent intent) {
1035 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1036 // permission above.
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);
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.
1052 final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
1054 public void onReceive(Context context, Intent intent) {
1055 synchronized (mUidRulesFirstLock) {
1056 synchronized (mNetworkPoliciesSecondLock) {
1057 upgradeWifiMeteredOverrideAL();
1060 // Only need to perform upgrade logic once
1061 mContext.unregisterReceiver(this);
1065 private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue,
1067 final boolean lastValue = lastValues.get(network.netId, false);
1068 final boolean changed = (lastValue != newValue) || lastValues.indexOfKey(network.netId) < 0;
1070 lastValues.put(network.netId, newValue);
1075 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
1077 public void onCapabilitiesChanged(Network network,
1078 NetworkCapabilities networkCapabilities) {
1079 if (network == null || networkCapabilities == null) return;
1081 synchronized (mNetworkPoliciesSecondLock) {
1082 final boolean newMetered = !networkCapabilities
1083 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1084 final boolean meteredChanged = updateCapabilityChange(
1085 mNetworkMetered, newMetered, network);
1087 final boolean newRoaming = !networkCapabilities
1088 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
1089 final boolean roamingChanged = updateCapabilityChange(
1090 mNetworkRoaming, newRoaming, network);
1092 if (meteredChanged || roamingChanged) {
1093 mLogger.meterednessChanged(network.netId, newMetered);
1094 updateNetworkRulesNL();
1101 * Observer that watches for {@link INetworkManagementService} alerts.
1103 final private INetworkManagementEventObserver mAlertObserver
1104 = new BaseNetworkObserver() {
1106 public void limitReached(String limitName, String iface) {
1107 // only someone like NMS should be calling us
1108 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1110 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1111 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
1117 * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
1118 * to show visible notifications as needed.
1120 void updateNotificationsNL() {
1121 if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
1122 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNotificationsNL");
1124 // keep track of previously active notifications
1125 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
1126 mActiveNotifs.clear();
1128 // TODO: when switching to kernel notifications, compute next future
1129 // cycle boundary to recompute notifications.
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);
1137 // ignore policies that aren't relevant to user
1138 if (subId == INVALID_SUBSCRIPTION_ID) continue;
1139 if (!policy.hasCycle()) continue;
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);
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);
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);
1166 // Notify when data usage is over limit
1168 if (policy.isOverLimit(totalBytes)) {
1169 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
1170 if (snoozedThisCycle) {
1171 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
1173 enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
1174 notifyOverLimitNL(policy.template);
1177 notifyUnderLimitNL(policy.template);
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);
1189 final long cycleDuration = cycleEnd - cycleStart;
1190 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
1191 final long alertBytes = (policy.limitBytes * 3) / 2;
1194 Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected "
1195 + projectedBytes + " alert " + alertBytes);
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));
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);
1215 Trace.traceEnd(TRACE_TAG_NETWORK);
1219 * Attempt to find a specific app to blame for rapid data usage during the
1220 * given time period.
1222 private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
1223 long start, long end) {
1224 long totalBytes = 0;
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) {
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) {
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) {
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.
1263 * @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no
1264 * matching subId found.
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,
1274 if (template.matches(probeIdent)) {
1278 return INVALID_SUBSCRIPTION_ID;
1282 * Notify that given {@link NetworkTemplate} is over
1283 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1285 private void notifyOverLimitNL(NetworkTemplate template) {
1286 if (!mOverLimitNotified.contains(template)) {
1287 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
1288 mOverLimitNotified.add(template);
1292 private void notifyUnderLimitNL(NetworkTemplate template) {
1293 mOverLimitNotified.remove(template);
1297 * Show notification for combined {@link NetworkPolicy} and specific type,
1298 * like {@link #TYPE_LIMIT}. Okay to call multiple times.
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));
1310 final Resources res = mContext.getResources();
1311 final CharSequence title;
1312 final CharSequence body;
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));
1319 builder.setSmallIcon(R.drawable.stat_notify_error);
1321 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1322 builder.setDeleteIntent(PendingIntent.getBroadcast(
1323 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1325 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
1326 builder.setContentIntent(PendingIntent.getActivity(
1327 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1332 switch (policy.template.getMatchRule()) {
1334 title = res.getText(R.string.data_usage_mobile_limit_title);
1337 title = res.getText(R.string.data_usage_wifi_limit_title);
1342 body = res.getText(R.string.data_usage_limit_body);
1344 builder.setOngoing(true);
1345 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
1347 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
1348 builder.setContentIntent(PendingIntent.getActivity(
1349 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1352 case TYPE_LIMIT_SNOOZED: {
1353 switch (policy.template.getMatchRule()) {
1355 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1358 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1363 final long overBytes = totalBytes - policy.limitBytes;
1364 body = res.getString(R.string.data_usage_limit_snoozed_body,
1365 Formatter.formatFileSize(mContext, overBytes));
1367 builder.setOngoing(true);
1368 builder.setSmallIcon(R.drawable.stat_notify_error);
1369 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
1371 final Intent intent = buildViewDataUsageIntent(res, policy.template);
1372 builder.setContentIntent(PendingIntent.getActivity(
1373 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
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()));
1382 body = res.getString(R.string.data_usage_rapid_body);
1385 builder.setSmallIcon(R.drawable.stat_notify_error);
1387 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
1388 builder.setDeleteIntent(PendingIntent.getBroadcast(
1389 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1391 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
1392 builder.setContentIntent(PendingIntent.getActivity(
1393 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1401 builder.setTicker(title);
1402 builder.setContentTitle(title);
1403 builder.setContentText(body);
1404 builder.setStyle(new Notification.BigTextStyle().bigText(body));
1406 mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
1407 notificationId.getId(), builder.build(), UserHandle.ALL);
1408 mActiveNotifs.add(notificationId);
1411 private void cancelNotification(NotificationId notificationId) {
1412 mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(),
1413 notificationId.getId());
1417 * Receiver that watches for {@link IConnectivityManager} to claim network
1418 * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
1420 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
1422 public void onReceive(Context context, Intent intent) {
1423 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1424 // permission above.
1425 updateNetworksInternal();
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();
1434 synchronized (mUidRulesFirstLock) {
1435 synchronized (mNetworkPoliciesSecondLock) {
1436 ensureActiveMobilePolicyAL();
1437 normalizePoliciesNL();
1438 updateNetworkEnabledNL();
1439 updateNetworkRulesNL();
1440 updateNotificationsNL();
1446 public void updateNetworks() throws InterruptedException {
1447 updateNetworksInternal();
1448 final CountDownLatch latch = new CountDownLatch(1);
1449 mHandler.post(() -> {
1452 latch.await(5, TimeUnit.SECONDS);
1456 * Update mobile policies with data cycle information from {@link CarrierConfigManager}
1459 * @param subId that has its associated NetworkPolicy updated if necessary
1460 * @return if any policies were updated
1462 private boolean maybeUpdateMobilePolicyCycleAL(int subId, String subscriberId) {
1463 if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
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);
1476 return policyUpdated;
1480 * Returns the cycle day that should be used for a mobile NetworkPolicy.
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.
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.
1490 public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
1491 int fallbackCycleDay) {
1492 if (config == null) {
1493 return fallbackCycleDay;
1496 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1497 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1498 return fallbackCycleDay;
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;
1512 * Returns the warning bytes that should be used for a mobile NetworkPolicy.
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.
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.
1522 public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
1523 long fallbackWarningBytes) {
1524 if (config == null) {
1525 return fallbackWarningBytes;
1528 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
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;
1541 return warningBytes;
1545 * Returns the limit bytes that should be used for a mobile NetworkPolicy.
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.
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.
1555 public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
1556 long fallbackLimitBytes) {
1557 if (config == null) {
1558 return fallbackLimitBytes;
1561 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
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;
1577 * Receiver that watches for {@link CarrierConfigManager} to be changed.
1579 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
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.
1585 if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
1588 final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
1590 // Get all of our cross-process communication with telephony out of
1591 // the way before we acquire internal locks.
1592 updateSubscriptions();
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);
1601 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
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);
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.
1616 * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1619 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1620 if (shouldNormalizePolicies) {
1621 normalizePoliciesNL();
1623 updateNetworkEnabledNL();
1624 updateNetworkRulesNL();
1625 updateNotificationsNL();
1630 * Proactively control network data connections when they exceed
1631 * {@link NetworkPolicy#limitBytes}.
1633 void updateNetworkEnabledNL() {
1634 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
1635 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkEnabledNL");
1637 // TODO: reset any policy-disabled networks when any policy is removed
1638 // completely, which is currently rare case.
1640 final long startTime = mStatLogger.getTime();
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);
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);
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;
1661 setNetworkTemplateEnabled(policy.template, networkEnabled);
1664 mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime);
1665 Trace.traceEnd(TRACE_TAG_NETWORK);
1669 * Proactively disable networks that match the given
1670 * {@link NetworkTemplate}.
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)
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.
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.
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);
1693 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1694 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1696 // Template is matched when subscriber id matches.
1697 if (template.matches(probeIdent)) {
1698 matchingSubIds.add(subId);
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);
1713 * Collect all ifaces from a {@link NetworkState} into the given set.
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);
1720 for (LinkProperties stackedLink : state.linkProperties.getStackedLinks()) {
1721 final String stackedIface = stackedLink.getInterfaceName();
1722 if (stackedIface != null) {
1723 ifaces.add(stackedIface);
1729 * Examine all currently active subscriptions from
1730 * {@link SubscriptionManager#getActiveSubscriptionIdList()} and update
1731 * internal data structures.
1733 * Callers <em>must not</em> hold any locks when this method called.
1735 void updateSubscriptions() {
1736 if (LOGV) Slog.v(TAG, "updateSubscriptions()");
1737 Trace.traceBegin(TRACE_TAG_NETWORK, "updateSubscriptions");
1739 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1740 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
1742 final int[] subIds = ArrayUtils.defeatNullable(sm.getActiveSubscriptionIdList());
1743 final String[] mergedSubscriberIds = ArrayUtils.defeatNullable(tm.getMergedSubscriberIds());
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);
1751 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
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));
1762 mMergedSubscriberIds = mergedSubscriberIds;
1765 Trace.traceEnd(TRACE_TAG_NETWORK);
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.
1773 void updateNetworkRulesNL() {
1774 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
1775 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
1777 final NetworkState[] states;
1779 states = defeatNullable(mConnManager.getAllNetworkState());
1780 } catch (RemoteException e) {
1781 // ignored; service lives in system_server
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));
1793 if (state.networkInfo != null && state.networkInfo.isConnected()) {
1794 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1796 identified.put(state, ident);
1800 final ArraySet<String> newMeteredIfaces = new ArraySet<>();
1801 long lowestRule = Long.MAX_VALUE;
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);
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));
1818 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces);
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);
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;
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);
1843 // metered network, but no policy limit; we still need to
1844 // restrict apps, so push really high quota.
1845 quotaBytes = Long.MAX_VALUE;
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");
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);
1860 // keep track of lowest warning or limit of active policies
1861 if (hasWarning && policy.warningBytes < lowestRule) {
1862 lowestRule = policy.warningBytes;
1864 if (hasLimit && policy.limitBytes < lowestRule) {
1865 lowestRule = policy.limitBytes;
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);
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);
1893 mMeteredIfaces = newMeteredIfaces;
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);
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;
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
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;
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),
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));
1939 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
1942 mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
1945 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
1946 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
1948 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
1950 Trace.traceEnd(TRACE_TAG_NETWORK);
1954 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1955 * have at least a default mobile policy defined.
1957 private void ensureActiveMobilePolicyAL() {
1958 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
1959 if (mSuppressDefaultPolicy) return;
1961 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1962 final int subId = mSubIdToSubscriberId.keyAt(i);
1963 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
1965 ensureActiveMobilePolicyAL(subId, subscriberId);
1970 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1971 * have at least a default mobile policy defined.
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.
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)) {
1985 Slog.d(TAG, "Found template " + template + " which matches subscriber "
1986 + NetworkIdentity.scrubSubscriberId(subscriberId));
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);
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;
2005 return dataWarningConfig * MB_IN_BYTES;
2009 private long getPlatformDefaultLimitBytes() {
2010 return LIMIT_DISABLED;
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);
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.
2034 * @return if the policy was modified
2036 private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
2037 if (!policy.inferred) {
2038 if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
2042 final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
2043 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
2044 policy.lastLimitSnooze, policy.metered, policy.inferred);
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;
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;
2065 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2070 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
2071 final int currentCycleDay;
2072 if (policy.cycleRule.isMonthly()) {
2073 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
2075 currentCycleDay = NetworkPolicy.CYCLE_NONE;
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);
2083 if (policy.equals(original)) {
2086 Slog.d(TAG, "Updated " + original + " to " + policy);
2091 private void readPolicyAL() {
2092 if (LOGV) Slog.v(TAG, "readPolicyAL()");
2094 // clear any existing policy and read from disk
2095 mNetworkPolicy.clear();
2096 mSubscriptionPlans.clear();
2097 mSubscriptionPlansOwner.clear();
2100 FileInputStream fis = null;
2102 fis = mPolicyFile.openRead();
2103 final XmlPullParser in = Xml.newPullParser();
2104 in.setInput(fis, StandardCharsets.UTF_8.name());
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();
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);
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));
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);
2145 cycleTimezone = "UTC";
2147 cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone));
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);
2157 lastLimitSnooze = SNOOZE_NEVER;
2159 final boolean metered;
2160 if (version >= VERSION_ADDED_METERED) {
2161 metered = readBooleanAttribute(in, ATTR_METERED);
2163 switch (networkTemplate) {
2171 final long lastWarningSnooze;
2172 if (version >= VERSION_SPLIT_SNOOZE) {
2173 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
2175 lastWarningSnooze = SNOOZE_NEVER;
2177 final boolean inferred;
2178 if (version >= VERSION_ADDED_INFERRED) {
2179 inferred = readBooleanAttribute(in, ATTR_INFERRED);
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));
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));
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);
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);
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));
2226 final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
2227 mSubscriptionPlansOwner.put(subId, ownerPackage);
2229 } else if (TAG_UID_POLICY.equals(tag)) {
2230 final int uid = readIntAttribute(in, ATTR_UID);
2231 final int policy = readIntAttribute(in, ATTR_POLICY);
2233 if (UserHandle.isApp(uid)) {
2234 setUidPolicyUncheckedUL(uid, policy, false);
2236 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
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);
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);
2248 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
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);
2259 } else if (type == END_TAG) {
2260 if (TAG_WHITELIST.equals(tag)) {
2261 insideWhitelist = false;
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));
2276 if (UserHandle.isApp(uid)) {
2277 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
2279 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
2280 setUidPolicyUncheckedUL(uid, newPolicy, false);
2282 Slog.w(TAG, "unable to update policy on UID " + uid);
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);
2292 IoUtils.closeQuietly(fis);
2297 * Upgrade legacy background data flags, notifying listeners of one last
2298 * change to always-true.
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.
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;
2308 // NOTE: We used to read the legacy setting here :
2310 // final int legacyFlagValue = Settings.Secure.getInt(
2311 // mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..);
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.
2319 * Perform upgrade step of moving any user-defined meterness overrides over
2320 * into {@link WifiConfiguration}.
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);
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);
2352 void writePolicyAL() {
2353 if (LOGV) Slog.v(TAG, "writePolicyAL()");
2355 FileOutputStream fos = null;
2357 fos = mPolicyFile.startWrite();
2359 XmlSerializer out = new FastXmlSerializer();
2360 out.setOutput(fos, StandardCharsets.UTF_8.name());
2361 out.startDocument(null, true);
2363 out.startTag(null, TAG_POLICY_LIST);
2364 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
2365 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
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;
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);
2379 final String networkId = template.getNetworkId();
2380 if (networkId != null) {
2381 out.attribute(null, ATTR_NETWORK_ID, networkId);
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);
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;
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);
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);
2431 // skip writing empty policies
2432 if (policy == POLICY_NONE) continue;
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);
2440 out.endTag(null, TAG_POLICY_LIST);
2442 // write all whitelists
2443 out.startTag(null, TAG_WHITELIST);
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);
2454 out.endTag(null, TAG_WHITELIST);
2458 mPolicyFile.finishWrite(fos);
2459 } catch (IOException e) {
2461 mPolicyFile.failWrite(fos);
2467 public void setUidPolicy(int uid, int policy) {
2468 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2470 if (!UserHandle.isApp(uid)) {
2471 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2473 synchronized (mUidRulesFirstLock) {
2474 final long token = Binder.clearCallingIdentity();
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);
2482 Binder.restoreCallingIdentity(token);
2488 public void addUidPolicy(int uid, int policy) {
2489 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2491 if (!UserHandle.isApp(uid)) {
2492 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
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);
2506 public void removeUidPolicy(int uid, int policy) {
2507 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2509 if (!UserHandle.isApp(uid)) {
2510 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
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);
2523 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
2524 setUidPolicyUncheckedUL(uid, policy, false);
2526 final boolean notifyApp;
2527 if (!isUidValidForWhitelistRules(uid)) {
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)) {
2540 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist");
2541 mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2543 notifyApp = wasBlocked != isBlocked;
2545 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2548 synchronized (mNetworkPoliciesSecondLock) {
2554 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
2555 if (policy == POLICY_NONE) {
2556 mUidPolicy.delete(uid);
2558 mUidPolicy.put(uid, policy);
2561 // uid policy changed, recompute rules and persist policy.
2562 updateRulesForDataUsageRestrictionsUL(uid);
2564 synchronized (mNetworkPoliciesSecondLock) {
2571 public int getUidPolicy(int uid) {
2572 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2574 synchronized (mUidRulesFirstLock) {
2575 return mUidPolicy.get(uid, POLICY_NONE);
2580 public int[] getUidsWithPolicy(int policy) {
2581 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
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);
2598 * Removes any persistable state associated with given {@link UserHandle}, persisting
2599 * if any changes that are made.
2601 boolean removeUserStateUL(int userId, boolean writePolicy) {
2603 mLogger.removingUserState(userId);
2604 boolean changed = false;
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);
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);
2624 if (uids.length > 0) {
2625 for (int uid : uids) {
2626 mUidPolicy.delete(uid);
2630 synchronized (mNetworkPoliciesSecondLock) {
2631 updateRulesForGlobalChangeAL(true);
2632 if (writePolicy && changed) {
2640 public void registerListener(INetworkPolicyListener listener) {
2641 // TODO: create permission for observing network policy
2642 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2643 mListeners.register(listener);
2647 public void unregisterListener(INetworkPolicyListener listener) {
2648 // TODO: create permission for observing network policy
2649 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2650 mListeners.unregister(listener);
2654 public void setNetworkPolicies(NetworkPolicy[] policies) {
2655 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2657 final long token = Binder.clearCallingIdentity();
2659 synchronized (mUidRulesFirstLock) {
2660 synchronized (mNetworkPoliciesSecondLock) {
2661 normalizePoliciesNL(policies);
2662 handleNetworkPoliciesUpdateAL(false);
2666 Binder.restoreCallingIdentity(token);
2670 void addNetworkPolicyAL(NetworkPolicy policy) {
2671 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
2672 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
2673 setNetworkPolicies(policies);
2677 public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
2678 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2680 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
2681 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
2683 } catch (SecurityException e) {
2684 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
2686 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
2687 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2688 return new NetworkPolicy[0];
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);
2702 private void normalizePoliciesNL() {
2703 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
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);
2717 mNetworkPolicy.put(policy.template, policy);
2723 public void snoozeLimit(NetworkTemplate template) {
2724 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2726 final long token = Binder.clearCallingIdentity();
2728 performSnooze(template, TYPE_LIMIT);
2730 Binder.restoreCallingIdentity(token);
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);
2746 policy.lastWarningSnooze = currentTime;
2749 policy.lastLimitSnooze = currentTime;
2752 policy.lastRapidSnooze = currentTime;
2755 throw new IllegalArgumentException("unexpected type");
2758 handleNetworkPoliciesUpdateAL(true);
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);
2775 public void setRestrictBackground(boolean restrictBackground) {
2776 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
2778 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2779 final long token = Binder.clearCallingIdentity();
2781 synchronized (mUidRulesFirstLock) {
2782 setRestrictBackgroundUL(restrictBackground);
2785 Binder.restoreCallingIdentity(token);
2788 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2792 private void setRestrictBackgroundUL(boolean restrictBackground) {
2793 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL");
2795 if (restrictBackground == mRestrictBackground) {
2796 // Ideally, UI should never allow this scenario...
2797 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground);
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();
2808 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
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.
2816 } catch (RemoteException e) {
2817 // ignored; service lives in system_server
2820 sendRestrictBackgroundChangedMsg();
2821 mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
2823 if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
2824 mRestrictBackgroundChangedInBsm = true;
2826 synchronized (mNetworkPoliciesSecondLock) {
2827 updateNotificationsNL();
2831 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2835 private void sendRestrictBackgroundChangedMsg() {
2836 mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED);
2837 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0)
2842 public int getRestrictBackgroundByCaller() {
2843 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2844 final int uid = Binder.getCallingUid();
2846 synchronized (mUidRulesFirstLock) {
2847 // Must clear identity because getUidPolicy() is restricted to system.
2848 final long token = Binder.clearCallingIdentity();
2851 policy = getUidPolicy(uid);
2853 Binder.restoreCallingIdentity(token);
2855 if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2856 // App is blacklisted.
2857 return RESTRICT_BACKGROUND_STATUS_ENABLED;
2859 if (!mRestrictBackground) {
2860 return RESTRICT_BACKGROUND_STATUS_DISABLED;
2862 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
2863 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2864 : RESTRICT_BACKGROUND_STATUS_ENABLED;
2869 public boolean getRestrictBackground() {
2870 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2872 synchronized (mUidRulesFirstLock) {
2873 return mRestrictBackground;
2878 public void setDeviceIdleMode(boolean enabled) {
2879 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2880 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2882 synchronized (mUidRulesFirstLock) {
2883 if (mDeviceIdleMode == enabled) {
2886 mDeviceIdleMode = enabled;
2887 mLogger.deviceIdleModeEnabled(enabled);
2889 // Device idle change means we need to rebuild rules for all
2890 // known apps, so do a global refresh.
2891 updateRulesForRestrictPowerUL();
2895 EventLogTags.writeDeviceIdleOnPhase("net");
2897 EventLogTags.writeDeviceIdleOffPhase("net");
2900 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2905 public void setWifiMeteredOverride(String networkId, int meteredOverride) {
2906 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2907 final long token = Binder.clearCallingIdentity();
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);
2918 Binder.restoreCallingIdentity(token);
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();
2930 private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) {
2931 // Verify they're not lying about package name
2932 mAppOps.checkPackage(callingUid, callingPackage);
2934 final SubscriptionInfo si;
2935 final PersistableBundle config;
2936 final long token = Binder.clearCallingIdentity();
2938 si = mContext.getSystemService(SubscriptionManager.class)
2939 .getActiveSubscriptionInfo(subId);
2940 config = mCarrierConfigManager.getConfigForSubId(subId);
2942 Binder.restoreCallingIdentity(token);
2945 // First check: is caller the CarrierService?
2947 if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
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)) {
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)) {
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)) {
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)) {
2983 // Final check: does the caller hold a permission?
2984 mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
2988 public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
2989 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
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())
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())
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())
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())
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())
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())
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())
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())
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())
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")
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())
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())
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())
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())
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())
3129 return plans.toArray(new SubscriptionPlan[plans.size()]);
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);
3141 Log.w(TAG, "Not returning plans because caller " + callingPackage
3142 + " doesn't match owner " + ownerPackage);
3149 public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) {
3150 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3152 for (SubscriptionPlan plan : plans) {
3153 Preconditions.checkNotNull(plan);
3156 final long token = Binder.clearCallingIdentity();
3158 synchronized (mUidRulesFirstLock) {
3159 synchronized (mNetworkPoliciesSecondLock) {
3160 mSubscriptionPlans.put(subId, plans);
3161 mSubscriptionPlansOwner.put(subId, callingPackage);
3163 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
3164 if (subscriberId != null) {
3165 ensureActiveMobilePolicyAL(subId, subscriberId);
3166 maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
3168 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
3171 handleNetworkPoliciesUpdateAL(true);
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);
3180 Binder.restoreCallingIdentity(token);
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.
3188 void setSubscriptionPlansOwner(int subId, String packageName) {
3189 SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName);
3193 public String getSubscriptionPlansOwner(int subId) {
3194 if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) {
3195 throw new SecurityException();
3198 synchronized (mNetworkPoliciesSecondLock) {
3199 return mSubscriptionPlansOwner.get(subId);
3204 public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
3205 long timeoutMillis, String callingPackage) {
3206 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3208 // We can only override when carrier told us about plans
3209 synchronized (mNetworkPoliciesSecondLock) {
3210 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
3212 || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
3213 throw new IllegalStateException(
3214 "Must provide valid SubscriptionPlan to enable overriding");
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);
3233 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
3234 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
3236 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
3238 final ArraySet<String> argSet = new ArraySet<String>(args.length);
3239 for (String arg : args) {
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();
3250 handleNetworkPoliciesUpdateAL(true);
3252 fout.println("Cleared snooze timestamps");
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));
3263 fout.println("Network policies:");
3264 fout.increaseIndent();
3265 for (int i = 0; i < mNetworkPolicy.size(); i++) {
3266 fout.println(mNetworkPolicy.valueAt(i).toString());
3268 fout.decreaseIndent();
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) {
3283 fout.decreaseIndent();
3285 fout.decreaseIndent();
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);
3294 fout.println(subId + "=" + NetworkIdentity.scrubSubscriberId(subscriberId));
3296 fout.decreaseIndent();
3299 fout.println("Merged subscriptions: "
3300 + Arrays.toString(NetworkIdentity.scrubSubscriberId(mMergedSubscriberIds)));
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);
3311 fout.print(" policy=");
3312 fout.print(uidPoliciesToString(policy));
3315 fout.decreaseIndent();
3317 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3319 fout.println("Power save whitelist (except idle) app ids:");
3320 fout.increaseIndent();
3321 for (int i = 0; i < size; i++) {
3323 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3325 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
3328 fout.decreaseIndent();
3331 size = mPowerSaveWhitelistAppIds.size();
3333 fout.println("Power save whitelist app ids:");
3334 fout.increaseIndent();
3335 for (int i = 0; i < size; i++) {
3337 fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
3339 fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
3342 fout.decreaseIndent();
3345 size = mDefaultRestrictBackgroundWhitelistUids.size();
3347 fout.println("Default restrict background whitelist uids:");
3348 fout.increaseIndent();
3349 for (int i = 0; i < size; i++) {
3351 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
3354 fout.decreaseIndent();
3357 size = mRestrictBackgroundWhitelistRevokedUids.size();
3359 fout.println("Default restrict background whitelist uids revoked by users:");
3360 fout.increaseIndent();
3361 for (int i = 0; i < size; i++) {
3363 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
3366 fout.decreaseIndent();
3369 final SparseBooleanArray knownUids = new SparseBooleanArray();
3370 collectKeys(mUidState, knownUids);
3371 collectKeys(mUidRules, knownUids);
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);
3381 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3382 fout.print(" state=");
3384 if (state <= ActivityManager.PROCESS_STATE_TOP) {
3385 fout.print(" (fg)");
3387 fout.print(state <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
3388 ? " (fg svc)" : " (bg)");
3391 final int uidRules = mUidRules.get(uid, RULE_NONE);
3392 fout.print(" rules=");
3393 fout.print(uidRulesToString(uidRules));
3396 fout.decreaseIndent();
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);
3405 final int uidRules = mUidRules.get(uid, RULE_NONE);
3406 fout.print(" rules=");
3407 fout.print(uidRulesToString(uidRules));
3410 fout.decreaseIndent();
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));
3419 fout.decreaseIndent();
3422 mStatLogger.dump(fout);
3424 mLogger.dumpLogs(fout);
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);
3437 public boolean isUidForeground(int uid) {
3438 synchronized (mUidRulesFirstLock) {
3439 return isUidStateForeground(
3440 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
3444 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
3445 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3446 return isProcStateAllowedWhileOnRestrictBackground(procState);
3449 private boolean isUidForegroundOnRestrictPowerUL(int uid) {
3450 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3451 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
3454 private boolean isUidStateForeground(int state) {
3455 // only really in foreground when screen is also on
3456 return state <= NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
3460 * Process state of UID changed; if needed, will trigger
3461 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
3462 * {@link #updateRulesForPowerRestrictionsUL(int)}
3464 private void updateUidStateUL(int uid, int uidState) {
3465 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
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);
3478 if (mRestrictPower) {
3479 updateRuleForRestrictPowerUL(uid);
3481 updateRulesForPowerRestrictionsUL(uid);
3483 updateNetworkStats(uid, isUidStateForeground(uidState));
3486 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3490 private void removeUidStateUL(int uid) {
3491 final int index = mUidState.indexOfKey(uid);
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);
3501 if (mRestrictPower) {
3502 updateRuleForRestrictPowerUL(uid);
3504 updateRulesForPowerRestrictionsUL(uid);
3505 updateNetworkStats(uid, false);
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"));
3517 mNetworkStats.setUidForeground(uid, uidForeground);
3519 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3523 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
3525 final boolean oldForeground =
3526 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
3527 final boolean newForeground =
3528 isProcStateAllowedWhileOnRestrictBackground(newUidState);
3529 if (oldForeground != newForeground) {
3530 updateRulesForDataUsageRestrictionsUL(uid);
3534 void updateRulesForPowerSaveUL() {
3535 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
3537 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
3538 mUidFirewallPowerSaveRules);
3540 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3544 void updateRuleForRestrictPowerUL(int uid) {
3545 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
3548 void updateRulesForDeviceIdleUL() {
3549 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
3551 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
3552 mUidFirewallDozableRules);
3554 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3558 void updateRuleForDeviceIdleUL(int uid) {
3559 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
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) {
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;
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);
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);
3586 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);
3588 setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);
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);
3604 * @param deviceIdleMode if true then we don't consider
3605 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
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);
3615 return isWhitelisted;
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) {
3622 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid,
3623 chain == FIREWALL_CHAIN_DOZABLE);
3624 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
3625 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
3627 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
3632 void updateRulesForAppIdleUL() {
3633 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
3635 final SparseIntArray uidRules = mUidFirewallStandbyRules;
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
3648 if (hasInternetPermissions(uid)) {
3649 uidRules.put(uid, FIREWALL_RULE_DENY);
3655 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
3657 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3661 void updateRuleForAppIdleUL(int uid) {
3662 if (!isUidValidForBlacklistRules(uid)) return;
3664 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3665 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
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);
3673 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
3676 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3681 * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
3684 void updateRulesForAppIdleParoleUL() {
3685 boolean paroled = mUsageStats.isAppIdleParoleOn();
3686 boolean enableChain = !paroled;
3687 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
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);
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;
3700 // Skip if it had no restrictions to begin with
3701 if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
3703 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
3704 if (newUidRules == RULE_NONE) {
3705 mUidRules.delete(uid);
3707 mUidRules.put(uid, newUidRules);
3713 * Update rules that might be changed by {@link #mRestrictBackground},
3714 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
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" : "-"));
3722 updateRulesForAppIdleUL();
3723 updateRulesForRestrictPowerUL();
3724 updateRulesForRestrictBackgroundUL();
3726 // If the set of restricted networks may have changed, re-evaluate those.
3727 if (restrictedNetworksChanged) {
3728 normalizePoliciesNL();
3729 updateNetworkRulesNL();
3732 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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");
3740 updateRulesForDeviceIdleUL();
3741 updateRulesForPowerSaveUL();
3742 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
3744 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3748 private void updateRulesForRestrictBackgroundUL() {
3749 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
3751 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
3753 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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,
3764 public @interface RestrictType {
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);
3773 // update rules for all installed applications
3775 final PackageManager pm = mContext.getPackageManager();
3776 final List<UserInfo> users;
3777 final List<ApplicationInfo> apps;
3779 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
3781 users = mUserManager.getUsers();
3783 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3785 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids");
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);
3792 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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);
3803 case TYPE_RESTRICT_BACKGROUND:
3804 updateRulesForDataUsageRestrictionsUL(uid);
3806 case TYPE_RESTRICT_POWER:
3807 updateRulesForPowerRestrictionsUL(uid);
3810 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
3815 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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);
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))) {
3846 private boolean isUidValidForWhitelistRules(int uid) {
3847 return UserHandle.isApp(uid) && hasInternetPermissions(uid);
3850 private boolean isUidIdle(int uid) {
3851 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
3852 final int userId = UserHandle.getUserId(uid);
3854 if (packages != null) {
3855 for (String packageName : packages) {
3856 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
3865 * Checks if an uid has INTERNET permissions.
3867 * Useful for the cases where the lack of network access can simplify the rules.
3869 private boolean hasInternetPermissions(int uid) {
3871 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
3872 != PackageManager.PERMISSION_GRANTED) {
3875 } catch (RemoteException e) {
3881 * Clears all state - internal and external - associated with an UID.
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);
3894 // ...then update iptables asynchronously.
3895 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
3899 * Applies network rules to bandwidth and firewall controllers based on uid policy.
3901 * <p>There are currently 4 types of restriction rules:
3905 * <li>Battery Saver Mode (also referred as power save).
3906 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
3909 * <p>This method changes both the external firewall rules and the internal state.
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);
3917 // Update internal state for power-related modes.
3918 updateRulesForPowerRestrictionsUL(uid);
3920 // Update firewall and internal rules for Data Saver Mode.
3921 updateRulesForDataUsageRestrictionsUL(uid);
3925 * Applies network rules to bandwidth controllers based on process state and user-defined
3926 * restrictions (blacklist / whitelist).
3929 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
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
3935 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
3936 * no UIDs other those whitelisted will have access.
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:
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.
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.
3960 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
3963 private void updateRulesForDataUsageRestrictionsUL(int uid) {
3964 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3965 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3966 "updateRulesForDataUsageRestrictionsUL: " + uid);
3969 updateRulesForDataUsageRestrictionsULInner(uid);
3971 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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);
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);
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;
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;
4001 if (isBlacklisted) {
4002 newRule = RULE_REJECT_METERED;
4003 } else if (mRestrictBackground && isWhitelisted) {
4004 newRule = RULE_ALLOW_METERED;
4007 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
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));
4021 if (newUidRules == RULE_NONE) {
4022 mUidRules.delete(uid);
4024 mUidRules.put(uid, newUidRules);
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).
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);
4040 } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
4041 // Remove temporary whitelist from app that is not on foreground anymore.
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);
4050 if (isBlacklisted || isRestrictedByAdmin) {
4051 setMeteredNetworkBlacklist(uid, true);
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);
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);
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));
4078 // Dispatch changed rule to existing listeners.
4079 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
4084 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
4085 * listeners in case of change.
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:
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.
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.
4099 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
4101 private void updateRulesForPowerRestrictionsUL(int uid) {
4102 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
4104 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false);
4106 if (newUidRules == RULE_NONE) {
4107 mUidRules.delete(uid);
4109 mUidRules.put(uid, newUidRules);
4114 * Similar to above but ignores idle state if app standby is currently disabled by parole.
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.
4120 * @return the new computed rules for the uid
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" : "-"));
4129 return updateRulesForPowerRestrictionsULInner(uid, oldUidRules, paroled);
4131 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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);
4141 final boolean isIdle = !paroled && isUidIdle(uid);
4142 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
4143 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
4145 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode);
4146 final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
4147 int newRule = RULE_NONE;
4149 // First step: define the new rule based on user restrictions and foreground state.
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.
4155 newRule = RULE_ALLOW_ALL;
4157 } else if (restrictMode) {
4158 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
4161 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
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));
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);
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));
4190 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
4196 private class AppIdleStateChangeListener
4197 extends UsageStatsManagerInternal.AppIdleStateChangeListener {
4200 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
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);
4210 } catch (NameNotFoundException nnfe) {
4215 public void onParoleStateChanged(boolean isParoleOn) {
4216 synchronized (mUidRulesFirstLock) {
4217 mLogger.paroleStateChanged(isParoleOn);
4218 updateRulesForAppIdleParoleUL();
4223 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
4224 if (listener != null) {
4226 listener.onUidRulesChanged(uid, uidRules);
4227 } catch (RemoteException ignored) {
4232 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
4233 String[] meteredIfaces) {
4234 if (listener != null) {
4236 listener.onMeteredIfacesChanged(meteredIfaces);
4237 } catch (RemoteException ignored) {
4242 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
4243 boolean restrictBackground) {
4244 if (listener != null) {
4246 listener.onRestrictBackgroundChanged(restrictBackground);
4247 } catch (RemoteException ignored) {
4252 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
4254 if (listener != null) {
4256 listener.onUidPoliciesChanged(uid, uidPolicies);
4257 } catch (RemoteException ignored) {
4262 private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
4263 int overrideMask, int overrideValue) {
4264 if (listener != null) {
4266 listener.onSubscriptionOverride(subId, overrideMask, overrideValue);
4267 } catch (RemoteException ignored) {
4272 private final Handler.Callback mHandlerCallback = new Handler.Callback() {
4274 public boolean handleMessage(Message msg) {
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);
4284 mListeners.finishBroadcast();
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);
4294 mListeners.finishBroadcast();
4297 case MSG_LIMIT_REACHED: {
4298 final String iface = (String) msg.obj;
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();
4306 updateNetworkEnabledNL();
4307 updateNotificationsNL();
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);
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);
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);
4336 mListeners.finishBroadcast();
4337 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
4338 if (notifyApp.booleanValue()) {
4339 broadcastRestrictBackgroundChanged(uid, notifyApp);
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);
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));
4358 case MSG_REMOVE_INTERFACE_QUOTA: {
4359 removeInterfaceQuota((String) msg.obj);
4362 case MSG_RESET_FIREWALL_RULES_BY_UID: {
4363 resetUidFirewallRules(msg.arg1);
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);
4375 mListeners.finishBroadcast();
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);
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);
4397 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
4399 public boolean handleMessage(Message msg) {
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;
4406 handleUidChanged(uid, procState, procStateSeq);
4409 case UID_MSG_GONE: {
4410 final int uid = msg.arg1;
4422 void handleUidChanged(int uid, int procState, long procStateSeq) {
4423 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
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);
4435 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4439 void handleUidGone(int uid) {
4440 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
4442 synchronized (mUidRulesFirstLock) {
4443 removeUidStateUL(uid);
4446 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
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));
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();
4471 private void setInterfaceQuota(String iface, long quotaBytes) {
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
4481 private void removeInterfaceQuotaAsync(String iface) {
4482 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface).sendToTarget();
4485 private void removeInterfaceQuota(String iface) {
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
4495 private void setMeteredNetworkBlacklist(int uid, boolean enable) {
4496 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
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
4506 private void setMeteredNetworkWhitelist(int uid, boolean enable) {
4507 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
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
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 = {
4523 CHAIN_TOGGLE_ENABLE,
4524 CHAIN_TOGGLE_DISABLE
4526 public @interface ChainToggleType {
4530 * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
4531 * {@link #enableFirewallChainUL(int, boolean)} synchronously.
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.
4537 private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,
4538 @ChainToggleType int toggle) {
4539 if (uidRules != null) {
4540 setUidFirewallRulesUL(chain, uidRules);
4542 if (toggle != CHAIN_TOGGLE_NONE) {
4543 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
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
4552 private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
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);
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
4571 * Add or remove a uid to the firewall blacklist for all network ifaces.
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);
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);
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
4596 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4601 * Add or remove a uid to the firewall blacklist for all network ifaces.
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.
4609 mFirewallChainStates.put(chain, enable);
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
4621 * Resets all firewall rules associated with an UID.
4623 private void resetUidFirewallRules(int uid) {
4625 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
4626 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
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
4639 private long getTotalBytes(NetworkTemplate template, long start, long end) {
4640 return getNetworkTotalBytes(template, start, end);
4643 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
4645 return mNetworkStats.getNetworkTotalBytes(template, start, end);
4646 } catch (RuntimeException e) {
4647 Slog.w(TAG, "Failed to read network stats: " + e);
4652 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
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);
4661 private boolean isBandwidthControlEnabled() {
4662 final long token = Binder.clearCallingIdentity();
4664 return mNetworkManager.isBandwidthControlEnabled();
4665 } catch (RemoteException e) {
4666 // ignored; service lives in system_server
4669 Binder.restoreCallingIdentity(token);
4673 private static Intent buildAllowBackgroundDataIntent() {
4674 return new Intent(ACTION_ALLOW_BACKGROUND);
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);
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);
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);
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);
4710 public void addIdleHandler(IdleHandler handler) {
4711 mHandler.getLooper().getQueue().addIdleHandler(handler);
4715 public void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
4716 mRestrictBackgroundPowerState = result;
4718 boolean restrictBackground = result.batterySaverEnabled;
4719 boolean shouldInvokeRestrictBackground;
4720 // store the temporary mRestrictBackgroundChangedInBsm and update it at last
4721 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
4723 if (result.globalBatterySaverEnabled) {
4724 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
4726 shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
4727 mRestrictBackgroundBeforeBsm = mRestrictBackground;
4728 localRestrictBgChangedInBsm = false;
4730 // Try to restore the restrictBackground if it doesn't change in bsm
4731 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
4732 restrictBackground = mRestrictBackgroundBeforeBsm;
4735 if (shouldInvokeRestrictBackground) {
4736 setRestrictBackgroundUL(restrictBackground);
4739 // Change it at last so setRestrictBackground() won't affect this variable
4740 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
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);
4751 public void factoryReset(String subscriber) {
4752 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
4754 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
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();
4768 setNetworkPolicies(policies);
4770 // Turn restrict background data off
4771 setRestrictBackground(false);
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);
4782 public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
4783 final long startTime = mStatLogger.getTime();
4785 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
4786 final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
4788 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
4793 private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
4795 final boolean isBackgroundRestricted;
4796 synchronized (mUidRulesFirstLock) {
4797 uidRules = mUidRules.get(uid, RULE_NONE);
4798 isBackgroundRestricted = mRestrictBackground;
4800 if (hasRule(uidRules, RULE_REJECT_ALL)) {
4801 mLogger.networkBlocked(uid, NTWK_BLOCKED_POWER);
4804 if (!isNetworkMetered) {
4805 mLogger.networkBlocked(uid, NTWK_ALLOWED_NON_METERED);
4808 if (hasRule(uidRules, RULE_REJECT_METERED)) {
4809 mLogger.networkBlocked(uid, NTWK_BLOCKED_BLACKLIST);
4812 if (hasRule(uidRules, RULE_ALLOW_METERED)) {
4813 mLogger.networkBlocked(uid, NTWK_ALLOWED_WHITELIST);
4816 if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
4817 mLogger.networkBlocked(uid, NTWK_ALLOWED_TMP_WHITELIST);
4820 if (isBackgroundRestricted) {
4821 mLogger.networkBlocked(uid, NTWK_BLOCKED_BG_RESTRICT);
4824 mLogger.networkBlocked(uid, NTWK_ALLOWED_DEFAULT);
4828 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
4831 public void resetUserState(int userId) {
4832 synchronized (mUidRulesFirstLock) {
4833 boolean changed = removeUserStateUL(userId, false);
4834 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
4836 synchronized (mNetworkPoliciesSecondLock) {
4844 * @return true if the given uid is restricted from doing networking on metered networks.
4847 public boolean isUidRestrictedOnMeteredNetworks(int uid) {
4849 final boolean isBackgroundRestricted;
4850 synchronized (mUidRulesFirstLock) {
4851 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
4852 isBackgroundRestricted = mRestrictBackground;
4854 return isBackgroundRestricted
4855 && !hasRule(uidRules, RULE_ALLOW_METERED)
4856 && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
4860 * @return true if networking is blocked on the given interface for the given uid according
4861 * to current networking policies.
4864 public boolean isUidNetworkingBlocked(int uid, String ifname) {
4865 final long startTime = mStatLogger.getTime();
4867 final boolean isNetworkMetered;
4868 synchronized (mNetworkPoliciesSecondLock) {
4869 isNetworkMetered = mMeteredIfaces.contains(ifname);
4871 final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
4873 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
4879 public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
4880 synchronized (mUidRulesFirstLock) {
4881 mLogger.tempPowerSaveWlChanged(appId, added);
4883 mPowerSaveTempWhitelistAppIds.put(appId, true);
4885 mPowerSaveTempWhitelistAppIds.delete(appId);
4887 updateRulesForTempWhitelistChangeUL(appId);
4892 public SubscriptionPlan getSubscriptionPlan(Network network) {
4893 synchronized (mNetworkPoliciesSecondLock) {
4894 final int subId = getSubIdLocked(network);
4895 return getPrimarySubscriptionPlanLocked(subId);
4900 public SubscriptionPlan getSubscriptionPlan(NetworkTemplate template) {
4901 synchronized (mNetworkPoliciesSecondLock) {
4902 final int subId = findRelevantSubIdNL(template);
4903 return getPrimarySubscriptionPlanLocked(subId);
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);
4914 if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
4915 return OPPORTUNISTIC_QUOTA_UNKNOWN;
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));
4925 return OPPORTUNISTIC_QUOTA_UNKNOWN;
4930 public void onAdminDataAvailable() {
4931 mAdminDataAvailableLatch.countDown();
4935 public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) {
4936 setMeteredRestrictedPackagesInternal(packageNames, userId);
4940 public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) {
4941 mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
4942 userId, 0, packageNames).sendToTarget();
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);
4952 newRestrictedUids.add(uid);
4955 final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId);
4956 mMeteredRestrictedUids.put(userId, newRestrictedUids);
4957 handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids);
4958 mLogger.meteredRestrictedPkgsChanged(newRestrictedUids);
4962 private int getUidForPackage(String packageName, int userId) {
4964 return mContext.getPackageManager().getPackageUidAsUser(packageName,
4965 PackageManager.MATCH_KNOWN_PACKAGES, userId);
4966 } catch (NameNotFoundException e) {
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) {
4979 subId = Integer.parseInt(((StringNetworkSpecifier) spec).specifier);
4980 } catch (NumberFormatException e) {
4987 @GuardedBy("mNetworkPoliciesSecondLock")
4988 private int getSubIdLocked(Network network) {
4989 return mNetIdToSubId.get(network.netId, INVALID_SUBSCRIPTION_ID);
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
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))) {
5013 * This will only ever be called once - during device boot.
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");
5022 private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids,
5023 Set<Integer> newRestrictedUids) {
5024 if (oldRestrictedUids == null) {
5025 for (int uid : newRestrictedUids) {
5026 updateRulesForDataUsageRestrictionsUL(uid);
5030 for (int uid : oldRestrictedUids) {
5031 if (!newRestrictedUids.contains(uid)) {
5032 updateRulesForDataUsageRestrictionsUL(uid);
5035 for (int uid : newRestrictedUids) {
5036 if (!oldRestrictedUids.contains(uid)) {
5037 updateRulesForDataUsageRestrictionsUL(uid);
5042 private boolean isRestrictedByAdminUL(int uid) {
5043 final Set<Integer> restrictedUids = mMeteredRestrictedUids.get(
5044 UserHandle.getUserId(uid));
5045 return restrictedUids != null && restrictedUids.contains(uid);
5048 private static boolean hasRule(int uidRules, int rule) {
5049 return (uidRules & rule) != 0;
5052 private static @NonNull NetworkState[] defeatNullable(@Nullable NetworkState[] val) {
5053 return (val != null) ? val : new NetworkState[0];
5056 private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle,
5057 String key, boolean defaultValue) {
5058 return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
5061 private class NotificationId {
5062 private final String mTag;
5063 private final int mId;
5065 NotificationId(NetworkPolicy policy, int type) {
5066 mTag = buildNotificationTag(policy, type);
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);
5079 public int hashCode() {
5080 return Objects.hash(mTag);
5084 * Build unique tag that identifies an active {@link NetworkPolicy}
5085 * notification of a specific type, like {@link #TYPE_LIMIT}.
5087 private String buildNotificationTag(NetworkPolicy policy, int type) {
5088 return TAG + ":" + policy.template.hashCode() + ":" + type;
5091 public String getTag() {
5095 public int getId() {