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