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.DUMP;
22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
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.net.ConnectivityManager.CONNECTIVITY_ACTION;
32 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
33 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
34 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
35 import static android.net.ConnectivityManager.TYPE_MOBILE;
36 import static android.net.ConnectivityManager.TYPE_WIMAX;
37 import static android.net.ConnectivityManager.isNetworkTypeMobile;
38 import static android.net.NetworkPolicy.CYCLE_NONE;
39 import static android.net.NetworkPolicy.LIMIT_DISABLED;
40 import static android.net.NetworkPolicy.SNOOZE_NEVER;
41 import static android.net.NetworkPolicy.WARNING_DISABLED;
42 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
43 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
44 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE;
45 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
46 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
47 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
48 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
49 import static android.net.NetworkPolicyManager.POLICY_NONE;
50 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
51 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
52 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
53 import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
54 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
55 import static android.net.NetworkPolicyManager.RULE_NONE;
56 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
57 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
58 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
59 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
60 import static android.net.NetworkPolicyManager.uidRulesToString;
61 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
62 import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
63 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
64 import static android.net.NetworkTemplate.MATCH_WIFI;
65 import static android.net.NetworkTemplate.buildTemplateMobileAll;
66 import static android.net.TrafficStats.MB_IN_BYTES;
67 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
68 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
69 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
70 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
71 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
72 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
73 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
74 import static android.text.format.DateUtils.DAY_IN_MILLIS;
76 import static com.android.internal.util.ArrayUtils.appendInt;
77 import static com.android.internal.util.Preconditions.checkNotNull;
78 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
79 import static com.android.internal.util.XmlUtils.readIntAttribute;
80 import static com.android.internal.util.XmlUtils.readLongAttribute;
81 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
82 import static com.android.internal.util.XmlUtils.writeIntAttribute;
83 import static com.android.internal.util.XmlUtils.writeLongAttribute;
84 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
85 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
87 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
88 import static org.xmlpull.v1.XmlPullParser.END_TAG;
89 import static org.xmlpull.v1.XmlPullParser.START_TAG;
91 import android.Manifest;
92 import android.annotation.IntDef;
93 import android.annotation.Nullable;
94 import android.app.ActivityManager;
95 import android.app.AppGlobals;
96 import android.app.AppOpsManager;
97 import android.app.IActivityManager;
98 import android.app.INotificationManager;
99 import android.app.IUidObserver;
100 import android.app.Notification;
101 import android.app.PendingIntent;
102 import android.app.usage.UsageStatsManagerInternal;
103 import android.content.BroadcastReceiver;
104 import android.content.ComponentName;
105 import android.content.Context;
106 import android.content.Intent;
107 import android.content.IntentFilter;
108 import android.content.pm.ApplicationInfo;
109 import android.content.pm.IPackageManager;
110 import android.content.pm.PackageManager;
111 import android.content.pm.PackageManager.NameNotFoundException;
112 import android.content.pm.UserInfo;
113 import android.content.res.Resources;
114 import android.net.ConnectivityManager;
115 import android.net.IConnectivityManager;
116 import android.net.INetworkManagementEventObserver;
117 import android.net.INetworkPolicyListener;
118 import android.net.INetworkPolicyManager;
119 import android.net.INetworkStatsService;
120 import android.net.LinkProperties;
121 import android.net.NetworkIdentity;
122 import android.net.NetworkInfo;
123 import android.net.NetworkPolicy;
124 import android.net.NetworkPolicyManager;
125 import android.net.NetworkQuotaInfo;
126 import android.net.NetworkState;
127 import android.net.NetworkTemplate;
128 import android.net.wifi.WifiConfiguration;
129 import android.net.wifi.WifiInfo;
130 import android.net.wifi.WifiManager;
131 import android.os.Binder;
132 import android.os.Environment;
133 import android.os.Handler;
134 import android.os.HandlerThread;
135 import android.os.IDeviceIdleController;
136 import android.os.INetworkManagementService;
137 import android.os.Message;
138 import android.os.MessageQueue.IdleHandler;
139 import android.os.PowerManager;
140 import android.os.PowerManagerInternal;
141 import android.os.RemoteCallbackList;
142 import android.os.RemoteException;
143 import android.os.ResultReceiver;
144 import android.os.ServiceManager;
145 import android.os.Trace;
146 import android.os.UserHandle;
147 import android.os.UserManager;
148 import android.provider.Settings;
149 import android.telephony.SubscriptionManager;
150 import android.telephony.TelephonyManager;
151 import android.text.format.Formatter;
152 import android.text.format.Time;
153 import android.util.ArrayMap;
154 import android.util.ArraySet;
155 import android.util.AtomicFile;
156 import android.util.DebugUtils;
157 import android.util.Log;
158 import android.util.NtpTrustedTime;
159 import android.util.Pair;
160 import android.util.Slog;
161 import android.util.SparseBooleanArray;
162 import android.util.SparseIntArray;
163 import android.util.TrustedTime;
164 import android.util.Xml;
166 import com.android.internal.R;
167 import com.android.internal.annotations.GuardedBy;
168 import com.android.internal.annotations.VisibleForTesting;
169 import com.android.internal.content.PackageMonitor;
170 import com.android.internal.util.ArrayUtils;
171 import com.android.internal.util.FastXmlSerializer;
172 import com.android.internal.util.IndentingPrintWriter;
173 import com.android.server.DeviceIdleController;
174 import com.android.server.EventLogTags;
175 import com.android.server.LocalServices;
176 import com.android.server.SystemConfig;
178 import libcore.io.IoUtils;
180 import com.google.android.collect.Lists;
182 import org.xmlpull.v1.XmlPullParser;
183 import org.xmlpull.v1.XmlPullParserException;
184 import org.xmlpull.v1.XmlSerializer;
187 import java.io.FileDescriptor;
188 import java.io.FileInputStream;
189 import java.io.FileNotFoundException;
190 import java.io.FileOutputStream;
191 import java.io.IOException;
192 import java.io.PrintWriter;
193 import java.lang.annotation.Retention;
194 import java.lang.annotation.RetentionPolicy;
195 import java.nio.charset.StandardCharsets;
196 import java.util.ArrayList;
197 import java.util.Arrays;
198 import java.util.List;
201 * Service that maintains low-level network policy rules, using
202 * {@link NetworkStatsService} statistics to drive those rules.
204 * Derives active rules by combining a given policy with other system status,
205 * and delivers to listeners, such as {@link ConnectivityManager}, for
209 * This class uses 2-3 locks to synchronize state:
211 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
213 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
214 * as network policies).
215 * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks
220 * As such, methods that require synchronization have the following prefixes:
222 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
223 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
224 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
225 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
228 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
229 static final String TAG = "NetworkPolicy";
230 private static final boolean LOGD = false;
231 private static final boolean LOGV = false;
233 private static final int VERSION_INIT = 1;
234 private static final int VERSION_ADDED_SNOOZE = 2;
235 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
236 private static final int VERSION_ADDED_METERED = 4;
237 private static final int VERSION_SPLIT_SNOOZE = 5;
238 private static final int VERSION_ADDED_TIMEZONE = 6;
239 private static final int VERSION_ADDED_INFERRED = 7;
240 private static final int VERSION_SWITCH_APP_ID = 8;
241 private static final int VERSION_ADDED_NETWORK_ID = 9;
242 private static final int VERSION_SWITCH_UID = 10;
243 private static final int VERSION_LATEST = VERSION_SWITCH_UID;
246 public static final int TYPE_WARNING = 0x1;
248 public static final int TYPE_LIMIT = 0x2;
250 public static final int TYPE_LIMIT_SNOOZED = 0x3;
252 private static final String TAG_POLICY_LIST = "policy-list";
253 private static final String TAG_NETWORK_POLICY = "network-policy";
254 private static final String TAG_UID_POLICY = "uid-policy";
255 private static final String TAG_APP_POLICY = "app-policy";
256 private static final String TAG_WHITELIST = "whitelist";
257 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
258 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
260 private static final String ATTR_VERSION = "version";
261 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
262 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
263 private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
264 private static final String ATTR_NETWORK_ID = "networkId";
265 private static final String ATTR_CYCLE_DAY = "cycleDay";
266 private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
267 private static final String ATTR_WARNING_BYTES = "warningBytes";
268 private static final String ATTR_LIMIT_BYTES = "limitBytes";
269 private static final String ATTR_LAST_SNOOZE = "lastSnooze";
270 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
271 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
272 private static final String ATTR_METERED = "metered";
273 private static final String ATTR_INFERRED = "inferred";
274 private static final String ATTR_UID = "uid";
275 private static final String ATTR_APP_ID = "appId";
276 private static final String ATTR_POLICY = "policy";
278 private static final String ACTION_ALLOW_BACKGROUND =
279 "com.android.server.net.action.ALLOW_BACKGROUND";
280 private static final String ACTION_SNOOZE_WARNING =
281 "com.android.server.net.action.SNOOZE_WARNING";
283 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
285 private static final int MSG_RULES_CHANGED = 1;
286 private static final int MSG_METERED_IFACES_CHANGED = 2;
287 private static final int MSG_LIMIT_REACHED = 5;
288 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
289 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
290 private static final int MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED = 9;
291 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
292 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
293 private static final int MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED = 12;
294 private static final int MSG_SET_FIREWALL_RULES = 13;
296 private final Context mContext;
297 private final IActivityManager mActivityManager;
298 private final INetworkStatsService mNetworkStats;
299 private final INetworkManagementService mNetworkManager;
300 private UsageStatsManagerInternal mUsageStats;
301 private final TrustedTime mTime;
302 private final UserManager mUserManager;
304 private IConnectivityManager mConnManager;
305 private INotificationManager mNotifManager;
306 private PowerManagerInternal mPowerManagerInternal;
307 private IDeviceIdleController mDeviceIdleController;
309 // See main javadoc for instructions on how to use these locks.
310 final Object mUidRulesFirstLock = new Object();
311 final Object mNetworkPoliciesSecondLock = new Object();
313 @GuardedBy("allLocks") volatile boolean mSystemReady;
315 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
316 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
317 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
319 private final boolean mSuppressDefaultPolicy;
321 /** Defined network policies. */
322 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
323 /** Currently active network rules for ifaces. */
324 final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
326 /** Defined UID policies. */
327 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
328 /** Currently derived rules for each UID. */
329 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
331 @GuardedBy("mUidRulesFirstLock")
332 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
333 @GuardedBy("mUidRulesFirstLock")
334 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
335 @GuardedBy("mUidRulesFirstLock")
336 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
338 /** Set of states for the child firewall chains. True if the chain is active. */
339 @GuardedBy("mUidRulesFirstLock")
340 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
343 * UIDs that have been white-listed to always be able to have network access
344 * in power save mode, except device idle (doze) still applies.
345 * TODO: An int array might be sufficient
347 @GuardedBy("mUidRulesFirstLock")
348 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
351 * UIDs that have been white-listed to always be able to have network access
352 * in power save mode.
353 * TODO: An int array might be sufficient
355 @GuardedBy("mUidRulesFirstLock")
356 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
358 @GuardedBy("mUidRulesFirstLock")
359 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
362 * UIDs that have been white-listed to avoid restricted background.
364 @GuardedBy("mUidRulesFirstLock")
365 private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray();
368 * UIDs that have been initially white-listed by system to avoid restricted background.
370 @GuardedBy("mUidRulesFirstLock")
371 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
372 new SparseBooleanArray();
375 * UIDs that have been initially white-listed by system to avoid restricted background,
376 * but later revoked by user.
378 @GuardedBy("mUidRulesFirstLock")
379 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
380 new SparseBooleanArray();
382 /** Set of ifaces that are metered. */
383 @GuardedBy("mNetworkPoliciesSecondLock")
384 private ArraySet<String> mMeteredIfaces = new ArraySet<>();
385 /** Set of over-limit templates that have been notified. */
386 @GuardedBy("mNetworkPoliciesSecondLock")
387 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
389 /** Set of currently active {@link Notification} tags. */
390 @GuardedBy("mNetworkPoliciesSecondLock")
391 private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
393 /** Foreground at UID granularity. */
394 @GuardedBy("mUidRulesFirstLock")
395 final SparseIntArray mUidState = new SparseIntArray();
397 /** Higher priority listener before general event dispatch */
398 private INetworkPolicyListener mConnectivityListener;
400 private final RemoteCallbackList<INetworkPolicyListener>
401 mListeners = new RemoteCallbackList<>();
403 final Handler mHandler;
405 @GuardedBy("allLocks")
406 private final AtomicFile mPolicyFile;
408 private final AppOpsManager mAppOps;
410 private final MyPackageMonitor mPackageMonitor;
411 private final IPackageManager mIPm;
414 // TODO: keep whitelist of system-critical services that should never have
415 // rules enforced, such as system, phone, and radio UIDs.
417 // TODO: migrate notifications to SystemUI
419 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
420 INetworkStatsService networkStats, INetworkManagementService networkManagement) {
421 this(context, activityManager, networkStats, networkManagement,
422 NtpTrustedTime.getInstance(context), getSystemDir(), false);
425 private static File getSystemDir() {
426 return new File(Environment.getDataDirectory(), "system");
429 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
430 INetworkStatsService networkStats, INetworkManagementService networkManagement,
431 TrustedTime time, File systemDir, boolean suppressDefaultPolicy) {
432 mContext = checkNotNull(context, "missing context");
433 mActivityManager = checkNotNull(activityManager, "missing activityManager");
434 mNetworkStats = checkNotNull(networkStats, "missing networkStats");
435 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
436 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
437 Context.DEVICE_IDLE_CONTROLLER));
438 mTime = checkNotNull(time, "missing TrustedTime");
439 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
440 mIPm = AppGlobals.getPackageManager();
442 HandlerThread thread = new HandlerThread(TAG);
444 mHandler = new Handler(thread.getLooper(), mHandlerCallback);
446 mSuppressDefaultPolicy = suppressDefaultPolicy;
448 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
450 mAppOps = context.getSystemService(AppOpsManager.class);
452 mPackageMonitor = new MyPackageMonitor();
454 // Expose private service for system components to use.
455 LocalServices.addService(NetworkPolicyManagerInternal.class,
456 new NetworkPolicyManagerInternalImpl());
459 public void bindConnectivityManager(IConnectivityManager connManager) {
460 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
463 public void bindNotificationManager(INotificationManager notifManager) {
464 mNotifManager = checkNotNull(notifManager, "missing INotificationManager");
467 void updatePowerSaveWhitelistUL() {
469 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
470 mPowerSaveWhitelistExceptIdleAppIds.clear();
471 if (whitelist != null) {
472 for (int uid : whitelist) {
473 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
476 whitelist = mDeviceIdleController.getAppIdWhitelist();
477 mPowerSaveWhitelistAppIds.clear();
478 if (whitelist != null) {
479 for (int uid : whitelist) {
480 mPowerSaveWhitelistAppIds.put(uid, true);
483 } catch (RemoteException e) {
488 * Whitelists pre-defined apps for restrict background, but only if the user didn't already
489 * revoke the whitelist.
491 * @return whether any uid has been added to {@link #mRestrictBackgroundWhitelistUids}.
493 boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
494 final List<UserInfo> users = mUserManager.getUsers();
495 final int numberUsers = users.size();
497 boolean changed = false;
498 for (int i = 0; i < numberUsers; i++) {
499 final UserInfo user = users.get(i);
500 changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
505 private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
506 final SystemConfig sysConfig = SystemConfig.getInstance();
507 final PackageManager pm = mContext.getPackageManager();
508 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
509 boolean changed = false;
510 for (int i = 0; i < allowDataUsage.size(); i++) {
511 final String pkg = allowDataUsage.valueAt(i);
513 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
514 + " and user " + userId);
515 final ApplicationInfo app;
517 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
518 } catch (PackageManager.NameNotFoundException e) {
519 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
520 // Ignore it - some apps on allow-in-data-usage-save are optional.
523 if (!app.isPrivilegedApp()) {
524 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
525 + "skipping non-privileged app " + pkg);
528 final int uid = UserHandle.getUid(userId, app.uid);
529 mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
531 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
532 + "background whitelist. Revoked status: "
533 + mRestrictBackgroundWhitelistRevokedUids.get(uid));
534 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
536 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
537 + userId + ") to restrict background whitelist");
538 mRestrictBackgroundWhitelistUids.append(uid, true);
545 void updatePowerSaveTempWhitelistUL() {
547 // Clear the states of the current whitelist
548 final int N = mPowerSaveTempWhitelistAppIds.size();
549 for (int i = 0; i < N; i++) {
550 mPowerSaveTempWhitelistAppIds.setValueAt(i, false);
552 // Update the states with the new whitelist
553 final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist();
554 if (whitelist != null) {
555 for (int uid : whitelist) {
556 mPowerSaveTempWhitelistAppIds.put(uid, true);
559 } catch (RemoteException e) {
564 * Remove unnecessary entries in the temp whitelist
566 void purgePowerSaveTempWhitelistUL() {
567 final int N = mPowerSaveTempWhitelistAppIds.size();
568 for (int i = N - 1; i >= 0; i--) {
569 if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) {
570 mPowerSaveTempWhitelistAppIds.removeAt(i);
575 public void systemReady() {
576 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
578 if (!isBandwidthControlEnabled()) {
579 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
583 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
585 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
587 synchronized (mUidRulesFirstLock) {
588 synchronized (mNetworkPoliciesSecondLock) {
589 updatePowerSaveWhitelistUL();
590 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
591 mPowerManagerInternal.registerLowPowerModeObserver(
592 new PowerManagerInternal.LowPowerModeListener() {
594 public void onLowPowerModeChanged(boolean enabled) {
595 if (LOGD) Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
596 synchronized (mUidRulesFirstLock) {
597 if (mRestrictPower != enabled) {
598 mRestrictPower = enabled;
599 updateRulesForRestrictPowerUL();
604 mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
608 // read policy from disk
611 if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
615 setRestrictBackgroundUL(mRestrictBackground);
616 updateRulesForGlobalChangeAL(false);
617 updateNotificationsNL();
622 mActivityManager.registerUidObserver(mUidObserver,
623 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE);
624 mNetworkManager.registerObserver(mAlertObserver);
625 } catch (RemoteException e) {
626 // ignored; both services live in system_server
629 // listen for changes to power save whitelist
630 final IntentFilter whitelistFilter = new IntentFilter(
631 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
632 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
634 DeviceIdleController.LocalService deviceIdleService
635 = LocalServices.getService(DeviceIdleController.LocalService.class);
636 deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
638 // watch for network interfaces to be claimed
639 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
640 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
642 // listen for package changes to update policy
643 final IntentFilter packageFilter = new IntentFilter();
644 packageFilter.addAction(ACTION_PACKAGE_ADDED);
645 packageFilter.addDataScheme("package");
646 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
648 // listen for UID changes to update policy
649 mContext.registerReceiver(
650 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
652 // listen for user changes to update policy
653 final IntentFilter userFilter = new IntentFilter();
654 userFilter.addAction(ACTION_USER_ADDED);
655 userFilter.addAction(ACTION_USER_REMOVED);
656 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
658 // listen for stats update events
659 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
660 mContext.registerReceiver(
661 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
663 // listen for restrict background changes from notifications
664 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
665 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
667 // listen for snooze warning from notifications
668 final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING);
669 mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
670 MANAGE_NETWORK_POLICY, mHandler);
672 // listen for configured wifi networks to be removed
673 final IntentFilter wifiConfigFilter =
674 new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
675 mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
677 // listen for wifi state changes to catch metered hint
678 final IntentFilter wifiStateFilter = new IntentFilter(
679 WifiManager.NETWORK_STATE_CHANGED_ACTION);
680 mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
682 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
684 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
688 final private IUidObserver mUidObserver = new IUidObserver.Stub() {
689 @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
690 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
692 synchronized (mUidRulesFirstLock) {
693 updateUidStateUL(uid, procState);
696 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
700 @Override public void onUidGone(int uid) throws RemoteException {
701 synchronized (mUidRulesFirstLock) {
702 removeUidStateUL(uid);
706 @Override public void onUidActive(int uid) throws RemoteException {
709 @Override public void onUidIdle(int uid) throws RemoteException {
713 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
715 public void onReceive(Context context, Intent intent) {
716 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
717 synchronized (mUidRulesFirstLock) {
718 updatePowerSaveWhitelistUL();
719 updateRulesForRestrictPowerUL();
720 updateRulesForAppIdleUL();
725 final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
728 synchronized (mUidRulesFirstLock) {
729 updatePowerSaveTempWhitelistUL();
730 updateRulesForTempWhitelistChangeUL();
731 purgePowerSaveTempWhitelistUL();
736 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
738 public void onReceive(Context context, Intent intent) {
739 // on background handler thread, and PACKAGE_ADDED is protected
741 final String action = intent.getAction();
742 final int uid = intent.getIntExtra(EXTRA_UID, -1);
743 if (uid == -1) return;
745 if (ACTION_PACKAGE_ADDED.equals(action)) {
746 // update rules for UID, since it might be subject to
747 // global background data policy
748 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
749 synchronized (mUidRulesFirstLock) {
750 updateRestrictionRulesForUidUL(uid);
756 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
758 public void onReceive(Context context, Intent intent) {
759 // on background handler thread, and UID_REMOVED is protected
761 final int uid = intent.getIntExtra(EXTRA_UID, -1);
762 if (uid == -1) return;
764 // remove any policy and update rules to clean up
765 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
766 synchronized (mUidRulesFirstLock) {
767 mUidPolicy.delete(uid);
768 updateRestrictionRulesForUidUL(uid);
769 synchronized (mNetworkPoliciesSecondLock) {
776 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
778 public void onReceive(Context context, Intent intent) {
779 // on background handler thread, and USER_ADDED and USER_REMOVED
780 // broadcasts are protected
782 final String action = intent.getAction();
783 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
784 if (userId == -1) return;
787 case ACTION_USER_REMOVED:
788 case ACTION_USER_ADDED:
789 synchronized (mUidRulesFirstLock) {
790 // Remove any persistable state for the given user; both cleaning up after a
791 // USER_REMOVED, and one last sanity check during USER_ADDED
792 removeUserStateUL(userId, true);
793 if (action == ACTION_USER_ADDED) {
794 // Add apps that are whitelisted by default.
795 addDefaultRestrictBackgroundWhitelistUidsUL(userId);
797 // Update global restrict for that user
798 synchronized (mNetworkPoliciesSecondLock) {
799 updateRulesForGlobalChangeAL(true);
808 * Receiver that watches for {@link INetworkStatsService} updates, which we
809 * use to check against {@link NetworkPolicy#warningBytes}.
811 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
813 public void onReceive(Context context, Intent intent) {
814 // on background handler thread, and verified
815 // READ_NETWORK_USAGE_HISTORY permission above.
817 maybeRefreshTrustedTime();
818 synchronized (mNetworkPoliciesSecondLock) {
819 updateNetworkEnabledNL();
820 updateNotificationsNL();
826 * Receiver that watches for {@link Notification} control of
827 * {@link #mRestrictBackground}.
829 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
831 public void onReceive(Context context, Intent intent) {
832 // on background handler thread, and verified MANAGE_NETWORK_POLICY
835 setRestrictBackground(false);
840 * Receiver that watches for {@link Notification} control of
841 * {@link NetworkPolicy#lastWarningSnooze}.
843 final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
845 public void onReceive(Context context, Intent intent) {
846 // on background handler thread, and verified MANAGE_NETWORK_POLICY
849 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
850 performSnooze(template, TYPE_WARNING);
855 * Receiver that watches for {@link WifiConfiguration} to be changed.
857 final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
859 public void onReceive(Context context, Intent intent) {
860 // on background handler thread, and verified CONNECTIVITY_INTERNAL
863 final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED);
864 if (reason == CHANGE_REASON_REMOVED) {
865 final WifiConfiguration config = intent.getParcelableExtra(
866 EXTRA_WIFI_CONFIGURATION);
867 if (config.SSID != null) {
868 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID);
869 synchronized (mUidRulesFirstLock) {
870 synchronized (mNetworkPoliciesSecondLock) {
871 if (mNetworkPolicy.containsKey(template)) {
872 mNetworkPolicy.remove(template);
883 * Receiver that watches {@link WifiInfo} state changes to infer metered
884 * state. Ignores hints when policy is user-defined.
886 final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
888 public void onReceive(Context context, Intent intent) {
889 // on background handler thread, and verified CONNECTIVITY_INTERNAL
892 // ignore when not connected
893 final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
894 if (!netInfo.isConnected()) return;
896 final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO);
897 final boolean meteredHint = info.getMeteredHint();
899 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID());
900 synchronized (mNetworkPoliciesSecondLock) {
901 NetworkPolicy policy = mNetworkPolicy.get(template);
902 if (policy == null && meteredHint) {
903 // policy doesn't exist, and AP is hinting that it's
904 // metered: create an inferred policy.
905 policy = newWifiPolicy(template, meteredHint);
906 addNetworkPolicyNL(policy);
908 } else if (policy != null && policy.inferred) {
909 // policy exists, and was inferred: update its current
911 policy.metered = meteredHint;
913 // since this is inferred for each wifi session, just update
914 // rules without persisting.
915 updateNetworkRulesNL();
921 static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) {
922 return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
923 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
928 * Observer that watches for {@link INetworkManagementService} alerts.
930 final private INetworkManagementEventObserver mAlertObserver
931 = new BaseNetworkObserver() {
933 public void limitReached(String limitName, String iface) {
934 // only someone like NMS should be calling us
935 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
937 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
938 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
944 * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
945 * to show visible notifications as needed.
947 void updateNotificationsNL() {
948 if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
950 // keep track of previously active notifications
951 final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
952 mActiveNotifs.clear();
954 // TODO: when switching to kernel notifications, compute next future
955 // cycle boundary to recompute notifications.
957 // examine stats for each active policy
958 final long currentTime = currentTimeMillis();
959 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
960 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
961 // ignore policies that aren't relevant to user
962 if (!isTemplateRelevant(policy.template)) continue;
963 if (!policy.hasCycle()) continue;
965 final long start = computeLastCycleBoundary(currentTime, policy);
966 final long end = currentTime;
967 final long totalBytes = getTotalBytes(policy.template, start, end);
969 if (policy.isOverLimit(totalBytes)) {
970 if (policy.lastLimitSnooze >= start) {
971 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
973 enqueueNotification(policy, TYPE_LIMIT, totalBytes);
974 notifyOverLimitNL(policy.template);
978 notifyUnderLimitNL(policy.template);
980 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
981 enqueueNotification(policy, TYPE_WARNING, totalBytes);
986 // cancel stale notifications that we didn't renew above
987 for (int i = beforeNotifs.size()-1; i >= 0; i--) {
988 final String tag = beforeNotifs.valueAt(i);
989 if (!mActiveNotifs.contains(tag)) {
990 cancelNotification(tag);
996 * Test if given {@link NetworkTemplate} is relevant to user based on
997 * current device state, such as when
998 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
999 * data connection status.
1001 private boolean isTemplateRelevant(NetworkTemplate template) {
1002 if (template.isMatchRuleMobile()) {
1003 final TelephonyManager tele = TelephonyManager.from(mContext);
1004 final SubscriptionManager sub = SubscriptionManager.from(mContext);
1006 // Mobile template is relevant when any active subscriber matches
1007 final int[] subIds = sub.getActiveSubscriptionIdList();
1008 for (int subId : subIds) {
1009 final String subscriberId = tele.getSubscriberId(subId);
1010 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1011 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1012 if (template.matches(probeIdent)) {
1023 * Notify that given {@link NetworkTemplate} is over
1024 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1026 private void notifyOverLimitNL(NetworkTemplate template) {
1027 if (!mOverLimitNotified.contains(template)) {
1028 mContext.startActivity(buildNetworkOverLimitIntent(template));
1029 mOverLimitNotified.add(template);
1033 private void notifyUnderLimitNL(NetworkTemplate template) {
1034 mOverLimitNotified.remove(template);
1038 * Build unique tag that identifies an active {@link NetworkPolicy}
1039 * notification of a specific type, like {@link #TYPE_LIMIT}.
1041 private String buildNotificationTag(NetworkPolicy policy, int type) {
1042 return TAG + ":" + policy.template.hashCode() + ":" + type;
1046 * Show notification for combined {@link NetworkPolicy} and specific type,
1047 * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1049 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
1050 final String tag = buildNotificationTag(policy, type);
1051 final Notification.Builder builder = new Notification.Builder(mContext);
1052 builder.setOnlyAlertOnce(true);
1053 builder.setWhen(0L);
1054 builder.setColor(mContext.getColor(
1055 com.android.internal.R.color.system_notification_accent_color));
1057 final Resources res = mContext.getResources();
1059 case TYPE_WARNING: {
1060 final CharSequence title = res.getText(R.string.data_usage_warning_title);
1061 final CharSequence body = res.getString(R.string.data_usage_warning_body);
1063 builder.setSmallIcon(R.drawable.stat_notify_error);
1064 builder.setTicker(title);
1065 builder.setContentTitle(title);
1066 builder.setContentText(body);
1067 builder.setDefaults(Notification.DEFAULT_ALL);
1068 builder.setPriority(Notification.PRIORITY_HIGH);
1070 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1071 builder.setDeleteIntent(PendingIntent.getBroadcast(
1072 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1074 final Intent viewIntent = buildViewDataUsageIntent(policy.template);
1075 builder.setContentIntent(PendingIntent.getActivity(
1076 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1081 final CharSequence body = res.getText(R.string.data_usage_limit_body);
1083 final CharSequence title;
1084 int icon = R.drawable.stat_notify_disabled_data;
1085 switch (policy.template.getMatchRule()) {
1086 case MATCH_MOBILE_3G_LOWER:
1087 title = res.getText(R.string.data_usage_3g_limit_title);
1089 case MATCH_MOBILE_4G:
1090 title = res.getText(R.string.data_usage_4g_limit_title);
1092 case MATCH_MOBILE_ALL:
1093 title = res.getText(R.string.data_usage_mobile_limit_title);
1096 title = res.getText(R.string.data_usage_wifi_limit_title);
1097 icon = R.drawable.stat_notify_error;
1104 builder.setOngoing(true);
1105 builder.setSmallIcon(icon);
1106 builder.setTicker(title);
1107 builder.setContentTitle(title);
1108 builder.setContentText(body);
1110 final Intent intent = buildNetworkOverLimitIntent(policy.template);
1111 builder.setContentIntent(PendingIntent.getActivity(
1112 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1115 case TYPE_LIMIT_SNOOZED: {
1116 final long overBytes = totalBytes - policy.limitBytes;
1117 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body,
1118 Formatter.formatFileSize(mContext, overBytes));
1120 final CharSequence title;
1121 switch (policy.template.getMatchRule()) {
1122 case MATCH_MOBILE_3G_LOWER:
1123 title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
1125 case MATCH_MOBILE_4G:
1126 title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
1128 case MATCH_MOBILE_ALL:
1129 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1132 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1139 builder.setOngoing(true);
1140 builder.setSmallIcon(R.drawable.stat_notify_error);
1141 builder.setTicker(title);
1142 builder.setContentTitle(title);
1143 builder.setContentText(body);
1145 final Intent intent = buildViewDataUsageIntent(policy.template);
1146 builder.setContentIntent(PendingIntent.getActivity(
1147 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1152 // TODO: move to NotificationManager once we can mock it
1154 final String packageName = mContext.getPackageName();
1155 final int[] idReceived = new int[1];
1156 mNotifManager.enqueueNotificationWithTag(
1157 packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
1158 UserHandle.USER_ALL);
1159 mActiveNotifs.add(tag);
1160 } catch (RemoteException e) {
1161 // ignored; service lives in system_server
1165 private void cancelNotification(String tag) {
1166 // TODO: move to NotificationManager once we can mock it
1168 final String packageName = mContext.getPackageName();
1169 mNotifManager.cancelNotificationWithTag(
1170 packageName, tag, 0x0, UserHandle.USER_ALL);
1171 } catch (RemoteException e) {
1172 // ignored; service lives in system_server
1177 * Receiver that watches for {@link IConnectivityManager} to claim network
1178 * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
1180 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
1182 public void onReceive(Context context, Intent intent) {
1183 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1184 // permission above.
1186 maybeRefreshTrustedTime();
1187 synchronized (mNetworkPoliciesSecondLock) {
1188 ensureActiveMobilePolicyNL();
1189 normalizePoliciesNL();
1190 updateNetworkEnabledNL();
1191 updateNetworkRulesNL();
1192 updateNotificationsNL();
1198 * Proactively control network data connections when they exceed
1199 * {@link NetworkPolicy#limitBytes}.
1201 void updateNetworkEnabledNL() {
1202 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
1204 // TODO: reset any policy-disabled networks when any policy is removed
1205 // completely, which is currently rare case.
1207 final long currentTime = currentTimeMillis();
1208 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1209 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1210 // shortcut when policy has no limit
1211 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
1212 setNetworkTemplateEnabled(policy.template, true);
1216 final long start = computeLastCycleBoundary(currentTime, policy);
1217 final long end = currentTime;
1218 final long totalBytes = getTotalBytes(policy.template, start, end);
1220 // disable data connection when over limit and not snoozed
1221 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
1222 && policy.lastLimitSnooze < start;
1223 final boolean networkEnabled = !overLimitWithoutSnooze;
1225 setNetworkTemplateEnabled(policy.template, networkEnabled);
1230 * Proactively disable networks that match the given
1231 * {@link NetworkTemplate}.
1233 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
1234 // TODO: reach into ConnectivityManager to proactively disable bringing
1235 // up this network, since we know that traffic will be blocked.
1237 if (template.getMatchRule() == MATCH_MOBILE_ALL) {
1238 // If mobile data usage hits the limit or if the user resumes the data, we need to
1239 // notify telephony.
1240 final SubscriptionManager sm = SubscriptionManager.from(mContext);
1241 final TelephonyManager tm = TelephonyManager.from(mContext);
1243 final int[] subIds = sm.getActiveSubscriptionIdList();
1244 for (int subId : subIds) {
1245 final String subscriberId = tm.getSubscriberId(subId);
1246 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1247 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1248 // Template is matched when subscriber id matches.
1249 if (template.matches(probeIdent)) {
1250 tm.setPolicyDataEnabled(enabled, subId);
1257 * Examine all connected {@link NetworkState}, looking for
1258 * {@link NetworkPolicy} that need to be enforced. When matches found, set
1259 * remaining quota based on usage cycle and historical stats.
1261 void updateNetworkRulesNL() {
1262 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
1264 final NetworkState[] states;
1266 states = mConnManager.getAllNetworkState();
1267 } catch (RemoteException e) {
1268 // ignored; service lives in system_server
1272 // First, generate identities of all connected networks so we can
1273 // quickly compare them against all defined policies below.
1274 final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length);
1275 final ArraySet<String> connIfaces = new ArraySet<String>(states.length);
1276 for (NetworkState state : states) {
1277 if (state.networkInfo != null && state.networkInfo.isConnected()) {
1278 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
1280 final String baseIface = state.linkProperties.getInterfaceName();
1281 if (baseIface != null) {
1282 connIdents.add(Pair.create(baseIface, ident));
1285 // Stacked interfaces are considered to have same identity as
1286 // their parent network.
1287 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1288 for (LinkProperties stackedLink : stackedLinks) {
1289 final String stackedIface = stackedLink.getInterfaceName();
1290 if (stackedIface != null) {
1291 connIdents.add(Pair.create(stackedIface, ident));
1297 // Apply policies against all connected interfaces found above
1298 mNetworkRules.clear();
1299 final ArrayList<String> ifaceList = Lists.newArrayList();
1300 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1301 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1304 for (int j = connIdents.size() - 1; j >= 0; j--) {
1305 final Pair<String, NetworkIdentity> ident = connIdents.get(j);
1306 if (policy.template.matches(ident.second)) {
1307 ifaceList.add(ident.first);
1311 if (ifaceList.size() > 0) {
1312 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]);
1313 mNetworkRules.put(policy, ifaces);
1317 long lowestRule = Long.MAX_VALUE;
1318 final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length);
1320 // apply each policy that we found ifaces for; compute remaining data
1321 // based on current cycle and historical stats, and push to kernel.
1322 final long currentTime = currentTimeMillis();
1323 for (int i = mNetworkRules.size()-1; i >= 0; i--) {
1324 final NetworkPolicy policy = mNetworkRules.keyAt(i);
1325 final String[] ifaces = mNetworkRules.valueAt(i);
1328 final long totalBytes;
1329 if (policy.hasCycle()) {
1330 start = computeLastCycleBoundary(currentTime, policy);
1331 totalBytes = getTotalBytes(policy.template, start, currentTime);
1333 start = Long.MAX_VALUE;
1338 Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces));
1341 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
1342 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
1343 if (hasLimit || policy.metered) {
1344 final long quotaBytes;
1346 // metered network, but no policy limit; we still need to
1347 // restrict apps, so push really high quota.
1348 quotaBytes = Long.MAX_VALUE;
1349 } else if (policy.lastLimitSnooze >= start) {
1350 // snoozing past quota, but we still need to restrict apps,
1351 // so push really high quota.
1352 quotaBytes = Long.MAX_VALUE;
1354 // remaining "quota" bytes are based on total usage in
1355 // current cycle. kernel doesn't like 0-byte rules, so we
1356 // set 1-byte quota and disable the radio later.
1357 quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
1360 if (ifaces.length > 1) {
1361 // TODO: switch to shared quota once NMS supports
1362 Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
1365 for (String iface : ifaces) {
1366 // long quotaBytes split up into two ints to fit in message
1367 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
1368 (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface)
1370 newMeteredIfaces.add(iface);
1374 // keep track of lowest warning or limit of active policies
1375 if (hasWarning && policy.warningBytes < lowestRule) {
1376 lowestRule = policy.warningBytes;
1378 if (hasLimit && policy.limitBytes < lowestRule) {
1379 lowestRule = policy.limitBytes;
1383 for (int i = connIfaces.size()-1; i >= 0; i--) {
1384 String iface = connIfaces.valueAt(i);
1385 // long quotaBytes split up into two ints to fit in message
1386 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
1387 (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface)
1389 newMeteredIfaces.add(iface);
1392 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
1394 // remove quota on any trailing interfaces
1395 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
1396 final String iface = mMeteredIfaces.valueAt(i);
1397 if (!newMeteredIfaces.contains(iface)) {
1398 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface)
1402 mMeteredIfaces = newMeteredIfaces;
1404 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
1405 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
1409 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1410 * have at least a default mobile policy defined.
1412 private void ensureActiveMobilePolicyNL() {
1413 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyNL()");
1414 if (mSuppressDefaultPolicy) return;
1416 final TelephonyManager tele = TelephonyManager.from(mContext);
1417 final SubscriptionManager sub = SubscriptionManager.from(mContext);
1419 final int[] subIds = sub.getActiveSubscriptionIdList();
1420 for (int subId : subIds) {
1421 final String subscriberId = tele.getSubscriberId(subId);
1422 ensureActiveMobilePolicyNL(subscriberId);
1426 private void ensureActiveMobilePolicyNL(String subscriberId) {
1427 // Poke around to see if we already have a policy
1428 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1429 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1430 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1431 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1432 if (template.matches(probeIdent)) {
1434 Slog.d(TAG, "Found template " + template + " which matches subscriber "
1435 + NetworkIdentity.scrubSubscriberId(subscriberId));
1441 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
1442 + "; generating default policy");
1444 // Build default mobile policy, and assume usage cycle starts today
1445 final long warningBytes = mContext.getResources().getInteger(
1446 com.android.internal.R.integer.config_networkPolicyDefaultWarning) * MB_IN_BYTES;
1448 final Time time = new Time();
1451 final int cycleDay = time.monthDay;
1452 final String cycleTimezone = time.timezone;
1454 final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
1455 final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
1456 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
1457 addNetworkPolicyNL(policy);
1460 private void readPolicyAL() {
1461 if (LOGV) Slog.v(TAG, "readPolicyAL()");
1463 // clear any existing policy and read from disk
1464 mNetworkPolicy.clear();
1467 FileInputStream fis = null;
1469 fis = mPolicyFile.openRead();
1470 final XmlPullParser in = Xml.newPullParser();
1471 in.setInput(fis, StandardCharsets.UTF_8.name());
1474 int version = VERSION_INIT;
1475 boolean insideWhitelist = false;
1476 while ((type = in.next()) != END_DOCUMENT) {
1477 final String tag = in.getName();
1478 if (type == START_TAG) {
1479 if (TAG_POLICY_LIST.equals(tag)) {
1480 final boolean oldValue = mRestrictBackground;
1481 version = readIntAttribute(in, ATTR_VERSION);
1482 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
1483 mRestrictBackground = readBooleanAttribute(
1484 in, ATTR_RESTRICT_BACKGROUND);
1486 mRestrictBackground = false;
1488 if (mRestrictBackground != oldValue) {
1489 // Some early services may have read the default value,
1490 // so notify them that it's changed
1491 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
1492 mRestrictBackground ? 1 : 0, 0).sendToTarget();
1495 } else if (TAG_NETWORK_POLICY.equals(tag)) {
1496 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
1497 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
1498 final String networkId;
1499 if (version >= VERSION_ADDED_NETWORK_ID) {
1500 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
1504 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
1505 final String cycleTimezone;
1506 if (version >= VERSION_ADDED_TIMEZONE) {
1507 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
1509 cycleTimezone = Time.TIMEZONE_UTC;
1511 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
1512 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
1513 final long lastLimitSnooze;
1514 if (version >= VERSION_SPLIT_SNOOZE) {
1515 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
1516 } else if (version >= VERSION_ADDED_SNOOZE) {
1517 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
1519 lastLimitSnooze = SNOOZE_NEVER;
1521 final boolean metered;
1522 if (version >= VERSION_ADDED_METERED) {
1523 metered = readBooleanAttribute(in, ATTR_METERED);
1525 switch (networkTemplate) {
1526 case MATCH_MOBILE_3G_LOWER:
1527 case MATCH_MOBILE_4G:
1528 case MATCH_MOBILE_ALL:
1535 final long lastWarningSnooze;
1536 if (version >= VERSION_SPLIT_SNOOZE) {
1537 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
1539 lastWarningSnooze = SNOOZE_NEVER;
1541 final boolean inferred;
1542 if (version >= VERSION_ADDED_INFERRED) {
1543 inferred = readBooleanAttribute(in, ATTR_INFERRED);
1548 final NetworkTemplate template = new NetworkTemplate(networkTemplate,
1549 subscriberId, networkId);
1550 if (template.isPersistable()) {
1551 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
1552 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
1553 lastLimitSnooze, metered, inferred));
1556 } else if (TAG_UID_POLICY.equals(tag)) {
1557 final int uid = readIntAttribute(in, ATTR_UID);
1558 final int policy = readIntAttribute(in, ATTR_POLICY);
1560 if (UserHandle.isApp(uid)) {
1561 setUidPolicyUncheckedUL(uid, policy, false);
1563 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
1565 } else if (TAG_APP_POLICY.equals(tag)) {
1566 final int appId = readIntAttribute(in, ATTR_APP_ID);
1567 final int policy = readIntAttribute(in, ATTR_POLICY);
1569 // TODO: set for other users during upgrade
1570 // app policy is deprecated so this is only used in pre system user split.
1571 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
1572 if (UserHandle.isApp(uid)) {
1573 setUidPolicyUncheckedUL(uid, policy, false);
1575 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
1577 } else if (TAG_WHITELIST.equals(tag)) {
1578 insideWhitelist = true;
1579 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
1580 final int uid = readIntAttribute(in, ATTR_UID);
1581 mRestrictBackgroundWhitelistUids.put(uid, true);
1582 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
1583 final int uid = readIntAttribute(in, ATTR_UID);
1584 mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
1586 } else if (type == END_TAG) {
1587 if (TAG_WHITELIST.equals(tag)) {
1588 insideWhitelist = false;
1594 } catch (FileNotFoundException e) {
1595 // missing policy is okay, probably first boot
1596 upgradeLegacyBackgroundDataUL();
1597 } catch (IOException e) {
1598 Log.wtf(TAG, "problem reading network policy", e);
1599 } catch (XmlPullParserException e) {
1600 Log.wtf(TAG, "problem reading network policy", e);
1602 IoUtils.closeQuietly(fis);
1607 * Upgrade legacy background data flags, notifying listeners of one last
1608 * change to always-true.
1610 private void upgradeLegacyBackgroundDataUL() {
1611 mRestrictBackground = Settings.Secure.getInt(
1612 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
1614 // kick off one last broadcast if restricted
1615 if (mRestrictBackground) {
1616 final Intent broadcast = new Intent(
1617 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
1618 mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL);
1622 void writePolicyAL() {
1623 if (LOGV) Slog.v(TAG, "writePolicyAL()");
1625 FileOutputStream fos = null;
1627 fos = mPolicyFile.startWrite();
1629 XmlSerializer out = new FastXmlSerializer();
1630 out.setOutput(fos, StandardCharsets.UTF_8.name());
1631 out.startDocument(null, true);
1633 out.startTag(null, TAG_POLICY_LIST);
1634 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
1635 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
1637 // write all known network policies
1638 for (int i = 0; i < mNetworkPolicy.size(); i++) {
1639 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1640 final NetworkTemplate template = policy.template;
1641 if (!template.isPersistable()) continue;
1643 out.startTag(null, TAG_NETWORK_POLICY);
1644 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
1645 final String subscriberId = template.getSubscriberId();
1646 if (subscriberId != null) {
1647 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
1649 final String networkId = template.getNetworkId();
1650 if (networkId != null) {
1651 out.attribute(null, ATTR_NETWORK_ID, networkId);
1653 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
1654 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
1655 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
1656 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
1657 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
1658 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
1659 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
1660 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
1661 out.endTag(null, TAG_NETWORK_POLICY);
1664 // write all known uid policies
1665 for (int i = 0; i < mUidPolicy.size(); i++) {
1666 final int uid = mUidPolicy.keyAt(i);
1667 final int policy = mUidPolicy.valueAt(i);
1669 // skip writing empty policies
1670 if (policy == POLICY_NONE) continue;
1672 out.startTag(null, TAG_UID_POLICY);
1673 writeIntAttribute(out, ATTR_UID, uid);
1674 writeIntAttribute(out, ATTR_POLICY, policy);
1675 out.endTag(null, TAG_UID_POLICY);
1678 out.endTag(null, TAG_POLICY_LIST);
1680 // write all whitelists
1681 out.startTag(null, TAG_WHITELIST);
1683 // restrict background whitelist
1684 int size = mRestrictBackgroundWhitelistUids.size();
1685 for (int i = 0; i < size; i++) {
1686 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i);
1687 out.startTag(null, TAG_RESTRICT_BACKGROUND);
1688 writeIntAttribute(out, ATTR_UID, uid);
1689 out.endTag(null, TAG_RESTRICT_BACKGROUND);
1692 // revoked restrict background whitelist
1693 size = mRestrictBackgroundWhitelistRevokedUids.size();
1694 for (int i = 0; i < size; i++) {
1695 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
1696 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
1697 writeIntAttribute(out, ATTR_UID, uid);
1698 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
1701 out.endTag(null, TAG_WHITELIST);
1705 mPolicyFile.finishWrite(fos);
1706 } catch (IOException e) {
1708 mPolicyFile.failWrite(fos);
1714 public void setUidPolicy(int uid, int policy) {
1715 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1717 if (!UserHandle.isApp(uid)) {
1718 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
1720 synchronized (mUidRulesFirstLock) {
1721 final long token = Binder.clearCallingIdentity();
1723 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
1724 if (oldPolicy != policy) {
1725 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
1728 Binder.restoreCallingIdentity(token);
1734 public void addUidPolicy(int uid, int policy) {
1735 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1737 if (!UserHandle.isApp(uid)) {
1738 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
1741 synchronized (mUidRulesFirstLock) {
1742 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
1743 policy |= oldPolicy;
1744 if (oldPolicy != policy) {
1745 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
1751 public void removeUidPolicy(int uid, int policy) {
1752 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1754 if (!UserHandle.isApp(uid)) {
1755 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
1758 synchronized (mUidRulesFirstLock) {
1759 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
1760 policy = oldPolicy & ~policy;
1761 if (oldPolicy != policy) {
1762 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
1767 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
1768 setUidPolicyUncheckedUL(uid, policy, persist);
1770 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
1771 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED, uid,
1772 isBlacklisted ? 1 : 0).sendToTarget();
1774 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
1775 // Checks if app was added or removed to the blacklist.
1776 if ((oldPolicy == POLICY_NONE && isBlacklisted)
1777 || (wasBlacklisted && policy == POLICY_NONE)) {
1778 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null)
1783 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
1784 mUidPolicy.put(uid, policy);
1786 // uid policy changed, recompute rules and persist policy.
1787 updateRulesForDataUsageRestrictionsUL(uid);
1789 synchronized (mNetworkPoliciesSecondLock) {
1796 public int getUidPolicy(int uid) {
1797 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1799 synchronized (mUidRulesFirstLock) {
1800 return mUidPolicy.get(uid, POLICY_NONE);
1805 public int[] getUidsWithPolicy(int policy) {
1806 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1808 int[] uids = new int[0];
1809 synchronized (mUidRulesFirstLock) {
1810 for (int i = 0; i < mUidPolicy.size(); i++) {
1811 final int uid = mUidPolicy.keyAt(i);
1812 final int uidPolicy = mUidPolicy.valueAt(i);
1813 if (uidPolicy == policy) {
1814 uids = appendInt(uids, uid);
1822 * Removes any persistable state associated with given {@link UserHandle}, persisting
1823 * if any changes that are made.
1825 boolean removeUserStateUL(int userId, boolean writePolicy) {
1827 if (LOGV) Slog.v(TAG, "removeUserStateUL()");
1828 boolean changed = false;
1830 // Remove entries from restricted background UID whitelist
1831 int[] wlUids = new int[0];
1832 for (int i = 0; i < mRestrictBackgroundWhitelistUids.size(); i++) {
1833 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i);
1834 if (UserHandle.getUserId(uid) == userId) {
1835 wlUids = appendInt(wlUids, uid);
1839 if (wlUids.length > 0) {
1840 for (int uid : wlUids) {
1841 removeRestrictBackgroundWhitelistedUidUL(uid, false, false);
1846 // Remove entries from revoked default restricted background UID whitelist
1847 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
1848 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
1849 if (UserHandle.getUserId(uid) == userId) {
1850 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
1855 // Remove associated UID policies
1856 int[] uids = new int[0];
1857 for (int i = 0; i < mUidPolicy.size(); i++) {
1858 final int uid = mUidPolicy.keyAt(i);
1859 if (UserHandle.getUserId(uid) == userId) {
1860 uids = appendInt(uids, uid);
1864 if (uids.length > 0) {
1865 for (int uid : uids) {
1866 mUidPolicy.delete(uid);
1870 synchronized (mNetworkPoliciesSecondLock) {
1871 updateRulesForGlobalChangeAL(true);
1872 if (writePolicy && changed) {
1880 public void setConnectivityListener(INetworkPolicyListener listener) {
1881 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1882 if (mConnectivityListener != null) {
1883 throw new IllegalStateException("Connectivity listener already registered");
1885 mConnectivityListener = listener;
1889 public void registerListener(INetworkPolicyListener listener) {
1890 // TODO: create permission for observing network policy
1891 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1892 mListeners.register(listener);
1896 public void unregisterListener(INetworkPolicyListener listener) {
1897 // TODO: create permission for observing network policy
1898 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1899 mListeners.unregister(listener);
1903 public void setNetworkPolicies(NetworkPolicy[] policies) {
1904 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1906 final long token = Binder.clearCallingIdentity();
1908 maybeRefreshTrustedTime();
1909 synchronized (mUidRulesFirstLock) {
1910 synchronized (mNetworkPoliciesSecondLock) {
1911 normalizePoliciesNL(policies);
1912 updateNetworkEnabledNL();
1913 updateNetworkRulesNL();
1914 updateNotificationsNL();
1919 Binder.restoreCallingIdentity(token);
1923 void addNetworkPolicyNL(NetworkPolicy policy) {
1924 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
1925 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
1926 setNetworkPolicies(policies);
1930 public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
1931 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1933 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
1934 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
1936 } catch (SecurityException e) {
1937 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
1939 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
1940 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1941 return new NetworkPolicy[0];
1945 synchronized (mNetworkPoliciesSecondLock) {
1946 final int size = mNetworkPolicy.size();
1947 final NetworkPolicy[] policies = new NetworkPolicy[size];
1948 for (int i = 0; i < size; i++) {
1949 policies[i] = mNetworkPolicy.valueAt(i);
1955 private void normalizePoliciesNL() {
1956 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
1959 private void normalizePoliciesNL(NetworkPolicy[] policies) {
1960 final TelephonyManager tele = TelephonyManager.from(mContext);
1961 final String[] merged = tele.getMergedSubscriberIds();
1963 mNetworkPolicy.clear();
1964 for (NetworkPolicy policy : policies) {
1965 // When two normalized templates conflict, prefer the most
1966 // restrictive policy
1967 policy.template = NetworkTemplate.normalize(policy.template, merged);
1968 final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
1969 if (existing == null || existing.compareTo(policy) > 0) {
1970 if (existing != null) {
1971 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
1973 mNetworkPolicy.put(policy.template, policy);
1979 public void snoozeLimit(NetworkTemplate template) {
1980 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1982 final long token = Binder.clearCallingIdentity();
1984 performSnooze(template, TYPE_LIMIT);
1986 Binder.restoreCallingIdentity(token);
1990 void performSnooze(NetworkTemplate template, int type) {
1991 maybeRefreshTrustedTime();
1992 final long currentTime = currentTimeMillis();
1993 synchronized (mUidRulesFirstLock) {
1994 synchronized (mNetworkPoliciesSecondLock) {
1995 // find and snooze local policy that matches
1996 final NetworkPolicy policy = mNetworkPolicy.get(template);
1997 if (policy == null) {
1998 throw new IllegalArgumentException("unable to find policy for " + template);
2003 policy.lastWarningSnooze = currentTime;
2006 policy.lastLimitSnooze = currentTime;
2009 throw new IllegalArgumentException("unexpected type");
2012 normalizePoliciesNL();
2013 updateNetworkEnabledNL();
2014 updateNetworkRulesNL();
2015 updateNotificationsNL();
2022 public void onTetheringChanged(String iface, boolean tethering) {
2023 // No need to enforce permission because setRestrictBackground() will do it.
2024 if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")");
2025 synchronized (mUidRulesFirstLock) {
2026 if (mRestrictBackground && tethering) {
2027 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
2028 setRestrictBackground(false);
2034 public void setRestrictBackground(boolean restrictBackground) {
2035 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2036 final long token = Binder.clearCallingIdentity();
2038 maybeRefreshTrustedTime();
2039 synchronized (mUidRulesFirstLock) {
2040 if (restrictBackground == mRestrictBackground) {
2041 // Ideally, UI should never allow this scenario...
2042 Slog.w(TAG, "setRestrictBackground: already " + restrictBackground);
2045 setRestrictBackgroundUL(restrictBackground);
2049 Binder.restoreCallingIdentity(token);
2052 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
2056 private void setRestrictBackgroundUL(boolean restrictBackground) {
2057 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
2058 final boolean oldRestrictBackground = mRestrictBackground;
2059 mRestrictBackground = restrictBackground;
2060 // Must whitelist foreground apps before turning data saver mode on.
2061 // TODO: there is no need to iterate through all apps here, just those in the foreground,
2062 // so it could call AM to get the UIDs of such apps, and iterate through them instead.
2063 updateRulesForRestrictBackgroundUL();
2065 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
2066 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
2067 mRestrictBackground = oldRestrictBackground;
2068 // TODO: if it knew the foreground apps (see TODO above), it could call
2069 // updateRulesForRestrictBackgroundUL() again to restore state.
2072 } catch (RemoteException e) {
2073 // ignored; service lives in system_server
2075 synchronized (mNetworkPoliciesSecondLock) {
2076 updateNotificationsNL();
2082 public void addRestrictBackgroundWhitelistedUid(int uid) {
2083 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2084 final boolean oldStatus;
2085 final boolean needFirewallRules;
2087 synchronized (mUidRulesFirstLock) {
2088 oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
2090 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted");
2093 needFirewallRules = isUidValidForWhitelistRules(uid);
2094 Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist");
2095 mRestrictBackgroundWhitelistUids.append(uid, true);
2096 if (mDefaultRestrictBackgroundWhitelistUids.get(uid)
2097 && mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2098 if (LOGD) Slog.d(TAG, "Removing uid " + uid
2099 + " from revoked restrict background whitelist");
2100 mRestrictBackgroundWhitelistRevokedUids.delete(uid);
2102 if (needFirewallRules) {
2103 // Only update firewall rules if necessary...
2104 updateRulesForDataUsageRestrictionsUL(uid);
2106 // ...but always persists the whitelist request.
2107 synchronized (mNetworkPoliciesSecondLock) {
2110 changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0;
2112 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed,
2113 Boolean.TRUE).sendToTarget();
2117 public void removeRestrictBackgroundWhitelistedUid(int uid) {
2118 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2119 final boolean changed;
2120 synchronized (mUidRulesFirstLock) {
2121 changed = removeRestrictBackgroundWhitelistedUidUL(uid, false, true);
2123 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0,
2124 Boolean.FALSE).sendToTarget();
2128 * Removes a uid from the restricted background whitelist, returning whether its current
2129 * {@link ConnectivityManager.RestrictBackgroundStatus} changed.
2131 private boolean removeRestrictBackgroundWhitelistedUidUL(int uid, boolean uidDeleted,
2132 boolean updateNow) {
2133 final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
2134 if (!oldStatus && !uidDeleted) {
2135 if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before");
2138 final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid);
2140 Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist");
2141 mRestrictBackgroundWhitelistUids.delete(uid);
2143 if (mDefaultRestrictBackgroundWhitelistUids.get(uid)
2144 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2145 if (LOGD) Slog.d(TAG, "Adding uid " + uid
2146 + " to revoked restrict background whitelist");
2147 mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2149 if (needFirewallRules) {
2150 // Only update firewall rules if necessary...
2151 updateRulesForDataUsageRestrictionsUL(uid, uidDeleted);
2154 // ...but always persists the whitelist request.
2155 synchronized (mNetworkPoliciesSecondLock) {
2159 // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the
2160 // app was whitelisted before).
2161 return mRestrictBackground && needFirewallRules;
2165 public int[] getRestrictBackgroundWhitelistedUids() {
2166 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2167 synchronized (mUidRulesFirstLock) {
2168 final int size = mRestrictBackgroundWhitelistUids.size();
2169 final int[] whitelist = new int[size];
2170 for (int i = 0; i < size; i++) {
2171 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i);
2174 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): "
2175 + mRestrictBackgroundWhitelistUids);
2182 public int getRestrictBackgroundByCaller() {
2183 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2184 final int uid = Binder.getCallingUid();
2186 synchronized (mUidRulesFirstLock) {
2187 // Must clear identity because getUidPolicy() is restricted to system.
2188 final long token = Binder.clearCallingIdentity();
2191 policy = getUidPolicy(uid);
2193 Binder.restoreCallingIdentity(token);
2195 if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2196 // App is blacklisted.
2197 return RESTRICT_BACKGROUND_STATUS_ENABLED;
2199 if (!mRestrictBackground) {
2200 return RESTRICT_BACKGROUND_STATUS_DISABLED;
2202 return mRestrictBackgroundWhitelistUids.get(uid)
2203 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2204 : RESTRICT_BACKGROUND_STATUS_ENABLED;
2209 public boolean getRestrictBackground() {
2210 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2212 synchronized (mUidRulesFirstLock) {
2213 return mRestrictBackground;
2218 public void setDeviceIdleMode(boolean enabled) {
2219 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2220 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2222 synchronized (mUidRulesFirstLock) {
2223 if (mDeviceIdleMode == enabled) {
2226 mDeviceIdleMode = enabled;
2228 // Device idle change means we need to rebuild rules for all
2229 // known apps, so do a global refresh.
2230 updateRulesForRestrictPowerUL();
2234 EventLogTags.writeDeviceIdleOnPhase("net");
2236 EventLogTags.writeDeviceIdleOffPhase("net");
2239 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2243 private NetworkPolicy findPolicyForNetworkNL(NetworkIdentity ident) {
2244 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
2245 NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2246 if (policy.template.matches(ident)) {
2254 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
2255 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2257 // only returns usage summary, so we don't require caller to have
2258 // READ_NETWORK_USAGE_HISTORY.
2259 final long token = Binder.clearCallingIdentity();
2261 return getNetworkQuotaInfoUnchecked(state);
2263 Binder.restoreCallingIdentity(token);
2267 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
2268 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
2270 final NetworkPolicy policy;
2271 synchronized (mNetworkPoliciesSecondLock) {
2272 policy = findPolicyForNetworkNL(ident);
2275 if (policy == null || !policy.hasCycle()) {
2276 // missing policy means we can't derive useful quota info
2280 final long currentTime = currentTimeMillis();
2282 // find total bytes used under policy
2283 final long start = computeLastCycleBoundary(currentTime, policy);
2284 final long end = currentTime;
2285 final long totalBytes = getTotalBytes(policy.template, start, end);
2287 // report soft and hard limits under policy
2288 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
2289 : NetworkQuotaInfo.NO_LIMIT;
2290 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
2291 : NetworkQuotaInfo.NO_LIMIT;
2293 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
2297 public boolean isNetworkMetered(NetworkState state) {
2298 if (state.networkInfo == null) {
2302 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
2304 final NetworkPolicy policy;
2305 synchronized (mNetworkPoliciesSecondLock) {
2306 policy = findPolicyForNetworkNL(ident);
2309 if (policy != null) {
2310 return policy.metered;
2312 final int type = state.networkInfo.getType();
2313 if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) {
2321 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2322 mContext.enforceCallingOrSelfPermission(DUMP, TAG);
2324 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
2326 final ArraySet<String> argSet = new ArraySet<String>(args.length);
2327 for (String arg : args) {
2331 synchronized (mUidRulesFirstLock) {
2332 synchronized (mNetworkPoliciesSecondLock) {
2333 if (argSet.contains("--unsnooze")) {
2334 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
2335 mNetworkPolicy.valueAt(i).clearSnooze();
2338 normalizePoliciesNL();
2339 updateNetworkEnabledNL();
2340 updateNetworkRulesNL();
2341 updateNotificationsNL();
2344 fout.println("Cleared snooze timestamps");
2348 fout.print("System ready: "); fout.println(mSystemReady);
2349 fout.print("Restrict background: "); fout.println(mRestrictBackground);
2350 fout.print("Restrict power: "); fout.println(mRestrictPower);
2351 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
2352 fout.println("Network policies:");
2353 fout.increaseIndent();
2354 for (int i = 0; i < mNetworkPolicy.size(); i++) {
2355 fout.println(mNetworkPolicy.valueAt(i).toString());
2357 fout.decreaseIndent();
2359 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
2361 fout.println("Policy for UIDs:");
2362 fout.increaseIndent();
2363 int size = mUidPolicy.size();
2364 for (int i = 0; i < size; i++) {
2365 final int uid = mUidPolicy.keyAt(i);
2366 final int policy = mUidPolicy.valueAt(i);
2369 fout.print(" policy=");
2370 fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
2373 fout.decreaseIndent();
2375 size = mPowerSaveWhitelistExceptIdleAppIds.size();
2377 fout.println("Power save whitelist (except idle) app ids:");
2378 fout.increaseIndent();
2379 for (int i = 0; i < size; i++) {
2381 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2383 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
2386 fout.decreaseIndent();
2389 size = mPowerSaveWhitelistAppIds.size();
2391 fout.println("Power save whitelist app ids:");
2392 fout.increaseIndent();
2393 for (int i = 0; i < size; i++) {
2395 fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
2397 fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
2400 fout.decreaseIndent();
2403 size = mRestrictBackgroundWhitelistUids.size();
2405 fout.println("Restrict background whitelist uids:");
2406 fout.increaseIndent();
2407 for (int i = 0; i < size; i++) {
2409 fout.print(mRestrictBackgroundWhitelistUids.keyAt(i));
2412 fout.decreaseIndent();
2415 size = mDefaultRestrictBackgroundWhitelistUids.size();
2417 fout.println("Default restrict background whitelist uids:");
2418 fout.increaseIndent();
2419 for (int i = 0; i < size; i++) {
2421 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
2424 fout.decreaseIndent();
2427 size = mRestrictBackgroundWhitelistRevokedUids.size();
2429 fout.println("Default restrict background whitelist uids revoked by users:");
2430 fout.increaseIndent();
2431 for (int i = 0; i < size; i++) {
2433 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
2436 fout.decreaseIndent();
2439 final SparseBooleanArray knownUids = new SparseBooleanArray();
2440 collectKeys(mUidState, knownUids);
2441 collectKeys(mUidRules, knownUids);
2443 fout.println("Status for all known UIDs:");
2444 fout.increaseIndent();
2445 size = knownUids.size();
2446 for (int i = 0; i < size; i++) {
2447 final int uid = knownUids.keyAt(i);
2451 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2452 fout.print(" state=");
2454 if (state <= ActivityManager.PROCESS_STATE_TOP) {
2455 fout.print(" (fg)");
2457 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
2458 ? " (fg svc)" : " (bg)");
2461 final int uidRules = mUidRules.get(uid, RULE_NONE);
2462 fout.print(" rules=");
2463 fout.print(uidRulesToString(uidRules));
2466 fout.decreaseIndent();
2468 fout.println("Status for just UIDs with rules:");
2469 fout.increaseIndent();
2470 size = mUidRules.size();
2471 for (int i = 0; i < size; i++) {
2472 final int uid = mUidRules.keyAt(i);
2475 final int uidRules = mUidRules.get(uid, RULE_NONE);
2476 fout.print(" rules=");
2477 fout.print(uidRulesToString(uidRules));
2480 fout.decreaseIndent();
2486 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
2487 String[] args, ResultReceiver resultReceiver) throws RemoteException {
2488 (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
2489 this, in, out, err, args, resultReceiver);
2493 public boolean isUidForeground(int uid) {
2494 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2496 synchronized (mUidRulesFirstLock) {
2497 return isUidForegroundUL(uid);
2501 private boolean isUidForegroundUL(int uid) {
2502 return isUidStateForegroundUL(
2503 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
2506 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
2507 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2508 return isProcStateAllowedWhileOnRestrictBackground(procState);
2511 private boolean isUidForegroundOnRestrictPowerUL(int uid) {
2512 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2513 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
2516 private boolean isUidStateForegroundUL(int state) {
2517 // only really in foreground when screen is also on
2518 return state <= ActivityManager.PROCESS_STATE_TOP;
2522 * Process state of UID changed; if needed, will trigger
2523 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
2524 * {@link #updateRulesForPowerRestrictionsUL(int)}
2526 private void updateUidStateUL(int uid, int uidState) {
2527 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
2529 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2530 if (oldUidState != uidState) {
2531 // state changed, push updated rules
2532 mUidState.put(uid, uidState);
2533 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
2534 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
2535 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
2536 if (isUidIdle(uid)) {
2537 updateRuleForAppIdleUL(uid);
2539 if (mDeviceIdleMode) {
2540 updateRuleForDeviceIdleUL(uid);
2542 if (mRestrictPower) {
2543 updateRuleForRestrictPowerUL(uid);
2545 updateRulesForPowerRestrictionsUL(uid);
2547 updateNetworkStats(uid, isUidStateForegroundUL(uidState));
2550 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2554 private void removeUidStateUL(int uid) {
2555 final int index = mUidState.indexOfKey(uid);
2557 final int oldUidState = mUidState.valueAt(index);
2558 mUidState.removeAt(index);
2559 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2560 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
2561 ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2562 if (mDeviceIdleMode) {
2563 updateRuleForDeviceIdleUL(uid);
2565 if (mRestrictPower) {
2566 updateRuleForRestrictPowerUL(uid);
2568 updateRulesForPowerRestrictionsUL(uid);
2569 updateNetworkStats(uid, false);
2574 // adjust stats accounting based on foreground status
2575 private void updateNetworkStats(int uid, boolean uidForeground) {
2577 mNetworkStats.setUidForeground(uid, uidForeground);
2578 } catch (RemoteException e) {
2579 // ignored; service lives in system_server
2583 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
2585 final boolean oldForeground =
2586 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
2587 final boolean newForeground =
2588 isProcStateAllowedWhileOnRestrictBackground(newUidState);
2589 if (oldForeground != newForeground) {
2590 updateRulesForDataUsageRestrictionsUL(uid);
2594 static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) {
2595 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
2598 static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
2599 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
2602 void updateRulesForPowerSaveUL() {
2603 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
2605 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
2606 mUidFirewallPowerSaveRules);
2608 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2612 void updateRuleForRestrictPowerUL(int uid) {
2613 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
2616 void updateRulesForDeviceIdleUL() {
2617 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
2619 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
2620 mUidFirewallDozableRules);
2622 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2626 void updateRuleForDeviceIdleUL(int uid) {
2627 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
2630 // NOTE: since both fw_dozable and fw_powersave uses the same map
2631 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
2632 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
2633 SparseIntArray rules) {
2635 // Sync the whitelists before enabling the chain. We don't care about the rules if
2636 // we are disabling the chain.
2637 final SparseIntArray uidRules = rules;
2639 final List<UserInfo> users = mUserManager.getUsers();
2640 for (int ui = users.size() - 1; ui >= 0; ui--) {
2641 UserInfo user = users.get(ui);
2642 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
2643 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
2644 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
2645 int uid = UserHandle.getUid(user.id, appId);
2646 uidRules.put(uid, FIREWALL_RULE_ALLOW);
2649 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
2650 int appId = mPowerSaveWhitelistAppIds.keyAt(i);
2651 int uid = UserHandle.getUid(user.id, appId);
2652 uidRules.put(uid, FIREWALL_RULE_ALLOW);
2655 for (int i = mUidState.size() - 1; i >= 0; i--) {
2656 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
2657 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
2660 setUidFirewallRulesAsync(chain, uidRules, CHAIN_TOGGLE_ENABLE);
2662 setUidFirewallRulesAsync(chain, null, CHAIN_TOGGLE_DISABLE);
2666 private boolean isWhitelistedBatterySaverUL(int uid) {
2667 final int appId = UserHandle.getAppId(uid);
2668 return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId);
2671 // NOTE: since both fw_dozable and fw_powersave uses the same map
2672 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
2673 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
2675 if (isWhitelistedBatterySaverUL(uid)
2676 || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) {
2677 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
2679 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
2684 void updateRulesForAppIdleUL() {
2685 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
2687 final SparseIntArray uidRules = mUidFirewallStandbyRules;
2690 // Fully update the app idle firewall chain.
2691 final List<UserInfo> users = mUserManager.getUsers();
2692 for (int ui = users.size() - 1; ui >= 0; ui--) {
2693 UserInfo user = users.get(ui);
2694 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
2695 for (int uid : idleUids) {
2696 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
2697 // quick check: if this uid doesn't have INTERNET permission, it
2698 // doesn't have network access anyway, so it is a waste to mess
2700 if (hasInternetPermissions(uid)) {
2701 uidRules.put(uid, FIREWALL_RULE_DENY);
2707 setUidFirewallRulesAsync(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
2709 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2713 void updateRuleForAppIdleUL(int uid) {
2714 if (!isUidValidForBlacklistRules(uid)) return;
2716 int appId = UserHandle.getAppId(uid);
2717 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
2718 && !isUidForegroundOnRestrictPowerUL(uid)) {
2719 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
2721 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
2725 void updateRulesForAppIdleParoleUL() {
2726 boolean enableChain = !mUsageStats.isAppIdleParoleOn();
2727 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
2731 * Update rules that might be changed by {@link #mRestrictBackground},
2732 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
2734 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
2735 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForGlobalChangeAL");
2737 updateRulesForAppIdleUL();
2738 updateRulesForRestrictPowerUL();
2739 updateRulesForRestrictBackgroundUL();
2741 // If the set of restricted networks may have changed, re-evaluate those.
2742 if (restrictedNetworksChanged) {
2743 normalizePoliciesNL();
2744 updateNetworkRulesNL();
2747 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2751 // TODO: rename / document to make it clear these are global (not app-specific) rules
2752 private void updateRulesForRestrictPowerUL() {
2753 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
2755 updateRulesForDeviceIdleUL();
2756 updateRulesForPowerSaveUL();
2757 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
2759 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2763 private void updateRulesForRestrictBackgroundUL() {
2764 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
2766 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
2768 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2772 private static final int TYPE_RESTRICT_BACKGROUND = 1;
2773 private static final int TYPE_RESTRICT_POWER = 2;
2774 @Retention(RetentionPolicy.SOURCE)
2775 @IntDef(flag = false, value = {
2776 TYPE_RESTRICT_BACKGROUND,
2777 TYPE_RESTRICT_POWER,
2779 public @interface RestrictType {
2782 // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
2783 private void updateRulesForAllAppsUL(@RestrictType int type) {
2784 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
2785 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
2788 final PackageManager pm = mContext.getPackageManager();
2790 // update rules for all installed applications
2791 final List<UserInfo> users = mUserManager.getUsers();
2792 final List<ApplicationInfo> apps = pm.getInstalledApplications(
2793 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS
2794 | PackageManager.MATCH_DIRECT_BOOT_AWARE
2795 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2797 final int usersSize = users.size();
2798 final int appsSize = apps.size();
2799 for (int i = 0; i < usersSize; i++) {
2800 final UserInfo user = users.get(i);
2801 for (int j = 0; j < appsSize; j++) {
2802 final ApplicationInfo app = apps.get(j);
2803 final int uid = UserHandle.getUid(user.id, app.uid);
2805 case TYPE_RESTRICT_BACKGROUND:
2806 updateRulesForDataUsageRestrictionsUL(uid);
2808 case TYPE_RESTRICT_POWER:
2809 updateRulesForPowerRestrictionsUL(uid);
2812 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
2817 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
2818 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2823 private void updateRulesForTempWhitelistChangeUL() {
2824 final List<UserInfo> users = mUserManager.getUsers();
2825 for (int i = 0; i < users.size(); i++) {
2826 final UserInfo user = users.get(i);
2827 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) {
2828 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j);
2829 int uid = UserHandle.getUid(user.id, appId);
2830 // Update external firewall rules.
2831 updateRuleForAppIdleUL(uid);
2832 updateRuleForDeviceIdleUL(uid);
2833 updateRuleForRestrictPowerUL(uid);
2834 // Update internal rules.
2835 updateRulesForPowerRestrictionsUL(uid);
2840 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
2841 // methods below could be merged into a isUidValidForRules() method.
2842 private boolean isUidValidForBlacklistRules(int uid) {
2843 // allow rules on specific system services, and any apps
2844 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
2845 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
2852 private boolean isUidValidForWhitelistRules(int uid) {
2853 return UserHandle.isApp(uid) && hasInternetPermissions(uid);
2856 private boolean isUidIdle(int uid) {
2857 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
2858 final int userId = UserHandle.getUserId(uid);
2860 if (!ArrayUtils.isEmpty(packages)) {
2861 for (String packageName : packages) {
2862 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
2871 * Checks if an uid has INTERNET permissions.
2873 * Useful for the cases where the lack of network access can simplify the rules.
2875 private boolean hasInternetPermissions(int uid) {
2877 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
2878 != PackageManager.PERMISSION_GRANTED) {
2881 } catch (RemoteException e) {
2887 * Applies network rules to bandwidth and firewall controllers based on uid policy.
2889 * <p>There are currently 4 types of restriction rules:
2893 * <li>Battery Saver Mode (also referred as power save).
2894 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
2897 * <p>This method changes both the external firewall rules and the internal state.
2899 private void updateRestrictionRulesForUidUL(int uid) {
2900 // Methods below only changes the firewall rules for the power-related modes.
2901 updateRuleForDeviceIdleUL(uid);
2902 updateRuleForAppIdleUL(uid);
2903 updateRuleForRestrictPowerUL(uid);
2905 // Update internal state for power-related modes.
2906 updateRulesForPowerRestrictionsUL(uid);
2908 // Update firewall and internal rules for Data Saver Mode.
2909 updateRulesForDataUsageRestrictionsUL(uid);
2913 * Applies network rules to bandwidth controllers based on process state and user-defined
2914 * restrictions (blacklist / whitelist).
2917 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
2920 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
2921 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
2923 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
2924 * no UIDs other those whitelisted will have access.
2927 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
2928 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
2929 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
2930 * respectively): these methods set the proper internal state (blacklist / whitelist), then call
2931 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
2932 * {@link INetworkManagementService}, but this method should also be called in events (like
2933 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
2934 * following rules should also be applied:
2937 * <li>When Data Saver mode is on, the foreground app should be temporarily added to
2938 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
2939 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
2940 * {@code bw_penalty_box}.
2941 * <li>When the app leaves foreground state, the temporary changes above should be reverted.
2944 * <p>For optimization, the rules are only applied on user apps that have internet access
2945 * permission, since there is no need to change the {@code iptables} rule if the app does not
2946 * have permission to use the internet.
2948 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
2951 private void updateRulesForDataUsageRestrictionsUL(int uid) {
2952 updateRulesForDataUsageRestrictionsUL(uid, false);
2956 * Overloaded version of {@link #updateRulesForDataUsageRestrictionsUL(int)} called when an
2957 * app is removed - it ignores the UID validity check.
2959 private void updateRulesForDataUsageRestrictionsUL(int uid, boolean uidDeleted) {
2960 if (!uidDeleted && !isUidValidForWhitelistRules(uid)) {
2961 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
2965 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
2966 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
2967 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
2969 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
2970 final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid);
2971 final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
2972 int newRule = RULE_NONE;
2974 // First step: define the new rule based on user restrictions and foreground state.
2976 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
2977 newRule = RULE_TEMPORARY_ALLOW_METERED;
2978 } else if (isWhitelisted) {
2979 newRule = RULE_ALLOW_METERED;
2982 if (isBlacklisted) {
2983 newRule = RULE_REJECT_METERED;
2984 } else if (mRestrictBackground && isWhitelisted) {
2985 newRule = RULE_ALLOW_METERED;
2988 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
2991 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
2992 + ": isForeground=" +isForeground
2993 + ", isBlacklisted=" + isBlacklisted
2994 + ", isWhitelisted=" + isWhitelisted
2995 + ", oldRule=" + uidRulesToString(oldRule)
2996 + ", newRule=" + uidRulesToString(newRule)
2997 + ", newUidRules=" + uidRulesToString(newUidRules)
2998 + ", oldUidRules=" + uidRulesToString(oldUidRules));
3001 if (newUidRules == RULE_NONE) {
3002 mUidRules.delete(uid);
3004 mUidRules.put(uid, newUidRules);
3007 // Second step: apply bw changes based on change of state.
3008 if (newRule != oldRule) {
3009 if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
3010 // Temporarily whitelist foreground app, removing from blacklist if necessary
3011 // (since bw_penalty_box prevails over bw_happy_box).
3013 setMeteredNetworkWhitelist(uid, true);
3014 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
3015 // but ideally it should be just:
3016 // setMeteredNetworkBlacklist(uid, isBlacklisted);
3017 if (isBlacklisted) {
3018 setMeteredNetworkBlacklist(uid, false);
3020 } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
3021 // Remove temporary whitelist from app that is not on foreground anymore.
3023 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
3024 // but ideally they should be just:
3025 // setMeteredNetworkWhitelist(uid, isWhitelisted);
3026 // setMeteredNetworkBlacklist(uid, isBlacklisted);
3027 if (!isWhitelisted) {
3028 setMeteredNetworkWhitelist(uid, false);
3030 if (isBlacklisted) {
3031 setMeteredNetworkBlacklist(uid, true);
3033 } else if ((newRule & RULE_REJECT_METERED) != 0
3034 || (oldRule & RULE_REJECT_METERED) != 0) {
3035 // Flip state because app was explicitly added or removed to blacklist.
3036 setMeteredNetworkBlacklist(uid, isBlacklisted);
3037 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) {
3038 // Since blacklist prevails over whitelist, we need to handle the special case
3039 // where app is whitelisted and blacklisted at the same time (although such
3040 // scenario should be blocked by the UI), then blacklist is removed.
3041 setMeteredNetworkWhitelist(uid, isWhitelisted);
3043 } else if ((newRule & RULE_ALLOW_METERED) != 0
3044 || (oldRule & RULE_ALLOW_METERED) != 0) {
3045 // Flip state because app was explicitly added or removed to whitelist.
3046 setMeteredNetworkWhitelist(uid, isWhitelisted);
3048 // All scenarios should have been covered above.
3049 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
3050 + ": foreground=" + isForeground
3051 + ", whitelisted=" + isWhitelisted
3052 + ", blacklisted=" + isBlacklisted
3053 + ", newRule=" + uidRulesToString(newUidRules)
3054 + ", oldRule=" + uidRulesToString(oldUidRules));
3057 // Dispatch changed rule to existing listeners.
3058 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
3063 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
3064 * listeners in case of change.
3066 * There are 3 power-related rules that affects whether an app has background access on
3067 * non-metered networks, and when the condition applies and the UID is not whitelisted for power
3068 * restriction, it's added to the equivalent firewall chain:
3070 * <li>App is idle: {@code fw_standby} firewall chain.
3071 * <li>Device is idle: {@code fw_dozable} firewall chain.
3072 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
3075 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
3076 * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
3078 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
3080 private void updateRulesForPowerRestrictionsUL(int uid) {
3081 if (!isUidValidForBlacklistRules(uid)) {
3082 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
3086 final boolean isIdle = isUidIdle(uid);
3087 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
3088 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
3089 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
3091 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid);
3092 final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
3093 int newRule = RULE_NONE;
3095 // First step: define the new rule based on user restrictions and foreground state.
3097 // NOTE: if statements below could be inlined, but it's easier to understand the logic
3098 // by considering the foreground and non-foreground states.
3101 newRule = RULE_ALLOW_ALL;
3103 } else if (restrictMode) {
3104 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
3107 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
3110 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
3111 + ", isIdle: " + isIdle
3112 + ", mRestrictPower: " + mRestrictPower
3113 + ", mDeviceIdleMode: " + mDeviceIdleMode
3114 + ", isForeground=" + isForeground
3115 + ", isWhitelisted=" + isWhitelisted
3116 + ", oldRule=" + uidRulesToString(oldRule)
3117 + ", newRule=" + uidRulesToString(newRule)
3118 + ", newUidRules=" + uidRulesToString(newUidRules)
3119 + ", oldUidRules=" + uidRulesToString(oldUidRules));
3122 if (newUidRules == RULE_NONE) {
3123 mUidRules.delete(uid);
3125 mUidRules.put(uid, newUidRules);
3128 // Second step: notify listeners if state changed.
3129 if (newRule != oldRule) {
3130 if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) {
3131 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
3132 } else if ((newRule & RULE_REJECT_ALL) != 0) {
3133 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
3135 // All scenarios should have been covered above
3136 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
3137 + ": foreground=" + isForeground
3138 + ", whitelisted=" + isWhitelisted
3139 + ", newRule=" + uidRulesToString(newUidRules)
3140 + ", oldRule=" + uidRulesToString(oldUidRules));
3142 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
3146 private class AppIdleStateChangeListener
3147 extends UsageStatsManagerInternal.AppIdleStateChangeListener {
3150 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
3152 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
3153 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
3154 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle);
3155 synchronized (mUidRulesFirstLock) {
3156 updateRuleForAppIdleUL(uid);
3157 updateRulesForPowerRestrictionsUL(uid);
3159 } catch (NameNotFoundException nnfe) {
3164 public void onParoleStateChanged(boolean isParoleOn) {
3165 synchronized (mUidRulesFirstLock) {
3166 updateRulesForAppIdleParoleUL();
3171 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
3172 if (listener != null) {
3174 listener.onUidRulesChanged(uid, uidRules);
3175 } catch (RemoteException ignored) {
3180 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
3181 String[] meteredIfaces) {
3182 if (listener != null) {
3184 listener.onMeteredIfacesChanged(meteredIfaces);
3185 } catch (RemoteException ignored) {
3190 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
3191 boolean restrictBackground) {
3192 if (listener != null) {
3194 listener.onRestrictBackgroundChanged(restrictBackground);
3195 } catch (RemoteException ignored) {
3200 private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener,
3201 int uid, boolean whitelisted) {
3202 if (listener != null) {
3204 listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted);
3205 } catch (RemoteException ignored) {
3210 private void dispatchRestrictBackgroundBlacklistChanged(INetworkPolicyListener listener,
3211 int uid, boolean blacklisted) {
3212 if (listener != null) {
3214 listener.onRestrictBackgroundBlacklistChanged(uid, blacklisted);
3215 } catch (RemoteException ignored) {
3220 private Handler.Callback mHandlerCallback = new Handler.Callback() {
3222 public boolean handleMessage(Message msg) {
3224 case MSG_RULES_CHANGED: {
3225 final int uid = msg.arg1;
3226 final int uidRules = msg.arg2;
3227 dispatchUidRulesChanged(mConnectivityListener, uid, uidRules);
3228 final int length = mListeners.beginBroadcast();
3229 for (int i = 0; i < length; i++) {
3230 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3231 dispatchUidRulesChanged(listener, uid, uidRules);
3233 mListeners.finishBroadcast();
3236 case MSG_METERED_IFACES_CHANGED: {
3237 final String[] meteredIfaces = (String[]) msg.obj;
3238 dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces);
3239 final int length = mListeners.beginBroadcast();
3240 for (int i = 0; i < length; i++) {
3241 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3242 dispatchMeteredIfacesChanged(listener, meteredIfaces);
3244 mListeners.finishBroadcast();
3247 case MSG_LIMIT_REACHED: {
3248 final String iface = (String) msg.obj;
3250 maybeRefreshTrustedTime();
3251 synchronized (mNetworkPoliciesSecondLock) {
3252 if (mMeteredIfaces.contains(iface)) {
3254 // force stats update to make sure we have
3255 // numbers that caused alert to trigger.
3256 mNetworkStats.forceUpdate();
3257 } catch (RemoteException e) {
3258 // ignored; service lives in system_server
3261 updateNetworkEnabledNL();
3262 updateNotificationsNL();
3267 case MSG_RESTRICT_BACKGROUND_CHANGED: {
3268 final boolean restrictBackground = msg.arg1 != 0;
3269 dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground);
3270 final int length = mListeners.beginBroadcast();
3271 for (int i = 0; i < length; i++) {
3272 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3273 dispatchRestrictBackgroundChanged(listener, restrictBackground);
3275 mListeners.finishBroadcast();
3276 final Intent intent =
3277 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
3278 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3279 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
3282 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: {
3283 // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions:
3284 // - when an app is whitelisted
3285 // - when an app is blacklisted
3287 // Whether the internal listeners (INetworkPolicyListener implementations) or
3288 // app broadcast receivers are notified depend on the following rules:
3290 // - App receivers are only notified when the app status changed (msg.arg2 = 1)
3291 // - Listeners are only notified when app was whitelisted (msg.obj is not null),
3292 // since blacklist notifications are handled through MSG_RULES_CHANGED).
3293 final int uid = msg.arg1;
3294 final boolean changed = msg.arg2 == 1;
3295 final Boolean whitelisted = (Boolean) msg.obj;
3297 // First notify internal listeners...
3298 if (whitelisted != null) {
3299 final boolean whitelistedBool = whitelisted.booleanValue();
3300 dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid,
3302 final int length = mListeners.beginBroadcast();
3303 for (int i = 0; i < length; i++) {
3304 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3305 dispatchRestrictBackgroundWhitelistChanged(listener, uid,
3308 mListeners.finishBroadcast();
3310 final PackageManager pm = mContext.getPackageManager();
3311 final String[] packages = pm.getPackagesForUid(uid);
3312 if (changed && packages != null) {
3313 // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
3314 final int userId = UserHandle.getUserId(uid);
3315 for (String packageName : packages) {
3316 final Intent intent = new Intent(
3317 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
3318 intent.setPackage(packageName);
3319 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3320 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
3325 case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: {
3326 final int uid = msg.arg1;
3327 final boolean blacklisted = msg.arg2 == 1;
3329 dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid,
3331 final int length = mListeners.beginBroadcast();
3332 for (int i = 0; i < length; i++) {
3333 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3334 dispatchRestrictBackgroundBlacklistChanged(listener, uid,
3337 mListeners.finishBroadcast();
3340 case MSG_ADVISE_PERSIST_THRESHOLD: {
3341 final long lowestRule = (Long) msg.obj;
3343 // make sure stats are recorded frequently enough; we aim
3344 // for 2MB threshold for 2GB/month rules.
3345 final long persistThreshold = lowestRule / 1000;
3346 mNetworkStats.advisePersistThreshold(persistThreshold);
3347 } catch (RemoteException e) {
3348 // ignored; service lives in system_server
3352 case MSG_UPDATE_INTERFACE_QUOTA: {
3353 removeInterfaceQuota((String) msg.obj);
3354 // int params need to be stitched back into a long
3355 setInterfaceQuota((String) msg.obj,
3356 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
3359 case MSG_REMOVE_INTERFACE_QUOTA: {
3360 removeInterfaceQuota((String) msg.obj);
3363 case MSG_SET_FIREWALL_RULES: {
3364 final int chain = msg.arg1;
3365 final int toggle = msg.arg2;
3366 final SparseIntArray uidRules = (SparseIntArray) msg.obj;
3367 if (uidRules != null) {
3368 setUidFirewallRules(chain, uidRules);
3370 if (toggle != CHAIN_TOGGLE_NONE) {
3371 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
3382 private void setInterfaceQuota(String iface, long quotaBytes) {
3384 mNetworkManager.setInterfaceQuota(iface, quotaBytes);
3385 } catch (IllegalStateException e) {
3386 Log.wtf(TAG, "problem setting interface quota", e);
3387 } catch (RemoteException e) {
3388 // ignored; service lives in system_server
3392 private void removeInterfaceQuota(String iface) {
3394 mNetworkManager.removeInterfaceQuota(iface);
3395 } catch (IllegalStateException e) {
3396 Log.wtf(TAG, "problem removing interface quota", e);
3397 } catch (RemoteException e) {
3398 // ignored; service lives in system_server
3402 private void setMeteredNetworkBlacklist(int uid, boolean enable) {
3403 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
3405 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
3406 } catch (IllegalStateException e) {
3407 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
3408 } catch (RemoteException e) {
3409 // ignored; service lives in system_server
3413 private void setMeteredNetworkWhitelist(int uid, boolean enable) {
3414 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
3416 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
3417 } catch (IllegalStateException e) {
3418 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
3419 } catch (RemoteException e) {
3420 // ignored; service lives in system_server
3424 private static final int CHAIN_TOGGLE_NONE = 0;
3425 private static final int CHAIN_TOGGLE_ENABLE = 1;
3426 private static final int CHAIN_TOGGLE_DISABLE = 2;
3427 @Retention(RetentionPolicy.SOURCE)
3428 @IntDef(flag = false, value = {
3430 CHAIN_TOGGLE_ENABLE,
3431 CHAIN_TOGGLE_DISABLE
3433 public @interface ChainToggleType {
3437 * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
3438 * {@link #enableFirewallChainUL(int, boolean)} asynchronously.
3440 * @param chain firewall chain.
3441 * @param uidRules new UID rules; if {@code null}, only toggles chain state.
3442 * @param toggle whether the chain should be enabled, disabled, or not changed.
3444 private void setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules,
3445 @ChainToggleType int toggle) {
3446 mHandler.obtainMessage(MSG_SET_FIREWALL_RULES, chain, toggle, uidRules).sendToTarget();
3450 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
3451 * here to netd. It will clean up dead rules and make sure the target chain only contains rules
3454 private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
3456 int size = uidRules.size();
3457 int[] uids = new int[size];
3458 int[] rules = new int[size];
3459 for(int index = size - 1; index >= 0; --index) {
3460 uids[index] = uidRules.keyAt(index);
3461 rules[index] = uidRules.valueAt(index);
3463 mNetworkManager.setFirewallUidRules(chain, uids, rules);
3464 } catch (IllegalStateException e) {
3465 Log.wtf(TAG, "problem setting firewall uid rules", e);
3466 } catch (RemoteException e) {
3467 // ignored; service lives in system_server
3472 * Add or remove a uid to the firewall blacklist for all network ifaces.
3474 private void setUidFirewallRule(int chain, int uid, int rule) {
3475 if (chain == FIREWALL_CHAIN_DOZABLE) {
3476 mUidFirewallDozableRules.put(uid, rule);
3477 } else if (chain == FIREWALL_CHAIN_STANDBY) {
3478 mUidFirewallStandbyRules.put(uid, rule);
3479 } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
3480 mUidFirewallPowerSaveRules.put(uid, rule);
3484 mNetworkManager.setFirewallUidRule(chain, uid, rule);
3485 } catch (IllegalStateException e) {
3486 Log.wtf(TAG, "problem setting firewall uid rules", e);
3487 } catch (RemoteException e) {
3488 // ignored; service lives in system_server
3493 * Add or remove a uid to the firewall blacklist for all network ifaces.
3495 private void enableFirewallChainUL(int chain, boolean enable) {
3496 if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
3497 mFirewallChainStates.get(chain) == enable) {
3498 // All is the same, nothing to do.
3501 mFirewallChainStates.put(chain, enable);
3503 mNetworkManager.setFirewallChainEnabled(chain, enable);
3504 } catch (IllegalStateException e) {
3505 Log.wtf(TAG, "problem enable firewall chain", e);
3506 } catch (RemoteException e) {
3507 // ignored; service lives in system_server
3511 private long getTotalBytes(NetworkTemplate template, long start, long end) {
3513 return mNetworkStats.getNetworkTotalBytes(template, start, end);
3514 } catch (RuntimeException e) {
3515 Slog.w(TAG, "problem reading network stats: " + e);
3517 } catch (RemoteException e) {
3518 // ignored; service lives in system_server
3523 private boolean isBandwidthControlEnabled() {
3524 final long token = Binder.clearCallingIdentity();
3526 return mNetworkManager.isBandwidthControlEnabled();
3527 } catch (RemoteException e) {
3528 // ignored; service lives in system_server
3531 Binder.restoreCallingIdentity(token);
3536 * Try refreshing {@link #mTime} when stale.
3538 void maybeRefreshTrustedTime() {
3539 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
3540 mTime.forceRefresh();
3544 private long currentTimeMillis() {
3545 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
3548 private static Intent buildAllowBackgroundDataIntent() {
3549 return new Intent(ACTION_ALLOW_BACKGROUND);
3552 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
3553 final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
3554 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3558 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
3559 final Intent intent = new Intent();
3560 intent.setComponent(new ComponentName(
3561 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity"));
3562 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3563 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3567 private static Intent buildViewDataUsageIntent(NetworkTemplate template) {
3568 final Intent intent = new Intent();
3569 intent.setComponent(new ComponentName(
3570 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
3571 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3572 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3577 public void addIdleHandler(IdleHandler handler) {
3578 mHandler.getLooper().getQueue().addIdleHandler(handler);
3581 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
3582 final int size = source.size();
3583 for (int i = 0; i < size; i++) {
3584 target.put(source.keyAt(i), true);
3589 public void factoryReset(String subscriber) {
3590 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
3592 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
3596 // Turn mobile data limit off
3597 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
3598 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
3599 for (NetworkPolicy policy : policies) {
3600 if (policy.template.equals(template)) {
3601 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
3602 policy.inferred = false;
3603 policy.clearSnooze();
3606 setNetworkPolicies(policies);
3608 // Turn restrict background data off
3609 setRestrictBackground(false);
3611 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
3612 // Remove app's "restrict background data" flag
3613 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
3614 setUidPolicy(uid, POLICY_NONE);
3619 private class MyPackageMonitor extends PackageMonitor {
3622 public void onPackageRemoved(String packageName, int uid) {
3623 if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid);
3624 synchronized (mUidRulesFirstLock) {
3625 removeRestrictBackgroundWhitelistedUidUL(uid, true, true);
3626 updateRestrictionRulesForUidUL(uid);
3631 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
3634 public void resetUserState(int userId) {
3635 synchronized (mUidRulesFirstLock) {
3636 boolean changed = removeUserStateUL(userId, false);
3637 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
3639 synchronized (mNetworkPoliciesSecondLock) {