NetworkPolicyManagerService.java revision 781ba14af2a8c8e85f684208055dba0ebfd5db30
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.net; 18 19import static android.Manifest.permission.ACCESS_NETWORK_STATE; 20import static android.Manifest.permission.CONNECTIVITY_INTERNAL; 21import static android.Manifest.permission.DUMP; 22import static android.Manifest.permission.MANAGE_NETWORK_POLICY; 23import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 24import static android.Manifest.permission.READ_PHONE_STATE; 25import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 26import static android.content.Intent.ACTION_PACKAGE_ADDED; 27import static android.content.Intent.ACTION_UID_REMOVED; 28import static android.content.Intent.ACTION_USER_ADDED; 29import static android.content.Intent.ACTION_USER_REMOVED; 30import static android.content.Intent.EXTRA_UID; 31import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 32import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 33import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 34import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; 35import static android.net.ConnectivityManager.TYPE_MOBILE; 36import static android.net.ConnectivityManager.TYPE_WIMAX; 37import static android.net.ConnectivityManager.isNetworkTypeMobile; 38import static android.net.NetworkPolicy.CYCLE_NONE; 39import static android.net.NetworkPolicy.LIMIT_DISABLED; 40import static android.net.NetworkPolicy.SNOOZE_NEVER; 41import static android.net.NetworkPolicy.WARNING_DISABLED; 42import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 43import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; 44import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; 45import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; 46import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; 47import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 48import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; 49import static android.net.NetworkPolicyManager.POLICY_NONE; 50import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 51import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 52import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 53import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; 54import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; 55import static android.net.NetworkPolicyManager.RULE_NONE; 56import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 57import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 58import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 59import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 60import static android.net.NetworkPolicyManager.uidRulesToString; 61import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 62import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 63import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 64import static android.net.NetworkTemplate.MATCH_WIFI; 65import static android.net.NetworkTemplate.buildTemplateMobileAll; 66import static android.net.TrafficStats.MB_IN_BYTES; 67import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 68import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 69import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 70import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 71import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 72import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 73import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 74import static android.text.format.DateUtils.DAY_IN_MILLIS; 75 76import static com.android.internal.util.ArrayUtils.appendInt; 77import static com.android.internal.util.Preconditions.checkNotNull; 78import static com.android.internal.util.XmlUtils.readBooleanAttribute; 79import static com.android.internal.util.XmlUtils.readIntAttribute; 80import static com.android.internal.util.XmlUtils.readLongAttribute; 81import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 82import static com.android.internal.util.XmlUtils.writeIntAttribute; 83import static com.android.internal.util.XmlUtils.writeLongAttribute; 84import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 85import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 86 87import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 88import static org.xmlpull.v1.XmlPullParser.END_TAG; 89import static org.xmlpull.v1.XmlPullParser.START_TAG; 90 91import android.Manifest; 92import android.app.ActivityManager; 93import android.app.AppGlobals; 94import android.app.AppOpsManager; 95import android.app.IActivityManager; 96import android.app.INotificationManager; 97import android.app.IUidObserver; 98import android.app.Notification; 99import android.app.PendingIntent; 100import android.app.usage.UsageStatsManagerInternal; 101import android.content.BroadcastReceiver; 102import android.content.ComponentName; 103import android.content.Context; 104import android.content.Intent; 105import android.content.IntentFilter; 106import android.content.pm.ApplicationInfo; 107import android.content.pm.IPackageManager; 108import android.content.pm.PackageManager; 109import android.content.pm.PackageManager.NameNotFoundException; 110import android.content.pm.UserInfo; 111import android.content.res.Resources; 112import android.net.ConnectivityManager; 113import android.net.IConnectivityManager; 114import android.net.INetworkManagementEventObserver; 115import android.net.INetworkPolicyListener; 116import android.net.INetworkPolicyManager; 117import android.net.INetworkStatsService; 118import android.net.LinkProperties; 119import android.net.NetworkIdentity; 120import android.net.NetworkInfo; 121import android.net.NetworkPolicy; 122import android.net.NetworkPolicyManager; 123import android.net.NetworkQuotaInfo; 124import android.net.NetworkState; 125import android.net.NetworkTemplate; 126import android.net.wifi.WifiConfiguration; 127import android.net.wifi.WifiInfo; 128import android.net.wifi.WifiManager; 129import android.os.Binder; 130import android.os.Environment; 131import android.os.Handler; 132import android.os.HandlerThread; 133import android.os.IDeviceIdleController; 134import android.os.INetworkManagementService; 135import android.os.IPowerManager; 136import android.os.Message; 137import android.os.MessageQueue.IdleHandler; 138import android.os.PowerManager; 139import android.os.PowerManagerInternal; 140import android.os.RemoteCallbackList; 141import android.os.RemoteException; 142import android.os.ResultReceiver; 143import android.os.ServiceManager; 144import android.os.UserHandle; 145import android.os.UserManager; 146import android.provider.Settings; 147import android.telephony.SubscriptionManager; 148import android.telephony.TelephonyManager; 149import android.text.format.Formatter; 150import android.text.format.Time; 151import android.util.ArrayMap; 152import android.util.ArraySet; 153import android.util.AtomicFile; 154import android.util.DebugUtils; 155import android.util.Log; 156import android.util.NtpTrustedTime; 157import android.util.Pair; 158import android.util.Slog; 159import android.util.SparseBooleanArray; 160import android.util.SparseIntArray; 161import android.util.TrustedTime; 162import android.util.Xml; 163 164import com.android.internal.R; 165import com.android.internal.annotations.VisibleForTesting; 166import com.android.internal.content.PackageMonitor; 167import com.android.internal.util.ArrayUtils; 168import com.android.internal.util.FastXmlSerializer; 169import com.android.internal.util.IndentingPrintWriter; 170import com.android.server.DeviceIdleController; 171import com.android.server.EventLogTags; 172import com.android.server.LocalServices; 173import com.android.server.SystemConfig; 174 175import libcore.io.IoUtils; 176 177import com.google.android.collect.Lists; 178 179import org.xmlpull.v1.XmlPullParser; 180import org.xmlpull.v1.XmlPullParserException; 181import org.xmlpull.v1.XmlSerializer; 182 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.PrintWriter; 190import java.nio.charset.StandardCharsets; 191import java.util.ArrayList; 192import java.util.Arrays; 193import java.util.List; 194 195/** 196 * Service that maintains low-level network policy rules, using 197 * {@link NetworkStatsService} statistics to drive those rules. 198 * <p> 199 * Derives active rules by combining a given policy with other system status, 200 * and delivers to listeners, such as {@link ConnectivityManager}, for 201 * enforcement. 202 */ 203public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 204 static final String TAG = "NetworkPolicy"; 205 private static final boolean LOGD = false; 206 private static final boolean LOGV = false; 207 208 private static final int VERSION_INIT = 1; 209 private static final int VERSION_ADDED_SNOOZE = 2; 210 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 211 private static final int VERSION_ADDED_METERED = 4; 212 private static final int VERSION_SPLIT_SNOOZE = 5; 213 private static final int VERSION_ADDED_TIMEZONE = 6; 214 private static final int VERSION_ADDED_INFERRED = 7; 215 private static final int VERSION_SWITCH_APP_ID = 8; 216 private static final int VERSION_ADDED_NETWORK_ID = 9; 217 private static final int VERSION_SWITCH_UID = 10; 218 private static final int VERSION_LATEST = VERSION_SWITCH_UID; 219 220 @VisibleForTesting 221 public static final int TYPE_WARNING = 0x1; 222 @VisibleForTesting 223 public static final int TYPE_LIMIT = 0x2; 224 @VisibleForTesting 225 public static final int TYPE_LIMIT_SNOOZED = 0x3; 226 227 private static final String TAG_POLICY_LIST = "policy-list"; 228 private static final String TAG_NETWORK_POLICY = "network-policy"; 229 private static final String TAG_UID_POLICY = "uid-policy"; 230 private static final String TAG_APP_POLICY = "app-policy"; 231 private static final String TAG_WHITELIST = "whitelist"; 232 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; 233 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background"; 234 235 private static final String ATTR_VERSION = "version"; 236 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 237 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 238 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 239 private static final String ATTR_NETWORK_ID = "networkId"; 240 private static final String ATTR_CYCLE_DAY = "cycleDay"; 241 private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 242 private static final String ATTR_WARNING_BYTES = "warningBytes"; 243 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 244 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 245 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 246 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 247 private static final String ATTR_METERED = "metered"; 248 private static final String ATTR_INFERRED = "inferred"; 249 private static final String ATTR_UID = "uid"; 250 private static final String ATTR_APP_ID = "appId"; 251 private static final String ATTR_POLICY = "policy"; 252 253 private static final String ACTION_ALLOW_BACKGROUND = 254 "com.android.server.net.action.ALLOW_BACKGROUND"; 255 private static final String ACTION_SNOOZE_WARNING = 256 "com.android.server.net.action.SNOOZE_WARNING"; 257 258 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 259 260 private static final int MSG_RULES_CHANGED = 1; 261 private static final int MSG_METERED_IFACES_CHANGED = 2; 262 private static final int MSG_LIMIT_REACHED = 5; 263 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 264 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 265 private static final int MSG_SCREEN_ON_CHANGED = 8; 266 private static final int MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED = 9; 267 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10; 268 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11; 269 270 private final Context mContext; 271 private final IActivityManager mActivityManager; 272 private final IPowerManager mPowerManager; 273 private final INetworkStatsService mNetworkStats; 274 private final INetworkManagementService mNetworkManager; 275 private UsageStatsManagerInternal mUsageStats; 276 private final TrustedTime mTime; 277 private final UserManager mUserManager; 278 279 private IConnectivityManager mConnManager; 280 private INotificationManager mNotifManager; 281 private PowerManagerInternal mPowerManagerInternal; 282 private IDeviceIdleController mDeviceIdleController; 283 284 final Object mRulesLock = new Object(); 285 286 volatile boolean mSystemReady; 287 volatile boolean mScreenOn; 288 volatile boolean mRestrictBackground; 289 volatile boolean mRestrictPower; 290 volatile boolean mDeviceIdleMode; 291 292 private final boolean mSuppressDefaultPolicy; 293 294 /** Defined network policies. */ 295 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); 296 /** Currently active network rules for ifaces. */ 297 final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>(); 298 299 /** Defined UID policies. */ 300 final SparseIntArray mUidPolicy = new SparseIntArray(); 301 /** Currently derived rules for each UID. */ 302 final SparseIntArray mUidRules = new SparseIntArray(); 303 304 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 305 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 306 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 307 308 /** Set of states for the child firewall chains. True if the chain is active. */ 309 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 310 311 /** 312 * UIDs that have been white-listed to always be able to have network access 313 * in power save mode, except device idle (doze) still applies. 314 * TODO: An int array might be sufficient 315 */ 316 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 317 318 /** 319 * UIDs that have been white-listed to always be able to have network access 320 * in power save mode. 321 * TODO: An int array might be sufficient 322 */ 323 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); 324 325 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); 326 327 /** 328 * UIDs that have been white-listed to avoid restricted background. 329 */ 330 private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray(); 331 332 /** 333 * UIDs that have been initially white-listed by system to avoid restricted background. 334 */ 335 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids = 336 new SparseBooleanArray(); 337 338 /** 339 * UIDs that have been initially white-listed by system to avoid restricted background, 340 * but later revoked by user. 341 */ 342 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids = 343 new SparseBooleanArray(); 344 345 /** Set of ifaces that are metered. */ 346 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 347 /** Set of over-limit templates that have been notified. */ 348 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>(); 349 350 /** Set of currently active {@link Notification} tags. */ 351 private final ArraySet<String> mActiveNotifs = new ArraySet<String>(); 352 353 /** Foreground at UID granularity. */ 354 final SparseIntArray mUidState = new SparseIntArray(); 355 356 /** Higher priority listener before general event dispatch */ 357 private INetworkPolicyListener mConnectivityListener; 358 359 private final RemoteCallbackList<INetworkPolicyListener> 360 mListeners = new RemoteCallbackList<>(); 361 362 final Handler mHandler; 363 364 private final AtomicFile mPolicyFile; 365 366 private final AppOpsManager mAppOps; 367 368 private final MyPackageMonitor mPackageMonitor; 369 private final IPackageManager mIPm; 370 371 372 // TODO: keep whitelist of system-critical services that should never have 373 // rules enforced, such as system, phone, and radio UIDs. 374 375 // TODO: migrate notifications to SystemUI 376 377 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 378 IPowerManager powerManager, INetworkStatsService networkStats, 379 INetworkManagementService networkManagement) { 380 this(context, activityManager, powerManager, networkStats, networkManagement, 381 NtpTrustedTime.getInstance(context), getSystemDir(), false); 382 } 383 384 private static File getSystemDir() { 385 return new File(Environment.getDataDirectory(), "system"); 386 } 387 388 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 389 IPowerManager powerManager, INetworkStatsService networkStats, 390 INetworkManagementService networkManagement, TrustedTime time, File systemDir, 391 boolean suppressDefaultPolicy) { 392 mContext = checkNotNull(context, "missing context"); 393 mActivityManager = checkNotNull(activityManager, "missing activityManager"); 394 mPowerManager = checkNotNull(powerManager, "missing powerManager"); 395 mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 396 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 397 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService( 398 Context.DEVICE_IDLE_CONTROLLER)); 399 mTime = checkNotNull(time, "missing TrustedTime"); 400 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 401 mIPm = AppGlobals.getPackageManager(); 402 403 HandlerThread thread = new HandlerThread(TAG); 404 thread.start(); 405 mHandler = new Handler(thread.getLooper(), mHandlerCallback); 406 407 mSuppressDefaultPolicy = suppressDefaultPolicy; 408 409 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 410 411 mAppOps = context.getSystemService(AppOpsManager.class); 412 413 mPackageMonitor = new MyPackageMonitor(); 414 415 // Expose private service for system components to use. 416 LocalServices.addService(NetworkPolicyManagerInternal.class, 417 new NetworkPolicyManagerInternalImpl()); 418 } 419 420 public void bindConnectivityManager(IConnectivityManager connManager) { 421 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 422 } 423 424 public void bindNotificationManager(INotificationManager notifManager) { 425 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 426 } 427 428 void updatePowerSaveWhitelistLocked() { 429 try { 430 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle(); 431 mPowerSaveWhitelistExceptIdleAppIds.clear(); 432 if (whitelist != null) { 433 for (int uid : whitelist) { 434 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); 435 } 436 } 437 whitelist = mDeviceIdleController.getAppIdWhitelist(); 438 mPowerSaveWhitelistAppIds.clear(); 439 if (whitelist != null) { 440 for (int uid : whitelist) { 441 mPowerSaveWhitelistAppIds.put(uid, true); 442 } 443 } 444 } catch (RemoteException e) { 445 } 446 } 447 448 /** 449 * Whitelists pre-defined apps for restrict background, but only if the user didn't already 450 * revoke the whitelist. 451 * 452 * @return whether any uid has been added to {@link #mRestrictBackgroundWhitelistUids}. 453 */ 454 boolean addDefaultRestrictBackgroundWhitelistUidsLocked() { 455 final List<UserInfo> users = mUserManager.getUsers(); 456 final int numberUsers = users.size(); 457 458 boolean changed = false; 459 for (int i = 0; i < numberUsers; i++) { 460 final UserInfo user = users.get(i); 461 changed = addDefaultRestrictBackgroundWhitelistUidsLocked(user.id) || changed; 462 } 463 return changed; 464 } 465 466 private boolean addDefaultRestrictBackgroundWhitelistUidsLocked(int userId) { 467 final SystemConfig sysConfig = SystemConfig.getInstance(); 468 final PackageManager pm = mContext.getPackageManager(); 469 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave(); 470 boolean changed = false; 471 for (int i = 0; i < allowDataUsage.size(); i++) { 472 final String pkg = allowDataUsage.valueAt(i); 473 if (LOGD) 474 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg 475 + " and user " + userId); 476 final ApplicationInfo app; 477 try { 478 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId); 479 } catch (PackageManager.NameNotFoundException e) { 480 // Should not happen 481 Slog.wtf(TAG, "No ApplicationInfo for package " + pkg); 482 continue; 483 } 484 if (!app.isPrivilegedApp()) { 485 Slog.wtf(TAG, "pm.getApplicationInfoAsUser() returned non-privileged app: " + pkg); 486 continue; 487 } 488 final int uid = UserHandle.getUid(userId, app.uid); 489 mDefaultRestrictBackgroundWhitelistUids.append(uid, true); 490 if (LOGD) 491 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted " 492 + "background whitelist. Revoked status: " 493 + mRestrictBackgroundWhitelistRevokedUids.get(uid)); 494 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 495 Slog.i(TAG, "adding default package " + pkg + " (uid " + uid + " for user " 496 + userId + ") to restrict background whitelist"); 497 mRestrictBackgroundWhitelistUids.append(uid, true); 498 changed = true; 499 } 500 } 501 return changed; 502 } 503 504 void updatePowerSaveTempWhitelistLocked() { 505 try { 506 // Clear the states of the current whitelist 507 final int N = mPowerSaveTempWhitelistAppIds.size(); 508 for (int i = 0; i < N; i++) { 509 mPowerSaveTempWhitelistAppIds.setValueAt(i, false); 510 } 511 // Update the states with the new whitelist 512 final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist(); 513 if (whitelist != null) { 514 for (int uid : whitelist) { 515 mPowerSaveTempWhitelistAppIds.put(uid, true); 516 } 517 } 518 } catch (RemoteException e) { 519 } 520 } 521 522 /** 523 * Remove unnecessary entries in the temp whitelist 524 */ 525 void purgePowerSaveTempWhitelistLocked() { 526 final int N = mPowerSaveTempWhitelistAppIds.size(); 527 for (int i = N - 1; i >= 0; i--) { 528 if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) { 529 mPowerSaveTempWhitelistAppIds.removeAt(i); 530 } 531 } 532 } 533 534 public void systemReady() { 535 if (!isBandwidthControlEnabled()) { 536 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 537 return; 538 } 539 540 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); 541 542 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); 543 544 synchronized (mRulesLock) { 545 updatePowerSaveWhitelistLocked(); 546 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 547 mPowerManagerInternal.registerLowPowerModeObserver( 548 new PowerManagerInternal.LowPowerModeListener() { 549 @Override 550 public void onLowPowerModeChanged(boolean enabled) { 551 if (LOGD) Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")"); 552 synchronized (mRulesLock) { 553 if (mRestrictPower != enabled) { 554 mRestrictPower = enabled; 555 updateRulesForRestrictPowerLocked(); 556 updateRulesForGlobalChangeLocked(true); 557 } 558 } 559 } 560 }); 561 mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled(); 562 563 mSystemReady = true; 564 565 // read policy from disk 566 readPolicyLocked(); 567 568 if (addDefaultRestrictBackgroundWhitelistUidsLocked()) { 569 writePolicyLocked(); 570 } 571 572 updateRulesForGlobalChangeLocked(false); 573 updateNotificationsLocked(); 574 } 575 576 updateScreenOn(); 577 578 try { 579 mActivityManager.registerUidObserver(mUidObserver, 580 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE); 581 mNetworkManager.registerObserver(mAlertObserver); 582 } catch (RemoteException e) { 583 // ignored; both services live in system_server 584 } 585 586 // TODO: traverse existing processes to know foreground state, or have 587 // activitymanager dispatch current state when new observer attached. 588 589 final IntentFilter screenFilter = new IntentFilter(); 590 screenFilter.addAction(Intent.ACTION_SCREEN_ON); 591 screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 592 mContext.registerReceiver(mScreenReceiver, screenFilter); 593 594 // listen for changes to power save whitelist 595 final IntentFilter whitelistFilter = new IntentFilter( 596 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 597 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); 598 599 DeviceIdleController.LocalService deviceIdleService 600 = LocalServices.getService(DeviceIdleController.LocalService.class); 601 deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback); 602 603 // watch for network interfaces to be claimed 604 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 605 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 606 607 // listen for package changes to update policy 608 final IntentFilter packageFilter = new IntentFilter(); 609 packageFilter.addAction(ACTION_PACKAGE_ADDED); 610 packageFilter.addDataScheme("package"); 611 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 612 613 // listen for UID changes to update policy 614 mContext.registerReceiver( 615 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 616 617 // listen for user changes to update policy 618 final IntentFilter userFilter = new IntentFilter(); 619 userFilter.addAction(ACTION_USER_ADDED); 620 userFilter.addAction(ACTION_USER_REMOVED); 621 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 622 623 // listen for stats update events 624 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 625 mContext.registerReceiver( 626 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 627 628 // listen for restrict background changes from notifications 629 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 630 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 631 632 // listen for snooze warning from notifications 633 final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING); 634 mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter, 635 MANAGE_NETWORK_POLICY, mHandler); 636 637 // listen for configured wifi networks to be removed 638 final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); 639 mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler); 640 641 // listen for wifi state changes to catch metered hint 642 final IntentFilter wifiStateFilter = new IntentFilter( 643 WifiManager.NETWORK_STATE_CHANGED_ACTION); 644 mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); 645 646 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); 647 648 } 649 650 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 651 @Override public void onUidStateChanged(int uid, int procState) throws RemoteException { 652 synchronized (mRulesLock) { 653 updateUidStateLocked(uid, procState); 654 } 655 } 656 657 @Override public void onUidGone(int uid) throws RemoteException { 658 synchronized (mRulesLock) { 659 removeUidStateLocked(uid); 660 } 661 } 662 663 @Override public void onUidActive(int uid) throws RemoteException { 664 } 665 666 @Override public void onUidIdle(int uid) throws RemoteException { 667 } 668 }; 669 670 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { 671 @Override 672 public void onReceive(Context context, Intent intent) { 673 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected 674 synchronized (mRulesLock) { 675 updatePowerSaveWhitelistLocked(); 676 updateRulesForGlobalChangeLocked(false); 677 } 678 } 679 }; 680 681 final private Runnable mTempPowerSaveChangedCallback = new Runnable() { 682 @Override 683 public void run() { 684 synchronized (mRulesLock) { 685 updatePowerSaveTempWhitelistLocked(); 686 updateRulesForTempWhitelistChangeLocked(); 687 purgePowerSaveTempWhitelistLocked(); 688 } 689 } 690 }; 691 692 final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 693 @Override 694 public void onReceive(Context context, Intent intent) { 695 // screen-related broadcasts are protected by system, no need 696 // for permissions check. 697 mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); 698 } 699 }; 700 701 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 702 @Override 703 public void onReceive(Context context, Intent intent) { 704 // on background handler thread, and PACKAGE_ADDED is protected 705 706 final String action = intent.getAction(); 707 final int uid = intent.getIntExtra(EXTRA_UID, -1); 708 if (uid == -1) return; 709 710 if (ACTION_PACKAGE_ADDED.equals(action)) { 711 // update rules for UID, since it might be subject to 712 // global background data policy 713 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 714 synchronized (mRulesLock) { 715 updateRestrictionRulesForUidLocked(uid); 716 } 717 } 718 } 719 }; 720 721 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 722 @Override 723 public void onReceive(Context context, Intent intent) { 724 // on background handler thread, and UID_REMOVED is protected 725 726 final int uid = intent.getIntExtra(EXTRA_UID, -1); 727 if (uid == -1) return; 728 729 // remove any policy and update rules to clean up 730 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 731 synchronized (mRulesLock) { 732 mUidPolicy.delete(uid); 733 updateRestrictionRulesForUidLocked(uid); 734 writePolicyLocked(); 735 } 736 } 737 }; 738 739 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 740 @Override 741 public void onReceive(Context context, Intent intent) { 742 // on background handler thread, and USER_ADDED and USER_REMOVED 743 // broadcasts are protected 744 745 final String action = intent.getAction(); 746 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 747 if (userId == -1) return; 748 749 switch (action) { 750 case ACTION_USER_REMOVED: 751 case ACTION_USER_ADDED: 752 synchronized (mRulesLock) { 753 // Remove any persistable state for the given user; both cleaning up after a 754 // USER_REMOVED, and one last sanity check during USER_ADDED 755 removeUserStateLocked(userId, true); 756 if (action == ACTION_USER_ADDED) { 757 // Add apps that are whitelisted by default. 758 addDefaultRestrictBackgroundWhitelistUidsLocked(userId); 759 } 760 // Update global restrict for that user 761 updateRulesForGlobalChangeLocked(true); 762 } 763 break; 764 } 765 } 766 }; 767 768 /** 769 * Receiver that watches for {@link INetworkStatsService} updates, which we 770 * use to check against {@link NetworkPolicy#warningBytes}. 771 */ 772 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 773 @Override 774 public void onReceive(Context context, Intent intent) { 775 // on background handler thread, and verified 776 // READ_NETWORK_USAGE_HISTORY permission above. 777 778 maybeRefreshTrustedTime(); 779 synchronized (mRulesLock) { 780 updateNetworkEnabledLocked(); 781 updateNotificationsLocked(); 782 } 783 } 784 }; 785 786 /** 787 * Receiver that watches for {@link Notification} control of 788 * {@link #mRestrictBackground}. 789 */ 790 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 791 @Override 792 public void onReceive(Context context, Intent intent) { 793 // on background handler thread, and verified MANAGE_NETWORK_POLICY 794 // permission above. 795 796 setRestrictBackground(false); 797 } 798 }; 799 800 /** 801 * Receiver that watches for {@link Notification} control of 802 * {@link NetworkPolicy#lastWarningSnooze}. 803 */ 804 final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { 805 @Override 806 public void onReceive(Context context, Intent intent) { 807 // on background handler thread, and verified MANAGE_NETWORK_POLICY 808 // permission above. 809 810 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 811 performSnooze(template, TYPE_WARNING); 812 } 813 }; 814 815 /** 816 * Receiver that watches for {@link WifiConfiguration} to be changed. 817 */ 818 final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { 819 @Override 820 public void onReceive(Context context, Intent intent) { 821 // on background handler thread, and verified CONNECTIVITY_INTERNAL 822 // permission above. 823 824 final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED); 825 if (reason == CHANGE_REASON_REMOVED) { 826 final WifiConfiguration config = intent.getParcelableExtra( 827 EXTRA_WIFI_CONFIGURATION); 828 if (config.SSID != null) { 829 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID); 830 synchronized (mRulesLock) { 831 if (mNetworkPolicy.containsKey(template)) { 832 mNetworkPolicy.remove(template); 833 writePolicyLocked(); 834 } 835 } 836 } 837 } 838 } 839 }; 840 841 /** 842 * Receiver that watches {@link WifiInfo} state changes to infer metered 843 * state. Ignores hints when policy is user-defined. 844 */ 845 final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 846 @Override 847 public void onReceive(Context context, Intent intent) { 848 // on background handler thread, and verified CONNECTIVITY_INTERNAL 849 // permission above. 850 851 // ignore when not connected 852 final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 853 if (!netInfo.isConnected()) return; 854 855 final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO); 856 final boolean meteredHint = info.getMeteredHint(); 857 858 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID()); 859 synchronized (mRulesLock) { 860 NetworkPolicy policy = mNetworkPolicy.get(template); 861 if (policy == null && meteredHint) { 862 // policy doesn't exist, and AP is hinting that it's 863 // metered: create an inferred policy. 864 policy = newWifiPolicy(template, meteredHint); 865 addNetworkPolicyLocked(policy); 866 867 } else if (policy != null && policy.inferred) { 868 // policy exists, and was inferred: update its current 869 // metered state. 870 policy.metered = meteredHint; 871 872 // since this is inferred for each wifi session, just update 873 // rules without persisting. 874 updateNetworkRulesLocked(); 875 } 876 } 877 } 878 }; 879 880 static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) { 881 return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC, 882 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, 883 metered, true); 884 } 885 886 /** 887 * Observer that watches for {@link INetworkManagementService} alerts. 888 */ 889 final private INetworkManagementEventObserver mAlertObserver 890 = new BaseNetworkObserver() { 891 @Override 892 public void limitReached(String limitName, String iface) { 893 // only someone like NMS should be calling us 894 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 895 896 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 897 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 898 } 899 } 900 }; 901 902 /** 903 * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 904 * to show visible notifications as needed. 905 */ 906 void updateNotificationsLocked() { 907 if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 908 909 // keep track of previously active notifications 910 final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs); 911 mActiveNotifs.clear(); 912 913 // TODO: when switching to kernel notifications, compute next future 914 // cycle boundary to recompute notifications. 915 916 // examine stats for each active policy 917 final long currentTime = currentTimeMillis(); 918 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 919 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 920 // ignore policies that aren't relevant to user 921 if (!isTemplateRelevant(policy.template)) continue; 922 if (!policy.hasCycle()) continue; 923 924 final long start = computeLastCycleBoundary(currentTime, policy); 925 final long end = currentTime; 926 final long totalBytes = getTotalBytes(policy.template, start, end); 927 928 if (policy.isOverLimit(totalBytes)) { 929 if (policy.lastLimitSnooze >= start) { 930 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 931 } else { 932 enqueueNotification(policy, TYPE_LIMIT, totalBytes); 933 notifyOverLimitLocked(policy.template); 934 } 935 936 } else { 937 notifyUnderLimitLocked(policy.template); 938 939 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) { 940 enqueueNotification(policy, TYPE_WARNING, totalBytes); 941 } 942 } 943 } 944 945 // cancel stale notifications that we didn't renew above 946 for (int i = beforeNotifs.size()-1; i >= 0; i--) { 947 final String tag = beforeNotifs.valueAt(i); 948 if (!mActiveNotifs.contains(tag)) { 949 cancelNotification(tag); 950 } 951 } 952 } 953 954 /** 955 * Test if given {@link NetworkTemplate} is relevant to user based on 956 * current device state, such as when 957 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 958 * data connection status. 959 */ 960 private boolean isTemplateRelevant(NetworkTemplate template) { 961 if (template.isMatchRuleMobile()) { 962 final TelephonyManager tele = TelephonyManager.from(mContext); 963 final SubscriptionManager sub = SubscriptionManager.from(mContext); 964 965 // Mobile template is relevant when any active subscriber matches 966 final int[] subIds = sub.getActiveSubscriptionIdList(); 967 for (int subId : subIds) { 968 final String subscriberId = tele.getSubscriberId(subId); 969 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 970 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 971 if (template.matches(probeIdent)) { 972 return true; 973 } 974 } 975 return false; 976 } else { 977 return true; 978 } 979 } 980 981 /** 982 * Notify that given {@link NetworkTemplate} is over 983 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 984 */ 985 private void notifyOverLimitLocked(NetworkTemplate template) { 986 if (!mOverLimitNotified.contains(template)) { 987 mContext.startActivity(buildNetworkOverLimitIntent(template)); 988 mOverLimitNotified.add(template); 989 } 990 } 991 992 private void notifyUnderLimitLocked(NetworkTemplate template) { 993 mOverLimitNotified.remove(template); 994 } 995 996 /** 997 * Build unique tag that identifies an active {@link NetworkPolicy} 998 * notification of a specific type, like {@link #TYPE_LIMIT}. 999 */ 1000 private String buildNotificationTag(NetworkPolicy policy, int type) { 1001 return TAG + ":" + policy.template.hashCode() + ":" + type; 1002 } 1003 1004 /** 1005 * Show notification for combined {@link NetworkPolicy} and specific type, 1006 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 1007 */ 1008 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 1009 final String tag = buildNotificationTag(policy, type); 1010 final Notification.Builder builder = new Notification.Builder(mContext); 1011 builder.setOnlyAlertOnce(true); 1012 builder.setWhen(0L); 1013 builder.setColor(mContext.getColor( 1014 com.android.internal.R.color.system_notification_accent_color)); 1015 1016 final Resources res = mContext.getResources(); 1017 switch (type) { 1018 case TYPE_WARNING: { 1019 final CharSequence title = res.getText(R.string.data_usage_warning_title); 1020 final CharSequence body = res.getString(R.string.data_usage_warning_body); 1021 1022 builder.setSmallIcon(R.drawable.stat_notify_error); 1023 builder.setTicker(title); 1024 builder.setContentTitle(title); 1025 builder.setContentText(body); 1026 1027 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template); 1028 builder.setDeleteIntent(PendingIntent.getBroadcast( 1029 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1030 1031 final Intent viewIntent = buildViewDataUsageIntent(policy.template); 1032 builder.setContentIntent(PendingIntent.getActivity( 1033 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1034 1035 break; 1036 } 1037 case TYPE_LIMIT: { 1038 final CharSequence body = res.getText(R.string.data_usage_limit_body); 1039 1040 final CharSequence title; 1041 int icon = R.drawable.stat_notify_disabled_data; 1042 switch (policy.template.getMatchRule()) { 1043 case MATCH_MOBILE_3G_LOWER: 1044 title = res.getText(R.string.data_usage_3g_limit_title); 1045 break; 1046 case MATCH_MOBILE_4G: 1047 title = res.getText(R.string.data_usage_4g_limit_title); 1048 break; 1049 case MATCH_MOBILE_ALL: 1050 title = res.getText(R.string.data_usage_mobile_limit_title); 1051 break; 1052 case MATCH_WIFI: 1053 title = res.getText(R.string.data_usage_wifi_limit_title); 1054 icon = R.drawable.stat_notify_error; 1055 break; 1056 default: 1057 title = null; 1058 break; 1059 } 1060 1061 builder.setOngoing(true); 1062 builder.setSmallIcon(icon); 1063 builder.setTicker(title); 1064 builder.setContentTitle(title); 1065 builder.setContentText(body); 1066 1067 final Intent intent = buildNetworkOverLimitIntent(policy.template); 1068 builder.setContentIntent(PendingIntent.getActivity( 1069 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1070 break; 1071 } 1072 case TYPE_LIMIT_SNOOZED: { 1073 final long overBytes = totalBytes - policy.limitBytes; 1074 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 1075 Formatter.formatFileSize(mContext, overBytes)); 1076 1077 final CharSequence title; 1078 switch (policy.template.getMatchRule()) { 1079 case MATCH_MOBILE_3G_LOWER: 1080 title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 1081 break; 1082 case MATCH_MOBILE_4G: 1083 title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 1084 break; 1085 case MATCH_MOBILE_ALL: 1086 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 1087 break; 1088 case MATCH_WIFI: 1089 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 1090 break; 1091 default: 1092 title = null; 1093 break; 1094 } 1095 1096 builder.setOngoing(true); 1097 builder.setSmallIcon(R.drawable.stat_notify_error); 1098 builder.setTicker(title); 1099 builder.setContentTitle(title); 1100 builder.setContentText(body); 1101 1102 final Intent intent = buildViewDataUsageIntent(policy.template); 1103 builder.setContentIntent(PendingIntent.getActivity( 1104 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1105 break; 1106 } 1107 } 1108 1109 // TODO: move to NotificationManager once we can mock it 1110 try { 1111 final String packageName = mContext.getPackageName(); 1112 final int[] idReceived = new int[1]; 1113 mNotifManager.enqueueNotificationWithTag( 1114 packageName, packageName, tag, 0x0, builder.getNotification(), idReceived, 1115 UserHandle.USER_ALL); 1116 mActiveNotifs.add(tag); 1117 } catch (RemoteException e) { 1118 // ignored; service lives in system_server 1119 } 1120 } 1121 1122 private void cancelNotification(String tag) { 1123 // TODO: move to NotificationManager once we can mock it 1124 try { 1125 final String packageName = mContext.getPackageName(); 1126 mNotifManager.cancelNotificationWithTag( 1127 packageName, tag, 0x0, UserHandle.USER_ALL); 1128 } catch (RemoteException e) { 1129 // ignored; service lives in system_server 1130 } 1131 } 1132 1133 /** 1134 * Receiver that watches for {@link IConnectivityManager} to claim network 1135 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 1136 */ 1137 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 1138 @Override 1139 public void onReceive(Context context, Intent intent) { 1140 // on background handler thread, and verified CONNECTIVITY_INTERNAL 1141 // permission above. 1142 1143 maybeRefreshTrustedTime(); 1144 synchronized (mRulesLock) { 1145 ensureActiveMobilePolicyLocked(); 1146 normalizePoliciesLocked(); 1147 updateNetworkEnabledLocked(); 1148 updateNetworkRulesLocked(); 1149 updateNotificationsLocked(); 1150 } 1151 } 1152 }; 1153 1154 /** 1155 * Proactively control network data connections when they exceed 1156 * {@link NetworkPolicy#limitBytes}. 1157 */ 1158 void updateNetworkEnabledLocked() { 1159 if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()"); 1160 1161 // TODO: reset any policy-disabled networks when any policy is removed 1162 // completely, which is currently rare case. 1163 1164 final long currentTime = currentTimeMillis(); 1165 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1166 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1167 // shortcut when policy has no limit 1168 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 1169 setNetworkTemplateEnabled(policy.template, true); 1170 continue; 1171 } 1172 1173 final long start = computeLastCycleBoundary(currentTime, policy); 1174 final long end = currentTime; 1175 final long totalBytes = getTotalBytes(policy.template, start, end); 1176 1177 // disable data connection when over limit and not snoozed 1178 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 1179 && policy.lastLimitSnooze < start; 1180 final boolean networkEnabled = !overLimitWithoutSnooze; 1181 1182 setNetworkTemplateEnabled(policy.template, networkEnabled); 1183 } 1184 } 1185 1186 /** 1187 * Proactively disable networks that match the given 1188 * {@link NetworkTemplate}. 1189 */ 1190 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 1191 // TODO: reach into ConnectivityManager to proactively disable bringing 1192 // up this network, since we know that traffic will be blocked. 1193 } 1194 1195 /** 1196 * Examine all connected {@link NetworkState}, looking for 1197 * {@link NetworkPolicy} that need to be enforced. When matches found, set 1198 * remaining quota based on usage cycle and historical stats. 1199 */ 1200 void updateNetworkRulesLocked() { 1201 if (LOGV) Slog.v(TAG, "updateNetworkRulesLocked()"); 1202 1203 final NetworkState[] states; 1204 try { 1205 states = mConnManager.getAllNetworkState(); 1206 } catch (RemoteException e) { 1207 // ignored; service lives in system_server 1208 return; 1209 } 1210 1211 // First, generate identities of all connected networks so we can 1212 // quickly compare them against all defined policies below. 1213 final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); 1214 final ArraySet<String> connIfaces = new ArraySet<String>(states.length); 1215 for (NetworkState state : states) { 1216 if (state.networkInfo != null && state.networkInfo.isConnected()) { 1217 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1218 1219 final String baseIface = state.linkProperties.getInterfaceName(); 1220 if (baseIface != null) { 1221 connIdents.add(Pair.create(baseIface, ident)); 1222 } 1223 1224 // Stacked interfaces are considered to have same identity as 1225 // their parent network. 1226 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); 1227 for (LinkProperties stackedLink : stackedLinks) { 1228 final String stackedIface = stackedLink.getInterfaceName(); 1229 if (stackedIface != null) { 1230 connIdents.add(Pair.create(stackedIface, ident)); 1231 } 1232 } 1233 } 1234 } 1235 1236 // Apply policies against all connected interfaces found above 1237 mNetworkRules.clear(); 1238 final ArrayList<String> ifaceList = Lists.newArrayList(); 1239 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1240 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1241 1242 ifaceList.clear(); 1243 for (int j = connIdents.size() - 1; j >= 0; j--) { 1244 final Pair<String, NetworkIdentity> ident = connIdents.get(j); 1245 if (policy.template.matches(ident.second)) { 1246 ifaceList.add(ident.first); 1247 } 1248 } 1249 1250 if (ifaceList.size() > 0) { 1251 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 1252 mNetworkRules.put(policy, ifaces); 1253 } 1254 } 1255 1256 long lowestRule = Long.MAX_VALUE; 1257 final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length); 1258 1259 // apply each policy that we found ifaces for; compute remaining data 1260 // based on current cycle and historical stats, and push to kernel. 1261 final long currentTime = currentTimeMillis(); 1262 for (int i = mNetworkRules.size()-1; i >= 0; i--) { 1263 final NetworkPolicy policy = mNetworkRules.keyAt(i); 1264 final String[] ifaces = mNetworkRules.valueAt(i); 1265 1266 final long start; 1267 final long totalBytes; 1268 if (policy.hasCycle()) { 1269 start = computeLastCycleBoundary(currentTime, policy); 1270 totalBytes = getTotalBytes(policy.template, start, currentTime); 1271 } else { 1272 start = Long.MAX_VALUE; 1273 totalBytes = 0; 1274 } 1275 1276 if (LOGD) { 1277 Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces)); 1278 } 1279 1280 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 1281 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 1282 if (hasLimit || policy.metered) { 1283 final long quotaBytes; 1284 if (!hasLimit) { 1285 // metered network, but no policy limit; we still need to 1286 // restrict apps, so push really high quota. 1287 quotaBytes = Long.MAX_VALUE; 1288 } else if (policy.lastLimitSnooze >= start) { 1289 // snoozing past quota, but we still need to restrict apps, 1290 // so push really high quota. 1291 quotaBytes = Long.MAX_VALUE; 1292 } else { 1293 // remaining "quota" bytes are based on total usage in 1294 // current cycle. kernel doesn't like 0-byte rules, so we 1295 // set 1-byte quota and disable the radio later. 1296 quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 1297 } 1298 1299 if (ifaces.length > 1) { 1300 // TODO: switch to shared quota once NMS supports 1301 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 1302 } 1303 1304 for (String iface : ifaces) { 1305 // long quotaBytes split up into two ints to fit in message 1306 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1307 (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface) 1308 .sendToTarget(); 1309 newMeteredIfaces.add(iface); 1310 } 1311 } 1312 1313 // keep track of lowest warning or limit of active policies 1314 if (hasWarning && policy.warningBytes < lowestRule) { 1315 lowestRule = policy.warningBytes; 1316 } 1317 if (hasLimit && policy.limitBytes < lowestRule) { 1318 lowestRule = policy.limitBytes; 1319 } 1320 } 1321 1322 for (int i = connIfaces.size()-1; i >= 0; i--) { 1323 String iface = connIfaces.valueAt(i); 1324 // long quotaBytes split up into two ints to fit in message 1325 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1326 (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface) 1327 .sendToTarget(); 1328 newMeteredIfaces.add(iface); 1329 } 1330 1331 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 1332 1333 // remove quota on any trailing interfaces 1334 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) { 1335 final String iface = mMeteredIfaces.valueAt(i); 1336 if (!newMeteredIfaces.contains(iface)) { 1337 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface) 1338 .sendToTarget(); 1339 } 1340 } 1341 mMeteredIfaces = newMeteredIfaces; 1342 1343 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 1344 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 1345 } 1346 1347 /** 1348 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 1349 * have at least a default mobile policy defined. 1350 */ 1351 private void ensureActiveMobilePolicyLocked() { 1352 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 1353 if (mSuppressDefaultPolicy) return; 1354 1355 final TelephonyManager tele = TelephonyManager.from(mContext); 1356 final SubscriptionManager sub = SubscriptionManager.from(mContext); 1357 1358 final int[] subIds = sub.getActiveSubscriptionIdList(); 1359 for (int subId : subIds) { 1360 final String subscriberId = tele.getSubscriberId(subId); 1361 ensureActiveMobilePolicyLocked(subscriberId); 1362 } 1363 } 1364 1365 private void ensureActiveMobilePolicyLocked(String subscriberId) { 1366 // Poke around to see if we already have a policy 1367 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1368 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1369 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1370 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1371 if (template.matches(probeIdent)) { 1372 if (LOGD) { 1373 Slog.d(TAG, "Found template " + template + " which matches subscriber " 1374 + NetworkIdentity.scrubSubscriberId(subscriberId)); 1375 } 1376 return; 1377 } 1378 } 1379 1380 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId) 1381 + "; generating default policy"); 1382 1383 // Build default mobile policy, and assume usage cycle starts today 1384 final long warningBytes = mContext.getResources().getInteger( 1385 com.android.internal.R.integer.config_networkPolicyDefaultWarning) * MB_IN_BYTES; 1386 1387 final Time time = new Time(); 1388 time.setToNow(); 1389 1390 final int cycleDay = time.monthDay; 1391 final String cycleTimezone = time.timezone; 1392 1393 final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 1394 final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, 1395 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true); 1396 addNetworkPolicyLocked(policy); 1397 } 1398 1399 private void readPolicyLocked() { 1400 if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 1401 1402 // clear any existing policy and read from disk 1403 mNetworkPolicy.clear(); 1404 mUidPolicy.clear(); 1405 1406 FileInputStream fis = null; 1407 try { 1408 fis = mPolicyFile.openRead(); 1409 final XmlPullParser in = Xml.newPullParser(); 1410 in.setInput(fis, StandardCharsets.UTF_8.name()); 1411 1412 int type; 1413 int version = VERSION_INIT; 1414 boolean insideWhitelist = false; 1415 while ((type = in.next()) != END_DOCUMENT) { 1416 final String tag = in.getName(); 1417 if (type == START_TAG) { 1418 if (TAG_POLICY_LIST.equals(tag)) { 1419 final boolean oldValue = mRestrictBackground; 1420 version = readIntAttribute(in, ATTR_VERSION); 1421 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 1422 mRestrictBackground = readBooleanAttribute( 1423 in, ATTR_RESTRICT_BACKGROUND); 1424 } else { 1425 mRestrictBackground = false; 1426 } 1427 if (mRestrictBackground != oldValue) { 1428 // Some early services may have read the default value, 1429 // so notify them that it's changed 1430 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, 1431 mRestrictBackground ? 1 : 0, 0).sendToTarget(); 1432 } 1433 1434 } else if (TAG_NETWORK_POLICY.equals(tag)) { 1435 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 1436 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 1437 final String networkId; 1438 if (version >= VERSION_ADDED_NETWORK_ID) { 1439 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 1440 } else { 1441 networkId = null; 1442 } 1443 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 1444 final String cycleTimezone; 1445 if (version >= VERSION_ADDED_TIMEZONE) { 1446 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 1447 } else { 1448 cycleTimezone = Time.TIMEZONE_UTC; 1449 } 1450 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 1451 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 1452 final long lastLimitSnooze; 1453 if (version >= VERSION_SPLIT_SNOOZE) { 1454 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 1455 } else if (version >= VERSION_ADDED_SNOOZE) { 1456 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 1457 } else { 1458 lastLimitSnooze = SNOOZE_NEVER; 1459 } 1460 final boolean metered; 1461 if (version >= VERSION_ADDED_METERED) { 1462 metered = readBooleanAttribute(in, ATTR_METERED); 1463 } else { 1464 switch (networkTemplate) { 1465 case MATCH_MOBILE_3G_LOWER: 1466 case MATCH_MOBILE_4G: 1467 case MATCH_MOBILE_ALL: 1468 metered = true; 1469 break; 1470 default: 1471 metered = false; 1472 } 1473 } 1474 final long lastWarningSnooze; 1475 if (version >= VERSION_SPLIT_SNOOZE) { 1476 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 1477 } else { 1478 lastWarningSnooze = SNOOZE_NEVER; 1479 } 1480 final boolean inferred; 1481 if (version >= VERSION_ADDED_INFERRED) { 1482 inferred = readBooleanAttribute(in, ATTR_INFERRED); 1483 } else { 1484 inferred = false; 1485 } 1486 1487 final NetworkTemplate template = new NetworkTemplate(networkTemplate, 1488 subscriberId, networkId); 1489 if (template.isPersistable()) { 1490 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, 1491 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, 1492 lastLimitSnooze, metered, inferred)); 1493 } 1494 1495 } else if (TAG_UID_POLICY.equals(tag)) { 1496 final int uid = readIntAttribute(in, ATTR_UID); 1497 final int policy = readIntAttribute(in, ATTR_POLICY); 1498 1499 if (UserHandle.isApp(uid)) { 1500 setUidPolicyUncheckedLocked(uid, policy, false); 1501 } else { 1502 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1503 } 1504 } else if (TAG_APP_POLICY.equals(tag)) { 1505 final int appId = readIntAttribute(in, ATTR_APP_ID); 1506 final int policy = readIntAttribute(in, ATTR_POLICY); 1507 1508 // TODO: set for other users during upgrade 1509 // app policy is deprecated so this is only used in pre system user split. 1510 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId); 1511 if (UserHandle.isApp(uid)) { 1512 setUidPolicyUncheckedLocked(uid, policy, false); 1513 } else { 1514 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1515 } 1516 } else if (TAG_WHITELIST.equals(tag)) { 1517 insideWhitelist = true; 1518 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1519 final int uid = readIntAttribute(in, ATTR_UID); 1520 mRestrictBackgroundWhitelistUids.put(uid, true); 1521 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1522 final int uid = readIntAttribute(in, ATTR_UID); 1523 mRestrictBackgroundWhitelistRevokedUids.put(uid, true); 1524 } 1525 } else if (type == END_TAG) { 1526 if (TAG_WHITELIST.equals(tag)) { 1527 insideWhitelist = false; 1528 } 1529 1530 } 1531 } 1532 1533 } catch (FileNotFoundException e) { 1534 // missing policy is okay, probably first boot 1535 upgradeLegacyBackgroundData(); 1536 } catch (IOException e) { 1537 Log.wtf(TAG, "problem reading network policy", e); 1538 } catch (XmlPullParserException e) { 1539 Log.wtf(TAG, "problem reading network policy", e); 1540 } finally { 1541 IoUtils.closeQuietly(fis); 1542 } 1543 } 1544 1545 /** 1546 * Upgrade legacy background data flags, notifying listeners of one last 1547 * change to always-true. 1548 */ 1549 private void upgradeLegacyBackgroundData() { 1550 mRestrictBackground = Settings.Secure.getInt( 1551 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 1552 1553 // kick off one last broadcast if restricted 1554 if (mRestrictBackground) { 1555 final Intent broadcast = new Intent( 1556 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 1557 mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL); 1558 } 1559 } 1560 1561 void writePolicyLocked() { 1562 if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 1563 1564 FileOutputStream fos = null; 1565 try { 1566 fos = mPolicyFile.startWrite(); 1567 1568 XmlSerializer out = new FastXmlSerializer(); 1569 out.setOutput(fos, StandardCharsets.UTF_8.name()); 1570 out.startDocument(null, true); 1571 1572 out.startTag(null, TAG_POLICY_LIST); 1573 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 1574 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 1575 1576 // write all known network policies 1577 for (int i = 0; i < mNetworkPolicy.size(); i++) { 1578 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1579 final NetworkTemplate template = policy.template; 1580 if (!template.isPersistable()) continue; 1581 1582 out.startTag(null, TAG_NETWORK_POLICY); 1583 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 1584 final String subscriberId = template.getSubscriberId(); 1585 if (subscriberId != null) { 1586 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 1587 } 1588 final String networkId = template.getNetworkId(); 1589 if (networkId != null) { 1590 out.attribute(null, ATTR_NETWORK_ID, networkId); 1591 } 1592 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 1593 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone); 1594 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 1595 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 1596 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 1597 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 1598 writeBooleanAttribute(out, ATTR_METERED, policy.metered); 1599 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 1600 out.endTag(null, TAG_NETWORK_POLICY); 1601 } 1602 1603 // write all known uid policies 1604 for (int i = 0; i < mUidPolicy.size(); i++) { 1605 final int uid = mUidPolicy.keyAt(i); 1606 final int policy = mUidPolicy.valueAt(i); 1607 1608 // skip writing empty policies 1609 if (policy == POLICY_NONE) continue; 1610 1611 out.startTag(null, TAG_UID_POLICY); 1612 writeIntAttribute(out, ATTR_UID, uid); 1613 writeIntAttribute(out, ATTR_POLICY, policy); 1614 out.endTag(null, TAG_UID_POLICY); 1615 } 1616 1617 out.endTag(null, TAG_POLICY_LIST); 1618 1619 // write all whitelists 1620 out.startTag(null, TAG_WHITELIST); 1621 1622 // restrict background whitelist 1623 int size = mRestrictBackgroundWhitelistUids.size(); 1624 for (int i = 0; i < size; i++) { 1625 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); 1626 out.startTag(null, TAG_RESTRICT_BACKGROUND); 1627 writeIntAttribute(out, ATTR_UID, uid); 1628 out.endTag(null, TAG_RESTRICT_BACKGROUND); 1629 } 1630 1631 // revoked restrict background whitelist 1632 size = mRestrictBackgroundWhitelistRevokedUids.size(); 1633 for (int i = 0; i < size; i++) { 1634 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 1635 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 1636 writeIntAttribute(out, ATTR_UID, uid); 1637 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 1638 } 1639 1640 out.endTag(null, TAG_WHITELIST); 1641 1642 out.endDocument(); 1643 1644 mPolicyFile.finishWrite(fos); 1645 } catch (IOException e) { 1646 if (fos != null) { 1647 mPolicyFile.failWrite(fos); 1648 } 1649 } 1650 } 1651 1652 @Override 1653 public void setUidPolicy(int uid, int policy) { 1654 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1655 1656 if (!UserHandle.isApp(uid)) { 1657 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1658 } 1659 1660 synchronized (mRulesLock) { 1661 final long token = Binder.clearCallingIdentity(); 1662 try { 1663 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1664 if (oldPolicy != policy) { 1665 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1666 } 1667 } finally { 1668 Binder.restoreCallingIdentity(token); 1669 } 1670 } 1671 } 1672 1673 @Override 1674 public void addUidPolicy(int uid, int policy) { 1675 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1676 1677 if (!UserHandle.isApp(uid)) { 1678 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1679 } 1680 1681 synchronized (mRulesLock) { 1682 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1683 policy |= oldPolicy; 1684 if (oldPolicy != policy) { 1685 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1686 } 1687 } 1688 } 1689 1690 @Override 1691 public void removeUidPolicy(int uid, int policy) { 1692 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1693 1694 if (!UserHandle.isApp(uid)) { 1695 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1696 } 1697 1698 synchronized (mRulesLock) { 1699 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1700 policy = oldPolicy & ~policy; 1701 if (oldPolicy != policy) { 1702 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1703 } 1704 } 1705 } 1706 1707 private void setUidPolicyUncheckedLocked(int uid, int oldPolicy, int policy, boolean persist) { 1708 setUidPolicyUncheckedLocked(uid, policy, persist); 1709 1710 // Checks if app was added or removed to the blacklist. 1711 if ((oldPolicy == POLICY_NONE && policy == POLICY_REJECT_METERED_BACKGROUND) 1712 || (oldPolicy == POLICY_REJECT_METERED_BACKGROUND && policy == POLICY_NONE)) { 1713 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null) 1714 .sendToTarget(); 1715 } 1716 } 1717 1718 private void setUidPolicyUncheckedLocked(int uid, int policy, boolean persist) { 1719 mUidPolicy.put(uid, policy); 1720 1721 // uid policy changed, recompute rules and persist policy. 1722 updateRulesForDataUsageRestrictionsLocked(uid); 1723 if (persist) { 1724 writePolicyLocked(); 1725 } 1726 } 1727 1728 @Override 1729 public int getUidPolicy(int uid) { 1730 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1731 1732 synchronized (mRulesLock) { 1733 return mUidPolicy.get(uid, POLICY_NONE); 1734 } 1735 } 1736 1737 @Override 1738 public int[] getUidsWithPolicy(int policy) { 1739 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1740 1741 int[] uids = new int[0]; 1742 synchronized (mRulesLock) { 1743 for (int i = 0; i < mUidPolicy.size(); i++) { 1744 final int uid = mUidPolicy.keyAt(i); 1745 final int uidPolicy = mUidPolicy.valueAt(i); 1746 if (uidPolicy == policy) { 1747 uids = appendInt(uids, uid); 1748 } 1749 } 1750 } 1751 return uids; 1752 } 1753 1754 /** 1755 * Removes any persistable state associated with given {@link UserHandle}, persisting 1756 * if any changes that are made. 1757 */ 1758 boolean removeUserStateLocked(int userId, boolean writePolicy) { 1759 1760 if (LOGV) Slog.v(TAG, "removeUserStateLocked()"); 1761 boolean changed = false; 1762 1763 // Remove entries from restricted background UID whitelist 1764 int[] wlUids = new int[0]; 1765 for (int i = 0; i < mRestrictBackgroundWhitelistUids.size(); i++) { 1766 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); 1767 if (UserHandle.getUserId(uid) == userId) { 1768 wlUids = appendInt(wlUids, uid); 1769 } 1770 } 1771 1772 if (wlUids.length > 0) { 1773 for (int uid : wlUids) { 1774 removeRestrictBackgroundWhitelistedUidLocked(uid, false, false); 1775 } 1776 changed = true; 1777 } 1778 1779 // Remove entries from revoked default restricted background UID whitelist 1780 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) { 1781 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 1782 if (UserHandle.getUserId(uid) == userId) { 1783 mRestrictBackgroundWhitelistRevokedUids.removeAt(i); 1784 changed = true; 1785 } 1786 } 1787 1788 // Remove associated UID policies 1789 int[] uids = new int[0]; 1790 for (int i = 0; i < mUidPolicy.size(); i++) { 1791 final int uid = mUidPolicy.keyAt(i); 1792 if (UserHandle.getUserId(uid) == userId) { 1793 uids = appendInt(uids, uid); 1794 } 1795 } 1796 1797 if (uids.length > 0) { 1798 for (int uid : uids) { 1799 mUidPolicy.delete(uid); 1800 } 1801 changed = true; 1802 } 1803 1804 updateRulesForGlobalChangeLocked(true); 1805 1806 if (writePolicy && changed) { 1807 writePolicyLocked(); 1808 } 1809 return changed; 1810 } 1811 1812 @Override 1813 public void setConnectivityListener(INetworkPolicyListener listener) { 1814 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1815 if (mConnectivityListener != null) { 1816 throw new IllegalStateException("Connectivity listener already registered"); 1817 } 1818 mConnectivityListener = listener; 1819 } 1820 1821 @Override 1822 public void registerListener(INetworkPolicyListener listener) { 1823 // TODO: create permission for observing network policy 1824 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1825 mListeners.register(listener); 1826 } 1827 1828 @Override 1829 public void unregisterListener(INetworkPolicyListener listener) { 1830 // TODO: create permission for observing network policy 1831 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1832 mListeners.unregister(listener); 1833 } 1834 1835 @Override 1836 public void setNetworkPolicies(NetworkPolicy[] policies) { 1837 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1838 1839 final long token = Binder.clearCallingIdentity(); 1840 try { 1841 maybeRefreshTrustedTime(); 1842 synchronized (mRulesLock) { 1843 normalizePoliciesLocked(policies); 1844 updateNetworkEnabledLocked(); 1845 updateNetworkRulesLocked(); 1846 updateNotificationsLocked(); 1847 writePolicyLocked(); 1848 } 1849 } finally { 1850 Binder.restoreCallingIdentity(token); 1851 } 1852 } 1853 1854 void addNetworkPolicyLocked(NetworkPolicy policy) { 1855 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 1856 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy); 1857 setNetworkPolicies(policies); 1858 } 1859 1860 @Override 1861 public NetworkPolicy[] getNetworkPolicies(String callingPackage) { 1862 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1863 try { 1864 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); 1865 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED 1866 // permission 1867 } catch (SecurityException e) { 1868 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 1869 1870 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 1871 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1872 return new NetworkPolicy[0]; 1873 } 1874 } 1875 1876 synchronized (mRulesLock) { 1877 final int size = mNetworkPolicy.size(); 1878 final NetworkPolicy[] policies = new NetworkPolicy[size]; 1879 for (int i = 0; i < size; i++) { 1880 policies[i] = mNetworkPolicy.valueAt(i); 1881 } 1882 return policies; 1883 } 1884 } 1885 1886 private void normalizePoliciesLocked() { 1887 normalizePoliciesLocked(getNetworkPolicies(mContext.getOpPackageName())); 1888 } 1889 1890 private void normalizePoliciesLocked(NetworkPolicy[] policies) { 1891 final TelephonyManager tele = TelephonyManager.from(mContext); 1892 final String[] merged = tele.getMergedSubscriberIds(); 1893 1894 mNetworkPolicy.clear(); 1895 for (NetworkPolicy policy : policies) { 1896 // When two normalized templates conflict, prefer the most 1897 // restrictive policy 1898 policy.template = NetworkTemplate.normalize(policy.template, merged); 1899 final NetworkPolicy existing = mNetworkPolicy.get(policy.template); 1900 if (existing == null || existing.compareTo(policy) > 0) { 1901 if (existing != null) { 1902 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy); 1903 } 1904 mNetworkPolicy.put(policy.template, policy); 1905 } 1906 } 1907 } 1908 1909 @Override 1910 public void snoozeLimit(NetworkTemplate template) { 1911 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1912 1913 final long token = Binder.clearCallingIdentity(); 1914 try { 1915 performSnooze(template, TYPE_LIMIT); 1916 } finally { 1917 Binder.restoreCallingIdentity(token); 1918 } 1919 } 1920 1921 void performSnooze(NetworkTemplate template, int type) { 1922 maybeRefreshTrustedTime(); 1923 final long currentTime = currentTimeMillis(); 1924 synchronized (mRulesLock) { 1925 // find and snooze local policy that matches 1926 final NetworkPolicy policy = mNetworkPolicy.get(template); 1927 if (policy == null) { 1928 throw new IllegalArgumentException("unable to find policy for " + template); 1929 } 1930 1931 switch (type) { 1932 case TYPE_WARNING: 1933 policy.lastWarningSnooze = currentTime; 1934 break; 1935 case TYPE_LIMIT: 1936 policy.lastLimitSnooze = currentTime; 1937 break; 1938 default: 1939 throw new IllegalArgumentException("unexpected type"); 1940 } 1941 1942 normalizePoliciesLocked(); 1943 updateNetworkEnabledLocked(); 1944 updateNetworkRulesLocked(); 1945 updateNotificationsLocked(); 1946 writePolicyLocked(); 1947 } 1948 } 1949 1950 @Override 1951 public void onTetheringChanged(String iface, boolean tethering) { 1952 // No need to enforce permission because setRestrictBackground() will do it. 1953 if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")"); 1954 synchronized (mRulesLock) { 1955 if (mRestrictBackground && tethering) { 1956 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver"); 1957 setRestrictBackground(false); 1958 } 1959 } 1960 } 1961 1962 @Override 1963 public void setRestrictBackground(boolean restrictBackground) { 1964 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1965 final long token = Binder.clearCallingIdentity(); 1966 try { 1967 maybeRefreshTrustedTime(); 1968 synchronized (mRulesLock) { 1969 if (restrictBackground == mRestrictBackground) { 1970 // Ideally, UI should never allow this scenario... 1971 Slog.w(TAG, "setRestrictBackground: already " + restrictBackground); 1972 return; 1973 } 1974 setRestrictBackgroundLocked(restrictBackground); 1975 } 1976 1977 } finally { 1978 Binder.restoreCallingIdentity(token); 1979 } 1980 1981 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 1982 .sendToTarget(); 1983 } 1984 1985 private void setRestrictBackgroundLocked(boolean restrictBackground) { 1986 final boolean oldRestrictBackground = mRestrictBackground; 1987 mRestrictBackground = restrictBackground; 1988 // Must whitelist foreground apps before turning data saver mode on. 1989 // TODO: there is no need to iterate through all apps here, just those in the foreground, 1990 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 1991 updateRulesForRestrictBackgroundLocked(); 1992 try { 1993 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 1994 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 1995 mRestrictBackground = oldRestrictBackground; 1996 // TODO: if it knew the foreground apps (see TODO above), it could call 1997 // updateRulesForRestrictBackgroundLocked() again to restore state. 1998 return; 1999 } 2000 } catch (RemoteException e) { 2001 // ignored; service lives in system_server 2002 } 2003 updateNotificationsLocked(); 2004 writePolicyLocked(); 2005 } 2006 2007 @Override 2008 public void addRestrictBackgroundWhitelistedUid(int uid) { 2009 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2010 final boolean oldStatus; 2011 final boolean needFirewallRules; 2012 synchronized (mRulesLock) { 2013 oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2014 if (oldStatus) { 2015 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); 2016 return; 2017 } 2018 needFirewallRules = isUidValidForWhitelistRules(uid); 2019 Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); 2020 mRestrictBackgroundWhitelistUids.append(uid, true); 2021 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2022 && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2023 if (LOGD) Slog.d(TAG, "Removing uid " + uid 2024 + " from revoked restrict background whitelist"); 2025 mRestrictBackgroundWhitelistRevokedUids.delete(uid); 2026 } 2027 if (needFirewallRules) { 2028 // Only update firewall rules if necessary... 2029 updateRulesForDataUsageRestrictionsLocked(uid); 2030 } 2031 // ...but always persists the whitelist request. 2032 writePolicyLocked(); 2033 } 2034 int changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; 2035 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, 2036 Boolean.TRUE).sendToTarget(); 2037 } 2038 2039 @Override 2040 public void removeRestrictBackgroundWhitelistedUid(int uid) { 2041 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2042 final boolean changed; 2043 synchronized (mRulesLock) { 2044 changed = removeRestrictBackgroundWhitelistedUidLocked(uid, false, true); 2045 } 2046 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, 2047 Boolean.FALSE).sendToTarget(); 2048 } 2049 2050 /** 2051 * Removes a uid from the restricted background whitelist, returning whether its current 2052 * {@link ConnectivityManager.RestrictBackgroundStatus} changed. 2053 */ 2054 private boolean removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean uidDeleted, 2055 boolean updateNow) { 2056 final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2057 if (!oldStatus && !uidDeleted) { 2058 if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before"); 2059 return false; 2060 } 2061 final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid); 2062 if (oldStatus) { 2063 Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); 2064 mRestrictBackgroundWhitelistUids.delete(uid); 2065 } 2066 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2067 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2068 if (LOGD) Slog.d(TAG, "Adding uid " + uid 2069 + " to revoked restrict background whitelist"); 2070 mRestrictBackgroundWhitelistRevokedUids.append(uid, true); 2071 } 2072 if (needFirewallRules) { 2073 // Only update firewall rules if necessary... 2074 updateRulesForDataUsageRestrictionsLocked(uid, uidDeleted); 2075 } 2076 if (updateNow) { 2077 // ...but always persists the whitelist request. 2078 writePolicyLocked(); 2079 } 2080 // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the 2081 // app was whitelisted before). 2082 return mRestrictBackground && needFirewallRules; 2083 } 2084 2085 @Override 2086 public int[] getRestrictBackgroundWhitelistedUids() { 2087 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2088 synchronized (mRulesLock) { 2089 final int size = mRestrictBackgroundWhitelistUids.size(); 2090 final int[] whitelist = new int[size]; 2091 for (int i = 0; i < size; i++) { 2092 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); 2093 } 2094 if (LOGV) { 2095 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " 2096 + mRestrictBackgroundWhitelistUids); 2097 } 2098 return whitelist; 2099 } 2100 } 2101 2102 @Override 2103 public int getRestrictBackgroundByCaller() { 2104 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2105 final int uid = Binder.getCallingUid(); 2106 2107 synchronized (mRulesLock) { 2108 // Must clear identity because getUidPolicy() is restricted to system. 2109 final long token = Binder.clearCallingIdentity(); 2110 final int policy; 2111 try { 2112 policy = getUidPolicy(uid); 2113 } finally { 2114 Binder.restoreCallingIdentity(token); 2115 } 2116 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 2117 // App is blacklisted. 2118 return RESTRICT_BACKGROUND_STATUS_ENABLED; 2119 } 2120 if (!mRestrictBackground) { 2121 return RESTRICT_BACKGROUND_STATUS_DISABLED; 2122 } 2123 return mRestrictBackgroundWhitelistUids.get(uid) 2124 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 2125 : RESTRICT_BACKGROUND_STATUS_ENABLED; 2126 } 2127 } 2128 2129 @Override 2130 public boolean getRestrictBackground() { 2131 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2132 2133 synchronized (mRulesLock) { 2134 return mRestrictBackground; 2135 } 2136 } 2137 2138 @Override 2139 public void setDeviceIdleMode(boolean enabled) { 2140 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2141 2142 synchronized (mRulesLock) { 2143 if (mDeviceIdleMode != enabled) { 2144 mDeviceIdleMode = enabled; 2145 if (mSystemReady) { 2146 // Device idle change means we need to rebuild rules for all 2147 // known apps, so do a global refresh. 2148 updateRulesForGlobalChangeLocked(false); 2149 } 2150 if (enabled) { 2151 EventLogTags.writeDeviceIdleOnPhase("net"); 2152 } else { 2153 EventLogTags.writeDeviceIdleOffPhase("net"); 2154 } 2155 } 2156 } 2157 } 2158 2159 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 2160 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2161 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2162 if (policy.template.matches(ident)) { 2163 return policy; 2164 } 2165 } 2166 return null; 2167 } 2168 2169 @Override 2170 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 2171 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2172 2173 // only returns usage summary, so we don't require caller to have 2174 // READ_NETWORK_USAGE_HISTORY. 2175 final long token = Binder.clearCallingIdentity(); 2176 try { 2177 return getNetworkQuotaInfoUnchecked(state); 2178 } finally { 2179 Binder.restoreCallingIdentity(token); 2180 } 2181 } 2182 2183 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 2184 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2185 2186 final NetworkPolicy policy; 2187 synchronized (mRulesLock) { 2188 policy = findPolicyForNetworkLocked(ident); 2189 } 2190 2191 if (policy == null || !policy.hasCycle()) { 2192 // missing policy means we can't derive useful quota info 2193 return null; 2194 } 2195 2196 final long currentTime = currentTimeMillis(); 2197 2198 // find total bytes used under policy 2199 final long start = computeLastCycleBoundary(currentTime, policy); 2200 final long end = currentTime; 2201 final long totalBytes = getTotalBytes(policy.template, start, end); 2202 2203 // report soft and hard limits under policy 2204 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 2205 : NetworkQuotaInfo.NO_LIMIT; 2206 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 2207 : NetworkQuotaInfo.NO_LIMIT; 2208 2209 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 2210 } 2211 2212 @Override 2213 public boolean isNetworkMetered(NetworkState state) { 2214 if (state.networkInfo == null) { 2215 return false; 2216 } 2217 2218 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2219 2220 // roaming networks are always considered metered 2221 if (ident.getRoaming()) { 2222 return true; 2223 } 2224 2225 final NetworkPolicy policy; 2226 synchronized (mRulesLock) { 2227 policy = findPolicyForNetworkLocked(ident); 2228 } 2229 2230 if (policy != null) { 2231 return policy.metered; 2232 } else { 2233 final int type = state.networkInfo.getType(); 2234 if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 2235 return true; 2236 } 2237 return false; 2238 } 2239 } 2240 2241 @Override 2242 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2243 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 2244 2245 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 2246 2247 final ArraySet<String> argSet = new ArraySet<String>(args.length); 2248 for (String arg : args) { 2249 argSet.add(arg); 2250 } 2251 2252 synchronized (mRulesLock) { 2253 if (argSet.contains("--unsnooze")) { 2254 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2255 mNetworkPolicy.valueAt(i).clearSnooze(); 2256 } 2257 2258 normalizePoliciesLocked(); 2259 updateNetworkEnabledLocked(); 2260 updateNetworkRulesLocked(); 2261 updateNotificationsLocked(); 2262 writePolicyLocked(); 2263 2264 fout.println("Cleared snooze timestamps"); 2265 return; 2266 } 2267 2268 fout.print("System ready: "); fout.println(mSystemReady); 2269 fout.print("Restrict background: "); fout.println(mRestrictBackground); 2270 fout.print("Restrict power: "); fout.println(mRestrictPower); 2271 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 2272 fout.println("Network policies:"); 2273 fout.increaseIndent(); 2274 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2275 fout.println(mNetworkPolicy.valueAt(i).toString()); 2276 } 2277 fout.decreaseIndent(); 2278 2279 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 2280 2281 fout.println("Policy for UIDs:"); 2282 fout.increaseIndent(); 2283 int size = mUidPolicy.size(); 2284 for (int i = 0; i < size; i++) { 2285 final int uid = mUidPolicy.keyAt(i); 2286 final int policy = mUidPolicy.valueAt(i); 2287 fout.print("UID="); 2288 fout.print(uid); 2289 fout.print(" policy="); 2290 fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy)); 2291 fout.println(); 2292 } 2293 fout.decreaseIndent(); 2294 2295 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2296 if (size > 0) { 2297 fout.println("Power save whitelist (except idle) app ids:"); 2298 fout.increaseIndent(); 2299 for (int i = 0; i < size; i++) { 2300 fout.print("UID="); 2301 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2302 fout.print(": "); 2303 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 2304 fout.println(); 2305 } 2306 fout.decreaseIndent(); 2307 } 2308 2309 size = mPowerSaveWhitelistAppIds.size(); 2310 if (size > 0) { 2311 fout.println("Power save whitelist app ids:"); 2312 fout.increaseIndent(); 2313 for (int i = 0; i < size; i++) { 2314 fout.print("UID="); 2315 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 2316 fout.print(": "); 2317 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 2318 fout.println(); 2319 } 2320 fout.decreaseIndent(); 2321 } 2322 2323 size = mRestrictBackgroundWhitelistUids.size(); 2324 if (size > 0) { 2325 fout.println("Restrict background whitelist uids:"); 2326 fout.increaseIndent(); 2327 for (int i = 0; i < size; i++) { 2328 fout.print("UID="); 2329 fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); 2330 fout.println(); 2331 } 2332 fout.decreaseIndent(); 2333 } 2334 2335 size = mDefaultRestrictBackgroundWhitelistUids.size(); 2336 if (size > 0) { 2337 fout.println("Default restrict background whitelist uids:"); 2338 fout.increaseIndent(); 2339 for (int i = 0; i < size; i++) { 2340 fout.print("UID="); 2341 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); 2342 fout.println(); 2343 } 2344 fout.decreaseIndent(); 2345 } 2346 2347 size = mRestrictBackgroundWhitelistRevokedUids.size(); 2348 if (size > 0) { 2349 fout.println("Default restrict background whitelist uids revoked by users:"); 2350 fout.increaseIndent(); 2351 for (int i = 0; i < size; i++) { 2352 fout.print("UID="); 2353 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); 2354 fout.println(); 2355 } 2356 fout.decreaseIndent(); 2357 } 2358 2359 final SparseBooleanArray knownUids = new SparseBooleanArray(); 2360 collectKeys(mUidState, knownUids); 2361 collectKeys(mUidRules, knownUids); 2362 2363 fout.println("Status for all known UIDs:"); 2364 fout.increaseIndent(); 2365 size = knownUids.size(); 2366 for (int i = 0; i < size; i++) { 2367 final int uid = knownUids.keyAt(i); 2368 fout.print("UID="); 2369 fout.print(uid); 2370 2371 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2372 fout.print(" state="); 2373 fout.print(state); 2374 if (state <= ActivityManager.PROCESS_STATE_TOP) { 2375 fout.print(" (fg)"); 2376 } else { 2377 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 2378 ? " (fg svc)" : " (bg)"); 2379 } 2380 2381 final int uidRules = mUidRules.get(uid, RULE_NONE); 2382 fout.print(" rules="); 2383 fout.print(uidRulesToString(uidRules)); 2384 fout.println(); 2385 } 2386 fout.decreaseIndent(); 2387 2388 fout.println("Status for just UIDs with rules:"); 2389 fout.increaseIndent(); 2390 size = mUidRules.size(); 2391 for (int i = 0; i < size; i++) { 2392 final int uid = mUidRules.keyAt(i); 2393 fout.print("UID="); 2394 fout.print(uid); 2395 final int uidRules = mUidRules.get(uid, RULE_NONE); 2396 fout.print(" rules="); 2397 fout.print(uidRulesToString(uidRules)); 2398 fout.println(); 2399 } 2400 fout.decreaseIndent(); 2401 } 2402 } 2403 2404 @Override 2405 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2406 String[] args, ResultReceiver resultReceiver) throws RemoteException { 2407 (new NetworkPolicyManagerShellCommand(mContext, this)).exec( 2408 this, in, out, err, args, resultReceiver); 2409 } 2410 2411 @Override 2412 public boolean isUidForeground(int uid) { 2413 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2414 2415 synchronized (mRulesLock) { 2416 return isUidForegroundLocked(uid); 2417 } 2418 } 2419 2420 private boolean isUidForegroundLocked(int uid) { 2421 return isUidStateForegroundLocked( 2422 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2423 } 2424 2425 private boolean isUidForegroundOnRestrictBackgroundLocked(int uid) { 2426 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2427 return isProcStateAllowedWhileOnRestrictBackgroundLocked(procState); 2428 } 2429 2430 private boolean isUidForegroundOnRestrictPowerLocked(int uid) { 2431 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2432 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState); 2433 } 2434 2435 private boolean isUidStateForegroundLocked(int state) { 2436 // only really in foreground when screen is also on 2437 return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP; 2438 } 2439 2440 /** 2441 * Process state of UID changed; if needed, will trigger 2442 * {@link #updateRulesForDataUsageRestrictionsLocked(int)} and 2443 * {@link #updateRulesForPowerRestrictionsLocked(int)} 2444 */ 2445 private void updateUidStateLocked(int uid, int uidState) { 2446 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2447 if (oldUidState != uidState) { 2448 // state changed, push updated rules 2449 mUidState.put(uid, uidState); 2450 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState); 2451 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 2452 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) { 2453 if (isUidIdle(uid)) { 2454 updateRuleForAppIdleLocked(uid); 2455 } 2456 if (mDeviceIdleMode) { 2457 updateRuleForDeviceIdleLocked(uid); 2458 } 2459 if (mRestrictPower) { 2460 updateRuleForRestrictPowerLocked(uid); 2461 } 2462 updateRulesForPowerRestrictionsLocked(uid); 2463 } 2464 updateNetworkStats(uid, isUidStateForegroundLocked(uidState)); 2465 } 2466 } 2467 2468 private void removeUidStateLocked(int uid) { 2469 final int index = mUidState.indexOfKey(uid); 2470 if (index >= 0) { 2471 final int oldUidState = mUidState.valueAt(index); 2472 mUidState.removeAt(index); 2473 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2474 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, 2475 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2476 if (mDeviceIdleMode) { 2477 updateRuleForDeviceIdleLocked(uid); 2478 } 2479 if (mRestrictPower) { 2480 updateRuleForRestrictPowerLocked(uid); 2481 } 2482 updateRulesForPowerRestrictionsLocked(uid); 2483 updateNetworkStats(uid, false); 2484 } 2485 } 2486 } 2487 2488 // adjust stats accounting based on foreground status 2489 private void updateNetworkStats(int uid, boolean uidForeground) { 2490 try { 2491 mNetworkStats.setUidForeground(uid, uidForeground); 2492 } catch (RemoteException e) { 2493 // ignored; service lives in system_server 2494 } 2495 } 2496 2497 private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState, 2498 int newUidState) { 2499 final boolean oldForeground = 2500 isProcStateAllowedWhileOnRestrictBackgroundLocked(oldUidState); 2501 final boolean newForeground = 2502 isProcStateAllowedWhileOnRestrictBackgroundLocked(newUidState); 2503 if (oldForeground != newForeground) { 2504 updateRulesForDataUsageRestrictionsLocked(uid); 2505 } 2506 } 2507 2508 private void updateScreenOn() { 2509 synchronized (mRulesLock) { 2510 try { 2511 mScreenOn = mPowerManager.isInteractive(); 2512 } catch (RemoteException e) { 2513 // ignored; service lives in system_server 2514 } 2515 updateRulesForScreenLocked(); 2516 } 2517 } 2518 2519 /** 2520 * Update rules that might be changed by {@link #mScreenOn} value. 2521 */ 2522 private void updateRulesForScreenLocked() { 2523 // only update rules for anyone with foreground activities 2524 final int size = mUidState.size(); 2525 for (int i = 0; i < size; i++) { 2526 if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 2527 final int uid = mUidState.keyAt(i); 2528 updateRestrictionRulesForUidLocked(uid); 2529 } 2530 } 2531 } 2532 2533 static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) { 2534 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2535 } 2536 2537 static boolean isProcStateAllowedWhileOnRestrictBackgroundLocked(int procState) { 2538 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2539 } 2540 2541 void updateRulesForRestrictPowerLocked() { 2542 updateRulesForWhitelistedPowerSaveLocked(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 2543 mUidFirewallPowerSaveRules); 2544 } 2545 2546 void updateRuleForRestrictPowerLocked(int uid) { 2547 updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2548 } 2549 2550 void updateRulesForDeviceIdleLocked() { 2551 updateRulesForWhitelistedPowerSaveLocked(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 2552 mUidFirewallDozableRules); 2553 } 2554 2555 void updateRuleForDeviceIdleLocked(int uid) { 2556 updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 2557 } 2558 2559 // NOTE: since both fw_dozable and fw_powersave uses the same map 2560 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2561 private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain, 2562 SparseIntArray rules) { 2563 if (enabled) { 2564 // Sync the whitelists before enabling the chain. We don't care about the rules if 2565 // we are disabling the chain. 2566 final SparseIntArray uidRules = rules; 2567 uidRules.clear(); 2568 final List<UserInfo> users = mUserManager.getUsers(); 2569 for (int ui = users.size() - 1; ui >= 0; ui--) { 2570 UserInfo user = users.get(ui); 2571 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2572 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) { 2573 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2574 int uid = UserHandle.getUid(user.id, appId); 2575 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2576 } 2577 } 2578 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { 2579 int appId = mPowerSaveWhitelistAppIds.keyAt(i); 2580 int uid = UserHandle.getUid(user.id, appId); 2581 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2582 } 2583 } 2584 for (int i = mUidState.size() - 1; i >= 0; i--) { 2585 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 2586 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2587 } 2588 } 2589 setUidFirewallRules(chain, uidRules); 2590 } 2591 2592 enableFirewallChainLocked(chain, enabled); 2593 } 2594 2595 private void updateRulesForNonMeteredNetworksLocked() { 2596 2597 } 2598 2599 private boolean isWhitelistedBatterySaverLocked(int uid) { 2600 final int appId = UserHandle.getAppId(uid); 2601 return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); 2602 } 2603 2604 // NOTE: since both fw_dozable and fw_powersave uses the same map 2605 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2606 private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) { 2607 if (enabled) { 2608 if (isWhitelistedBatterySaverLocked(uid) 2609 || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) { 2610 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 2611 } else { 2612 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 2613 } 2614 } 2615 } 2616 2617 void updateRulesForAppIdleLocked() { 2618 final SparseIntArray uidRules = mUidFirewallStandbyRules; 2619 uidRules.clear(); 2620 2621 // Fully update the app idle firewall chain. 2622 final List<UserInfo> users = mUserManager.getUsers(); 2623 for (int ui = users.size() - 1; ui >= 0; ui--) { 2624 UserInfo user = users.get(ui); 2625 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2626 for (int uid : idleUids) { 2627 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2628 // quick check: if this uid doesn't have INTERNET permission, it 2629 // doesn't have network access anyway, so it is a waste to mess 2630 // with it here. 2631 if (hasInternetPermissions(uid)) { 2632 uidRules.put(uid, FIREWALL_RULE_DENY); 2633 } 2634 } 2635 } 2636 } 2637 2638 setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); 2639 } 2640 2641 void updateRuleForAppIdleLocked(int uid) { 2642 if (!isUidValidForBlacklistRules(uid)) return; 2643 2644 int appId = UserHandle.getAppId(uid); 2645 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) 2646 && !isUidForegroundOnRestrictPowerLocked(uid)) { 2647 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2648 } else { 2649 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2650 } 2651 } 2652 2653 void updateRulesForAppIdleParoleLocked() { 2654 boolean enableChain = !mUsageStats.isAppIdleParoleOn(); 2655 enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); 2656 } 2657 2658 /** 2659 * Update rules that might be changed by {@link #mRestrictBackground}, 2660 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 2661 */ 2662 private void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) { 2663 long start; 2664 if (LOGD) start = System.currentTimeMillis(); 2665 2666 updateRulesForDeviceIdleLocked(); 2667 updateRulesForAppIdleLocked(); 2668 updateRulesForRestrictPowerLocked(); 2669 updateRulesForRestrictBackgroundLocked(); 2670 setRestrictBackgroundLocked(mRestrictBackground); 2671 2672 // If the set of restricted networks may have changed, re-evaluate those. 2673 if (restrictedNetworksChanged) { 2674 normalizePoliciesLocked(); 2675 updateNetworkRulesLocked(); 2676 } 2677 if (LOGD) { 2678 final long delta = System.currentTimeMillis() - start; 2679 Slog.d(TAG, "updateRulesForGlobalChangeLocked(" + restrictedNetworksChanged + ") took " 2680 + delta + "ms"); 2681 } 2682 } 2683 2684 private void updateRulesForRestrictBackgroundLocked() { 2685 final PackageManager pm = mContext.getPackageManager(); 2686 2687 // update rules for all installed applications 2688 final List<UserInfo> users = mUserManager.getUsers(); 2689 final List<ApplicationInfo> apps = pm.getInstalledApplications( 2690 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS 2691 | PackageManager.MATCH_DIRECT_BOOT_AWARE 2692 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2693 2694 final int usersSize = users.size(); 2695 final int appsSize = apps.size(); 2696 for (int i = 0; i < usersSize; i++) { 2697 final UserInfo user = users.get(i); 2698 for (int j = 0; j < appsSize; j++) { 2699 final ApplicationInfo app = apps.get(j); 2700 final int uid = UserHandle.getUid(user.id, app.uid); 2701 updateRulesForDataUsageRestrictionsLocked(uid); 2702 updateRulesForPowerRestrictionsLocked(uid); 2703 } 2704 } 2705 } 2706 2707 private void updateRulesForTempWhitelistChangeLocked() { 2708 final List<UserInfo> users = mUserManager.getUsers(); 2709 for (int i = 0; i < users.size(); i++) { 2710 final UserInfo user = users.get(i); 2711 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { 2712 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); 2713 int uid = UserHandle.getUid(user.id, appId); 2714 // Update external firewall rules. 2715 updateRuleForAppIdleLocked(uid); 2716 updateRuleForDeviceIdleLocked(uid); 2717 updateRuleForRestrictPowerLocked(uid); 2718 // Update internal rules. 2719 updateRulesForPowerRestrictionsLocked(uid); 2720 } 2721 } 2722 } 2723 2724 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 2725 // methods below could be merged into a isUidValidForRules() method. 2726 private boolean isUidValidForBlacklistRules(int uid) { 2727 // allow rules on specific system services, and any apps 2728 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 2729 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) { 2730 return true; 2731 } 2732 2733 return false; 2734 } 2735 2736 private boolean isUidValidForWhitelistRules(int uid) { 2737 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 2738 } 2739 2740 private boolean isUidIdle(int uid) { 2741 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 2742 final int userId = UserHandle.getUserId(uid); 2743 2744 if (!ArrayUtils.isEmpty(packages)) { 2745 for (String packageName : packages) { 2746 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 2747 return false; 2748 } 2749 } 2750 } 2751 return true; 2752 } 2753 2754 /** 2755 * Checks if an uid has INTERNET permissions. 2756 * <p> 2757 * Useful for the cases where the lack of network access can simplify the rules. 2758 */ 2759 private boolean hasInternetPermissions(int uid) { 2760 try { 2761 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) 2762 != PackageManager.PERMISSION_GRANTED) { 2763 return false; 2764 } 2765 } catch (RemoteException e) { 2766 } 2767 return true; 2768 } 2769 2770 /** 2771 * Applies network rules to bandwidth and firewall controllers based on uid policy. 2772 * 2773 * <p>There are currently 4 types of restriction rules: 2774 * <ul> 2775 * <li>Doze mode 2776 * <li>App idle mode 2777 * <li>Battery Saver Mode (also referred as power save). 2778 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data'). 2779 * </ul> 2780 * 2781 * <p>This method changes both the external firewall rules and the internal state. 2782 */ 2783 private void updateRestrictionRulesForUidLocked(int uid) { 2784 // Methods below only changes the firewall rules for the power-related modes. 2785 updateRuleForDeviceIdleLocked(uid); 2786 updateRuleForAppIdleLocked(uid); 2787 updateRuleForRestrictPowerLocked(uid); 2788 2789 // Update internal state for power-related modes. 2790 updateRulesForPowerRestrictionsLocked(uid); 2791 2792 // Update firewall and internal rules for Data Saver Mode. 2793 updateRulesForDataUsageRestrictionsLocked(uid); 2794 } 2795 2796 /** 2797 * Applies network rules to bandwidth controllers based on process state and user-defined 2798 * restrictions (blacklist / whitelist). 2799 * 2800 * <p> 2801 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 2802 * networks: 2803 * <ul> 2804 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). 2805 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're 2806 * also blacklisted. 2807 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 2808 * no UIDs other those whitelisted will have access. 2809 * <ul> 2810 * 2811 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 2812 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / 2813 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist 2814 * respectively): these methods set the proper internal state (blacklist / whitelist), then call 2815 * this ({@link #updateRulesForDataUsageRestrictionsLocked(int)}) to propagate the rules to 2816 * {@link INetworkManagementService}, but this method should also be called in events (like 2817 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 2818 * following rules should also be applied: 2819 * 2820 * <ul> 2821 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 2822 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 2823 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from 2824 * {@code bw_penalty_box}. 2825 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 2826 * </ul> 2827 * 2828 * <p>For optimization, the rules are only applied on user apps that have internet access 2829 * permission, since there is no need to change the {@code iptables} rule if the app does not 2830 * have permission to use the internet. 2831 * 2832 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID. 2833 * 2834 */ 2835 private void updateRulesForDataUsageRestrictionsLocked(int uid) { 2836 updateRulesForDataUsageRestrictionsLocked(uid, false); 2837 } 2838 2839 /** 2840 * Overloaded version of {@link #updateRulesForDataUsageRestrictionsLocked(int)} called when an 2841 * app is removed - it ignores the UID validity check. 2842 */ 2843 private void updateRulesForDataUsageRestrictionsLocked(int uid, boolean uidDeleted) { 2844 if (!uidDeleted && !isUidValidForWhitelistRules(uid)) { 2845 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 2846 return; 2847 } 2848 2849 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2850 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2851 final boolean isForeground = isUidForegroundOnRestrictBackgroundLocked(uid); 2852 2853 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 2854 final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid); 2855 final int oldRule = oldUidRules & MASK_METERED_NETWORKS; 2856 int newRule = RULE_NONE; 2857 2858 // First step: define the new rule based on user restrictions and foreground state. 2859 if (isForeground) { 2860 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { 2861 newRule = RULE_TEMPORARY_ALLOW_METERED; 2862 } else if (isWhitelisted) { 2863 newRule = RULE_ALLOW_METERED; 2864 } 2865 } else { 2866 if (isBlacklisted) { 2867 newRule = RULE_REJECT_METERED; 2868 } else if (mRestrictBackground && isWhitelisted) { 2869 newRule = RULE_ALLOW_METERED; 2870 } 2871 } 2872 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS); 2873 2874 if (LOGV) { 2875 Log.v(TAG, "updateRuleForRestrictBackgroundLocked(" + uid + ")" 2876 + ": isForeground=" +isForeground 2877 + ", isBlacklisted=" + isBlacklisted 2878 + ", isWhitelisted=" + isWhitelisted 2879 + ", oldRule=" + uidRulesToString(oldRule) 2880 + ", newRule=" + uidRulesToString(newRule) 2881 + ", newUidRules=" + uidRulesToString(newUidRules) 2882 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 2883 } 2884 2885 if (newUidRules == RULE_NONE) { 2886 mUidRules.delete(uid); 2887 } else { 2888 mUidRules.put(uid, newUidRules); 2889 } 2890 2891 boolean changed = false; 2892 2893 // Second step: apply bw changes based on change of state. 2894 if (newRule != oldRule) { 2895 changed = true; 2896 2897 if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2898 // Temporarily whitelist foreground app, removing from blacklist if necessary 2899 // (since bw_penalty_box prevails over bw_happy_box). 2900 2901 setMeteredNetworkWhitelist(uid, true); 2902 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, 2903 // but ideally it should be just: 2904 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2905 if (isBlacklisted) { 2906 setMeteredNetworkBlacklist(uid, false); 2907 } 2908 } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2909 // Remove temporary whitelist from app that is not on foreground anymore. 2910 2911 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, 2912 // but ideally they should be just: 2913 // setMeteredNetworkWhitelist(uid, isWhitelisted); 2914 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2915 if (!isWhitelisted) { 2916 setMeteredNetworkWhitelist(uid, false); 2917 } 2918 if (isBlacklisted) { 2919 setMeteredNetworkBlacklist(uid, true); 2920 } 2921 } else if ((newRule & RULE_REJECT_METERED) != 0 2922 || (oldRule & RULE_REJECT_METERED) != 0) { 2923 // Flip state because app was explicitly added or removed to blacklist. 2924 setMeteredNetworkBlacklist(uid, isBlacklisted); 2925 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) { 2926 // Since blacklist prevails over whitelist, we need to handle the special case 2927 // where app is whitelisted and blacklisted at the same time (although such 2928 // scenario should be blocked by the UI), then blacklist is removed. 2929 setMeteredNetworkWhitelist(uid, isWhitelisted); 2930 } 2931 } else if ((newRule & RULE_ALLOW_METERED) != 0 2932 || (oldRule & RULE_ALLOW_METERED) != 0) { 2933 // Flip state because app was explicitly added or removed to whitelist. 2934 setMeteredNetworkWhitelist(uid, isWhitelisted); 2935 } else { 2936 // All scenarios should have been covered above. 2937 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid 2938 + ": foreground=" + isForeground 2939 + ", whitelisted=" + isWhitelisted 2940 + ", blacklisted=" + isBlacklisted 2941 + ", newRule=" + uidRulesToString(newUidRules) 2942 + ", oldRule=" + uidRulesToString(oldUidRules)); 2943 } 2944 2945 // Dispatch changed rule to existing listeners. 2946 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 2947 } 2948 } 2949 2950 /** 2951 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external 2952 * listeners in case of change. 2953 * <p> 2954 * There are 3 power-related rules that affects whether an app has background access on 2955 * non-metered networks, and when the condition applies and the UID is not whitelisted for power 2956 * restriction, it's added to the equivalent firewall chain: 2957 * <ul> 2958 * <li>App is idle: {@code fw_standby} firewall chain. 2959 * <li>Device is idle: {@code fw_dozable} firewall chain. 2960 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain. 2961 * </ul> 2962 * <p> 2963 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on 2964 * these modes, the UID process state (foreground or not), and the UIDwhitelist state. 2965 * <p> 2966 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}. 2967 */ 2968 private void updateRulesForPowerRestrictionsLocked(int uid) { 2969 if (!isUidValidForBlacklistRules(uid)) { 2970 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); 2971 return; 2972 } 2973 2974 final boolean isIdle = isUidIdle(uid); 2975 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; 2976 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2977 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2978 final boolean isForeground = isUidForegroundOnRestrictPowerLocked(uid); 2979 2980 final boolean isWhitelisted = isWhitelistedBatterySaverLocked(uid); 2981 final int oldRule = oldUidRules & MASK_ALL_NETWORKS; 2982 int newRule = RULE_NONE; 2983 2984 // First step: define the new rule based on user restrictions and foreground state. 2985 2986 // NOTE: if statements below could be inlined, but it's easier to understand the logic 2987 // by considering the foreground and non-foreground states. 2988 if (isForeground) { 2989 if (restrictMode) { 2990 newRule = RULE_ALLOW_ALL; 2991 } 2992 } else if (restrictMode) { 2993 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL; 2994 } 2995 2996 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule; 2997 2998 if (LOGV) { 2999 Log.v(TAG, "updateRulesForNonMeteredNetworksLocked(" + uid + ")" 3000 + ", isIdle: " + isIdle 3001 + ", mRestrictPower: " + mRestrictPower 3002 + ", mDeviceIdleMode: " + mDeviceIdleMode 3003 + ", isForeground=" + isForeground 3004 + ", isWhitelisted=" + isWhitelisted 3005 + ", oldRule=" + uidRulesToString(oldRule) 3006 + ", newRule=" + uidRulesToString(newRule) 3007 + ", newUidRules=" + uidRulesToString(newUidRules) 3008 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 3009 } 3010 3011 if (newUidRules == RULE_NONE) { 3012 mUidRules.delete(uid); 3013 } else { 3014 mUidRules.put(uid, newUidRules); 3015 } 3016 3017 // Second step: notify listeners if state changed. 3018 if (newRule != oldRule) { 3019 if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) { 3020 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid); 3021 } else if ((newRule & RULE_REJECT_ALL) != 0) { 3022 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid); 3023 } else { 3024 // All scenarios should have been covered above 3025 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid 3026 + ": foreground=" + isForeground 3027 + ", whitelisted=" + isWhitelisted 3028 + ", newRule=" + uidRulesToString(newUidRules) 3029 + ", oldRule=" + uidRulesToString(oldUidRules)); 3030 } 3031 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 3032 } 3033 } 3034 3035 private class AppIdleStateChangeListener 3036 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 3037 3038 @Override 3039 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 3040 try { 3041 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 3042 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 3043 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle); 3044 synchronized (mRulesLock) { 3045 updateRuleForAppIdleLocked(uid); 3046 updateRulesForPowerRestrictionsLocked(uid); 3047 } 3048 } catch (NameNotFoundException nnfe) { 3049 } 3050 } 3051 3052 @Override 3053 public void onParoleStateChanged(boolean isParoleOn) { 3054 synchronized (mRulesLock) { 3055 updateRulesForAppIdleParoleLocked(); 3056 } 3057 } 3058 } 3059 3060 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { 3061 if (listener != null) { 3062 try { 3063 listener.onUidRulesChanged(uid, uidRules); 3064 } catch (RemoteException ignored) { 3065 } 3066 } 3067 } 3068 3069 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, 3070 String[] meteredIfaces) { 3071 if (listener != null) { 3072 try { 3073 listener.onMeteredIfacesChanged(meteredIfaces); 3074 } catch (RemoteException ignored) { 3075 } 3076 } 3077 } 3078 3079 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, 3080 boolean restrictBackground) { 3081 if (listener != null) { 3082 try { 3083 listener.onRestrictBackgroundChanged(restrictBackground); 3084 } catch (RemoteException ignored) { 3085 } 3086 } 3087 } 3088 3089 private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener, 3090 int uid, boolean whitelisted) { 3091 if (listener != null) { 3092 try { 3093 listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted); 3094 } catch (RemoteException ignored) { 3095 } 3096 } 3097 } 3098 3099 private Handler.Callback mHandlerCallback = new Handler.Callback() { 3100 @Override 3101 public boolean handleMessage(Message msg) { 3102 switch (msg.what) { 3103 case MSG_RULES_CHANGED: { 3104 final int uid = msg.arg1; 3105 final int uidRules = msg.arg2; 3106 dispatchUidRulesChanged(mConnectivityListener, uid, uidRules); 3107 final int length = mListeners.beginBroadcast(); 3108 for (int i = 0; i < length; i++) { 3109 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3110 dispatchUidRulesChanged(listener, uid, uidRules); 3111 } 3112 mListeners.finishBroadcast(); 3113 return true; 3114 } 3115 case MSG_METERED_IFACES_CHANGED: { 3116 final String[] meteredIfaces = (String[]) msg.obj; 3117 dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces); 3118 final int length = mListeners.beginBroadcast(); 3119 for (int i = 0; i < length; i++) { 3120 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3121 dispatchMeteredIfacesChanged(listener, meteredIfaces); 3122 } 3123 mListeners.finishBroadcast(); 3124 return true; 3125 } 3126 case MSG_LIMIT_REACHED: { 3127 final String iface = (String) msg.obj; 3128 3129 maybeRefreshTrustedTime(); 3130 synchronized (mRulesLock) { 3131 if (mMeteredIfaces.contains(iface)) { 3132 try { 3133 // force stats update to make sure we have 3134 // numbers that caused alert to trigger. 3135 mNetworkStats.forceUpdate(); 3136 } catch (RemoteException e) { 3137 // ignored; service lives in system_server 3138 } 3139 3140 updateNetworkEnabledLocked(); 3141 updateNotificationsLocked(); 3142 } 3143 } 3144 return true; 3145 } 3146 case MSG_RESTRICT_BACKGROUND_CHANGED: { 3147 final boolean restrictBackground = msg.arg1 != 0; 3148 dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground); 3149 final int length = mListeners.beginBroadcast(); 3150 for (int i = 0; i < length; i++) { 3151 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3152 dispatchRestrictBackgroundChanged(listener, restrictBackground); 3153 } 3154 mListeners.finishBroadcast(); 3155 final Intent intent = 3156 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3157 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3158 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3159 return true; 3160 } 3161 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { 3162 // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: 3163 // - when an app is whitelisted 3164 // - when an app is blacklisted 3165 // 3166 // Whether the internal listeners (INetworkPolicyListener implementations) or 3167 // app broadcast receivers are notified depend on the following rules: 3168 // 3169 // - App receivers are only notified when the app status changed (msg.arg2 = 1) 3170 // - Listeners are only notified when app was whitelisted (msg.obj is not null), 3171 // since blacklist notifications are handled through MSG_RULES_CHANGED). 3172 final int uid = msg.arg1; 3173 final boolean changed = msg.arg2 == 1; 3174 final Boolean whitelisted = (Boolean) msg.obj; 3175 3176 // First notify internal listeners... 3177 if (whitelisted != null) { 3178 final boolean whitelistedBool = whitelisted.booleanValue(); 3179 dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid, 3180 whitelistedBool); 3181 final int length = mListeners.beginBroadcast(); 3182 for (int i = 0; i < length; i++) { 3183 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3184 dispatchRestrictBackgroundWhitelistChanged(listener, uid, 3185 whitelistedBool); 3186 } 3187 mListeners.finishBroadcast(); 3188 } 3189 3190 final PackageManager pm = mContext.getPackageManager(); 3191 final String[] packages = pm.getPackagesForUid(uid); 3192 if (changed && packages != null) { 3193 // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 3194 final int userId = UserHandle.getUserId(uid); 3195 for (String packageName : packages) { 3196 final Intent intent = new Intent( 3197 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3198 intent.setPackage(packageName); 3199 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3200 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 3201 } 3202 } 3203 return true; 3204 } 3205 case MSG_ADVISE_PERSIST_THRESHOLD: { 3206 final long lowestRule = (Long) msg.obj; 3207 try { 3208 // make sure stats are recorded frequently enough; we aim 3209 // for 2MB threshold for 2GB/month rules. 3210 final long persistThreshold = lowestRule / 1000; 3211 mNetworkStats.advisePersistThreshold(persistThreshold); 3212 } catch (RemoteException e) { 3213 // ignored; service lives in system_server 3214 } 3215 return true; 3216 } 3217 case MSG_SCREEN_ON_CHANGED: { 3218 updateScreenOn(); 3219 return true; 3220 } 3221 case MSG_UPDATE_INTERFACE_QUOTA: { 3222 removeInterfaceQuota((String) msg.obj); 3223 // int params need to be stitched back into a long 3224 setInterfaceQuota((String) msg.obj, 3225 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); 3226 return true; 3227 } 3228 case MSG_REMOVE_INTERFACE_QUOTA: { 3229 removeInterfaceQuota((String) msg.obj); 3230 return true; 3231 } 3232 default: { 3233 return false; 3234 } 3235 } 3236 } 3237 }; 3238 3239 private void setInterfaceQuota(String iface, long quotaBytes) { 3240 try { 3241 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 3242 } catch (IllegalStateException e) { 3243 Log.wtf(TAG, "problem setting interface quota", e); 3244 } catch (RemoteException e) { 3245 // ignored; service lives in system_server 3246 } 3247 } 3248 3249 private void removeInterfaceQuota(String iface) { 3250 try { 3251 mNetworkManager.removeInterfaceQuota(iface); 3252 } catch (IllegalStateException e) { 3253 Log.wtf(TAG, "problem removing interface quota", e); 3254 } catch (RemoteException e) { 3255 // ignored; service lives in system_server 3256 } 3257 } 3258 3259 private void setMeteredNetworkBlacklist(int uid, boolean enable) { 3260 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); 3261 try { 3262 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); 3263 } catch (IllegalStateException e) { 3264 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); 3265 } catch (RemoteException e) { 3266 // ignored; service lives in system_server 3267 } 3268 } 3269 3270 private void setMeteredNetworkWhitelist(int uid, boolean enable) { 3271 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); 3272 try { 3273 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); 3274 } catch (IllegalStateException e) { 3275 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); 3276 } catch (RemoteException e) { 3277 // ignored; service lives in system_server 3278 } 3279 } 3280 3281 /** 3282 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 3283 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 3284 * specified here. 3285 */ 3286 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 3287 try { 3288 int size = uidRules.size(); 3289 int[] uids = new int[size]; 3290 int[] rules = new int[size]; 3291 for(int index = size - 1; index >= 0; --index) { 3292 uids[index] = uidRules.keyAt(index); 3293 rules[index] = uidRules.valueAt(index); 3294 } 3295 mNetworkManager.setFirewallUidRules(chain, uids, rules); 3296 } catch (IllegalStateException e) { 3297 Log.wtf(TAG, "problem setting firewall uid rules", e); 3298 } catch (RemoteException e) { 3299 // ignored; service lives in system_server 3300 } 3301 } 3302 3303 /** 3304 * Add or remove a uid to the firewall blacklist for all network ifaces. 3305 */ 3306 private void setUidFirewallRule(int chain, int uid, int rule) { 3307 if (chain == FIREWALL_CHAIN_DOZABLE) { 3308 mUidFirewallDozableRules.put(uid, rule); 3309 } else if (chain == FIREWALL_CHAIN_STANDBY) { 3310 mUidFirewallStandbyRules.put(uid, rule); 3311 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 3312 mUidFirewallPowerSaveRules.put(uid, rule); 3313 } 3314 3315 try { 3316 mNetworkManager.setFirewallUidRule(chain, uid, rule); 3317 } catch (IllegalStateException e) { 3318 Log.wtf(TAG, "problem setting firewall uid rules", e); 3319 } catch (RemoteException e) { 3320 // ignored; service lives in system_server 3321 } 3322 } 3323 3324 /** 3325 * Add or remove a uid to the firewall blacklist for all network ifaces. 3326 */ 3327 private void enableFirewallChainLocked(int chain, boolean enable) { 3328 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 3329 mFirewallChainStates.get(chain) == enable) { 3330 // All is the same, nothing to do. 3331 return; 3332 } 3333 mFirewallChainStates.put(chain, enable); 3334 try { 3335 mNetworkManager.setFirewallChainEnabled(chain, enable); 3336 } catch (IllegalStateException e) { 3337 Log.wtf(TAG, "problem enable firewall chain", e); 3338 } catch (RemoteException e) { 3339 // ignored; service lives in system_server 3340 } 3341 } 3342 3343 private long getTotalBytes(NetworkTemplate template, long start, long end) { 3344 try { 3345 return mNetworkStats.getNetworkTotalBytes(template, start, end); 3346 } catch (RuntimeException e) { 3347 Slog.w(TAG, "problem reading network stats: " + e); 3348 return 0; 3349 } catch (RemoteException e) { 3350 // ignored; service lives in system_server 3351 return 0; 3352 } 3353 } 3354 3355 private boolean isBandwidthControlEnabled() { 3356 final long token = Binder.clearCallingIdentity(); 3357 try { 3358 return mNetworkManager.isBandwidthControlEnabled(); 3359 } catch (RemoteException e) { 3360 // ignored; service lives in system_server 3361 return false; 3362 } finally { 3363 Binder.restoreCallingIdentity(token); 3364 } 3365 } 3366 3367 /** 3368 * Try refreshing {@link #mTime} when stale. 3369 */ 3370 void maybeRefreshTrustedTime() { 3371 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3372 mTime.forceRefresh(); 3373 } 3374 } 3375 3376 private long currentTimeMillis() { 3377 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3378 } 3379 3380 private static Intent buildAllowBackgroundDataIntent() { 3381 return new Intent(ACTION_ALLOW_BACKGROUND); 3382 } 3383 3384 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 3385 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 3386 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3387 return intent; 3388 } 3389 3390 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 3391 final Intent intent = new Intent(); 3392 intent.setComponent(new ComponentName( 3393 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 3394 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3395 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3396 return intent; 3397 } 3398 3399 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 3400 final Intent intent = new Intent(); 3401 intent.setComponent(new ComponentName( 3402 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 3403 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3404 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3405 return intent; 3406 } 3407 3408 @VisibleForTesting 3409 public void addIdleHandler(IdleHandler handler) { 3410 mHandler.getLooper().getQueue().addIdleHandler(handler); 3411 } 3412 3413 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3414 final int size = source.size(); 3415 for (int i = 0; i < size; i++) { 3416 target.put(source.keyAt(i), true); 3417 } 3418 } 3419 3420 @Override 3421 public void factoryReset(String subscriber) { 3422 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 3423 3424 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3425 return; 3426 } 3427 3428 // Turn mobile data limit off 3429 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 3430 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 3431 for (NetworkPolicy policy : policies) { 3432 if (policy.template.equals(template)) { 3433 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 3434 policy.inferred = false; 3435 policy.clearSnooze(); 3436 } 3437 } 3438 setNetworkPolicies(policies); 3439 3440 // Turn restrict background data off 3441 setRestrictBackground(false); 3442 3443 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 3444 // Remove app's "restrict background data" flag 3445 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 3446 setUidPolicy(uid, POLICY_NONE); 3447 } 3448 } 3449 } 3450 3451 private class MyPackageMonitor extends PackageMonitor { 3452 3453 @Override 3454 public void onPackageRemoved(String packageName, int uid) { 3455 if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); 3456 synchronized (mRulesLock) { 3457 removeRestrictBackgroundWhitelistedUidLocked(uid, true, true); 3458 updateRestrictionRulesForUidLocked(uid); 3459 } 3460 } 3461 } 3462 3463 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal { 3464 3465 @Override 3466 public void resetUserState(int userId) { 3467 synchronized (mRulesLock) { 3468 boolean changed = removeUserStateLocked(userId, false); 3469 changed = addDefaultRestrictBackgroundWhitelistUidsLocked(userId) || changed; 3470 if (changed) { 3471 writePolicyLocked(); 3472 } 3473 } 3474 } 3475 } 3476} 3477