1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.net; 18 19 import static android.Manifest.permission.ACCESS_NETWORK_STATE; 20 import static android.Manifest.permission.CONNECTIVITY_INTERNAL; 21 import static android.Manifest.permission.DUMP; 22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY; 23 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 24 import static android.Manifest.permission.READ_PHONE_STATE; 25 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 26 import static android.content.Intent.ACTION_PACKAGE_ADDED; 27 import static android.content.Intent.ACTION_UID_REMOVED; 28 import static android.content.Intent.ACTION_USER_ADDED; 29 import static android.content.Intent.ACTION_USER_REMOVED; 30 import static android.content.Intent.EXTRA_UID; 31 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 32 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 33 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 34 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; 35 import static android.net.ConnectivityManager.TYPE_MOBILE; 36 import static android.net.ConnectivityManager.TYPE_WIMAX; 37 import static android.net.ConnectivityManager.isNetworkTypeMobile; 38 import static android.net.NetworkPolicy.CYCLE_NONE; 39 import static android.net.NetworkPolicy.LIMIT_DISABLED; 40 import static android.net.NetworkPolicy.SNOOZE_NEVER; 41 import static android.net.NetworkPolicy.WARNING_DISABLED; 42 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 43 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; 44 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; 45 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; 46 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; 47 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 48 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; 49 import static android.net.NetworkPolicyManager.POLICY_NONE; 50 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 51 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 52 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 53 import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; 54 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; 55 import static android.net.NetworkPolicyManager.RULE_NONE; 56 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 57 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 58 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 59 import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 60 import static android.net.NetworkPolicyManager.uidRulesToString; 61 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 62 import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 63 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 64 import static android.net.NetworkTemplate.MATCH_WIFI; 65 import static android.net.NetworkTemplate.buildTemplateMobileAll; 66 import static android.net.TrafficStats.MB_IN_BYTES; 67 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 68 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 69 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 70 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 71 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 72 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 73 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 74 import static android.text.format.DateUtils.DAY_IN_MILLIS; 75 76 import static com.android.internal.util.ArrayUtils.appendInt; 77 import static com.android.internal.util.Preconditions.checkNotNull; 78 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 79 import static com.android.internal.util.XmlUtils.readIntAttribute; 80 import static com.android.internal.util.XmlUtils.readLongAttribute; 81 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 82 import static com.android.internal.util.XmlUtils.writeIntAttribute; 83 import static com.android.internal.util.XmlUtils.writeLongAttribute; 84 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 85 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 86 87 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 88 import static org.xmlpull.v1.XmlPullParser.END_TAG; 89 import static org.xmlpull.v1.XmlPullParser.START_TAG; 90 91 import android.Manifest; 92 import android.app.ActivityManager; 93 import android.app.AppGlobals; 94 import android.app.AppOpsManager; 95 import android.app.IActivityManager; 96 import android.app.INotificationManager; 97 import android.app.IUidObserver; 98 import android.app.Notification; 99 import android.app.PendingIntent; 100 import android.app.usage.UsageStatsManagerInternal; 101 import android.content.BroadcastReceiver; 102 import android.content.ComponentName; 103 import android.content.Context; 104 import android.content.Intent; 105 import android.content.IntentFilter; 106 import android.content.pm.ApplicationInfo; 107 import android.content.pm.IPackageManager; 108 import android.content.pm.PackageManager; 109 import android.content.pm.PackageManager.NameNotFoundException; 110 import android.content.pm.UserInfo; 111 import android.content.res.Resources; 112 import android.net.ConnectivityManager; 113 import android.net.IConnectivityManager; 114 import android.net.INetworkManagementEventObserver; 115 import android.net.INetworkPolicyListener; 116 import android.net.INetworkPolicyManager; 117 import android.net.INetworkStatsService; 118 import android.net.LinkProperties; 119 import android.net.NetworkIdentity; 120 import android.net.NetworkInfo; 121 import android.net.NetworkPolicy; 122 import android.net.NetworkPolicyManager; 123 import android.net.NetworkQuotaInfo; 124 import android.net.NetworkState; 125 import android.net.NetworkTemplate; 126 import android.net.wifi.WifiConfiguration; 127 import android.net.wifi.WifiInfo; 128 import android.net.wifi.WifiManager; 129 import android.os.Binder; 130 import android.os.Environment; 131 import android.os.Handler; 132 import android.os.HandlerThread; 133 import android.os.IDeviceIdleController; 134 import android.os.INetworkManagementService; 135 import android.os.IPowerManager; 136 import android.os.Message; 137 import android.os.MessageQueue.IdleHandler; 138 import android.os.PowerManager; 139 import android.os.PowerManagerInternal; 140 import android.os.RemoteCallbackList; 141 import android.os.RemoteException; 142 import android.os.ResultReceiver; 143 import android.os.ServiceManager; 144 import android.os.UserHandle; 145 import android.os.UserManager; 146 import android.provider.Settings; 147 import android.telephony.SubscriptionManager; 148 import android.telephony.TelephonyManager; 149 import android.text.format.Formatter; 150 import android.text.format.Time; 151 import android.util.ArrayMap; 152 import android.util.ArraySet; 153 import android.util.AtomicFile; 154 import android.util.DebugUtils; 155 import android.util.Log; 156 import android.util.NtpTrustedTime; 157 import android.util.Pair; 158 import android.util.Slog; 159 import android.util.SparseBooleanArray; 160 import android.util.SparseIntArray; 161 import android.util.TrustedTime; 162 import android.util.Xml; 163 164 import com.android.internal.R; 165 import com.android.internal.annotations.VisibleForTesting; 166 import com.android.internal.content.PackageMonitor; 167 import com.android.internal.util.ArrayUtils; 168 import com.android.internal.util.FastXmlSerializer; 169 import com.android.internal.util.IndentingPrintWriter; 170 import com.android.server.DeviceIdleController; 171 import com.android.server.EventLogTags; 172 import com.android.server.LocalServices; 173 import com.android.server.SystemConfig; 174 175 import libcore.io.IoUtils; 176 177 import com.google.android.collect.Lists; 178 179 import org.xmlpull.v1.XmlPullParser; 180 import org.xmlpull.v1.XmlPullParserException; 181 import org.xmlpull.v1.XmlSerializer; 182 183 import java.io.File; 184 import java.io.FileDescriptor; 185 import java.io.FileInputStream; 186 import java.io.FileNotFoundException; 187 import java.io.FileOutputStream; 188 import java.io.IOException; 189 import java.io.PrintWriter; 190 import java.nio.charset.StandardCharsets; 191 import java.util.ArrayList; 192 import java.util.Arrays; 193 import 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 */ 203 public 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 Slog.d(TAG, "setRestrictBackgroundLocked(): " + restrictBackground); 1993 final boolean oldRestrictBackground = mRestrictBackground; 1994 mRestrictBackground = restrictBackground; 1995 // Must whitelist foreground apps before turning data saver mode on. 1996 // TODO: there is no need to iterate through all apps here, just those in the foreground, 1997 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 1998 updateRulesForRestrictBackgroundLocked(); 1999 try { 2000 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 2001 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 2002 mRestrictBackground = oldRestrictBackground; 2003 // TODO: if it knew the foreground apps (see TODO above), it could call 2004 // updateRulesForRestrictBackgroundLocked() again to restore state. 2005 return; 2006 } 2007 } catch (RemoteException e) { 2008 // ignored; service lives in system_server 2009 } 2010 updateNotificationsLocked(); 2011 writePolicyLocked(); 2012 } 2013 2014 @Override 2015 public void addRestrictBackgroundWhitelistedUid(int uid) { 2016 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2017 final boolean oldStatus; 2018 final boolean needFirewallRules; 2019 synchronized (mRulesLock) { 2020 oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2021 if (oldStatus) { 2022 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); 2023 return; 2024 } 2025 needFirewallRules = isUidValidForWhitelistRules(uid); 2026 Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); 2027 mRestrictBackgroundWhitelistUids.append(uid, true); 2028 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2029 && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2030 if (LOGD) Slog.d(TAG, "Removing uid " + uid 2031 + " from revoked restrict background whitelist"); 2032 mRestrictBackgroundWhitelistRevokedUids.delete(uid); 2033 } 2034 if (needFirewallRules) { 2035 // Only update firewall rules if necessary... 2036 updateRulesForDataUsageRestrictionsLocked(uid); 2037 } 2038 // ...but always persists the whitelist request. 2039 writePolicyLocked(); 2040 } 2041 int changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; 2042 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, 2043 Boolean.TRUE).sendToTarget(); 2044 } 2045 2046 @Override 2047 public void removeRestrictBackgroundWhitelistedUid(int uid) { 2048 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2049 final boolean changed; 2050 synchronized (mRulesLock) { 2051 changed = removeRestrictBackgroundWhitelistedUidLocked(uid, false, true); 2052 } 2053 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, 2054 Boolean.FALSE).sendToTarget(); 2055 } 2056 2057 /** 2058 * Removes a uid from the restricted background whitelist, returning whether its current 2059 * {@link ConnectivityManager.RestrictBackgroundStatus} changed. 2060 */ 2061 private boolean removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean uidDeleted, 2062 boolean updateNow) { 2063 final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2064 if (!oldStatus && !uidDeleted) { 2065 if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before"); 2066 return false; 2067 } 2068 final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid); 2069 if (oldStatus) { 2070 Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); 2071 mRestrictBackgroundWhitelistUids.delete(uid); 2072 } 2073 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2074 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2075 if (LOGD) Slog.d(TAG, "Adding uid " + uid 2076 + " to revoked restrict background whitelist"); 2077 mRestrictBackgroundWhitelistRevokedUids.append(uid, true); 2078 } 2079 if (needFirewallRules) { 2080 // Only update firewall rules if necessary... 2081 updateRulesForDataUsageRestrictionsLocked(uid, uidDeleted); 2082 } 2083 if (updateNow) { 2084 // ...but always persists the whitelist request. 2085 writePolicyLocked(); 2086 } 2087 // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the 2088 // app was whitelisted before). 2089 return mRestrictBackground && needFirewallRules; 2090 } 2091 2092 @Override 2093 public int[] getRestrictBackgroundWhitelistedUids() { 2094 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2095 synchronized (mRulesLock) { 2096 final int size = mRestrictBackgroundWhitelistUids.size(); 2097 final int[] whitelist = new int[size]; 2098 for (int i = 0; i < size; i++) { 2099 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); 2100 } 2101 if (LOGV) { 2102 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " 2103 + mRestrictBackgroundWhitelistUids); 2104 } 2105 return whitelist; 2106 } 2107 } 2108 2109 @Override 2110 public int getRestrictBackgroundByCaller() { 2111 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2112 final int uid = Binder.getCallingUid(); 2113 2114 synchronized (mRulesLock) { 2115 // Must clear identity because getUidPolicy() is restricted to system. 2116 final long token = Binder.clearCallingIdentity(); 2117 final int policy; 2118 try { 2119 policy = getUidPolicy(uid); 2120 } finally { 2121 Binder.restoreCallingIdentity(token); 2122 } 2123 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 2124 // App is blacklisted. 2125 return RESTRICT_BACKGROUND_STATUS_ENABLED; 2126 } 2127 if (!mRestrictBackground) { 2128 return RESTRICT_BACKGROUND_STATUS_DISABLED; 2129 } 2130 return mRestrictBackgroundWhitelistUids.get(uid) 2131 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 2132 : RESTRICT_BACKGROUND_STATUS_ENABLED; 2133 } 2134 } 2135 2136 @Override 2137 public boolean getRestrictBackground() { 2138 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2139 2140 synchronized (mRulesLock) { 2141 return mRestrictBackground; 2142 } 2143 } 2144 2145 @Override 2146 public void setDeviceIdleMode(boolean enabled) { 2147 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2148 2149 synchronized (mRulesLock) { 2150 if (mDeviceIdleMode != enabled) { 2151 mDeviceIdleMode = enabled; 2152 if (mSystemReady) { 2153 // Device idle change means we need to rebuild rules for all 2154 // known apps, so do a global refresh. 2155 updateRulesForGlobalChangeLocked(false); 2156 } 2157 if (enabled) { 2158 EventLogTags.writeDeviceIdleOnPhase("net"); 2159 } else { 2160 EventLogTags.writeDeviceIdleOffPhase("net"); 2161 } 2162 } 2163 } 2164 } 2165 2166 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 2167 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2168 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2169 if (policy.template.matches(ident)) { 2170 return policy; 2171 } 2172 } 2173 return null; 2174 } 2175 2176 @Override 2177 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 2178 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2179 2180 // only returns usage summary, so we don't require caller to have 2181 // READ_NETWORK_USAGE_HISTORY. 2182 final long token = Binder.clearCallingIdentity(); 2183 try { 2184 return getNetworkQuotaInfoUnchecked(state); 2185 } finally { 2186 Binder.restoreCallingIdentity(token); 2187 } 2188 } 2189 2190 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 2191 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2192 2193 final NetworkPolicy policy; 2194 synchronized (mRulesLock) { 2195 policy = findPolicyForNetworkLocked(ident); 2196 } 2197 2198 if (policy == null || !policy.hasCycle()) { 2199 // missing policy means we can't derive useful quota info 2200 return null; 2201 } 2202 2203 final long currentTime = currentTimeMillis(); 2204 2205 // find total bytes used under policy 2206 final long start = computeLastCycleBoundary(currentTime, policy); 2207 final long end = currentTime; 2208 final long totalBytes = getTotalBytes(policy.template, start, end); 2209 2210 // report soft and hard limits under policy 2211 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 2212 : NetworkQuotaInfo.NO_LIMIT; 2213 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 2214 : NetworkQuotaInfo.NO_LIMIT; 2215 2216 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 2217 } 2218 2219 @Override 2220 public boolean isNetworkMetered(NetworkState state) { 2221 if (state.networkInfo == null) { 2222 return false; 2223 } 2224 2225 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2226 2227 // roaming networks are always considered metered 2228 if (ident.getRoaming()) { 2229 return true; 2230 } 2231 2232 final NetworkPolicy policy; 2233 synchronized (mRulesLock) { 2234 policy = findPolicyForNetworkLocked(ident); 2235 } 2236 2237 if (policy != null) { 2238 return policy.metered; 2239 } else { 2240 final int type = state.networkInfo.getType(); 2241 if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 2242 return true; 2243 } 2244 return false; 2245 } 2246 } 2247 2248 @Override 2249 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2250 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 2251 2252 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 2253 2254 final ArraySet<String> argSet = new ArraySet<String>(args.length); 2255 for (String arg : args) { 2256 argSet.add(arg); 2257 } 2258 2259 synchronized (mRulesLock) { 2260 if (argSet.contains("--unsnooze")) { 2261 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2262 mNetworkPolicy.valueAt(i).clearSnooze(); 2263 } 2264 2265 normalizePoliciesLocked(); 2266 updateNetworkEnabledLocked(); 2267 updateNetworkRulesLocked(); 2268 updateNotificationsLocked(); 2269 writePolicyLocked(); 2270 2271 fout.println("Cleared snooze timestamps"); 2272 return; 2273 } 2274 2275 fout.print("System ready: "); fout.println(mSystemReady); 2276 fout.print("Restrict background: "); fout.println(mRestrictBackground); 2277 fout.print("Restrict power: "); fout.println(mRestrictPower); 2278 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 2279 fout.println("Network policies:"); 2280 fout.increaseIndent(); 2281 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2282 fout.println(mNetworkPolicy.valueAt(i).toString()); 2283 } 2284 fout.decreaseIndent(); 2285 2286 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 2287 2288 fout.println("Policy for UIDs:"); 2289 fout.increaseIndent(); 2290 int size = mUidPolicy.size(); 2291 for (int i = 0; i < size; i++) { 2292 final int uid = mUidPolicy.keyAt(i); 2293 final int policy = mUidPolicy.valueAt(i); 2294 fout.print("UID="); 2295 fout.print(uid); 2296 fout.print(" policy="); 2297 fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy)); 2298 fout.println(); 2299 } 2300 fout.decreaseIndent(); 2301 2302 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2303 if (size > 0) { 2304 fout.println("Power save whitelist (except idle) app ids:"); 2305 fout.increaseIndent(); 2306 for (int i = 0; i < size; i++) { 2307 fout.print("UID="); 2308 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2309 fout.print(": "); 2310 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 2311 fout.println(); 2312 } 2313 fout.decreaseIndent(); 2314 } 2315 2316 size = mPowerSaveWhitelistAppIds.size(); 2317 if (size > 0) { 2318 fout.println("Power save whitelist app ids:"); 2319 fout.increaseIndent(); 2320 for (int i = 0; i < size; i++) { 2321 fout.print("UID="); 2322 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 2323 fout.print(": "); 2324 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 2325 fout.println(); 2326 } 2327 fout.decreaseIndent(); 2328 } 2329 2330 size = mRestrictBackgroundWhitelistUids.size(); 2331 if (size > 0) { 2332 fout.println("Restrict background whitelist uids:"); 2333 fout.increaseIndent(); 2334 for (int i = 0; i < size; i++) { 2335 fout.print("UID="); 2336 fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); 2337 fout.println(); 2338 } 2339 fout.decreaseIndent(); 2340 } 2341 2342 size = mDefaultRestrictBackgroundWhitelistUids.size(); 2343 if (size > 0) { 2344 fout.println("Default restrict background whitelist uids:"); 2345 fout.increaseIndent(); 2346 for (int i = 0; i < size; i++) { 2347 fout.print("UID="); 2348 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); 2349 fout.println(); 2350 } 2351 fout.decreaseIndent(); 2352 } 2353 2354 size = mRestrictBackgroundWhitelistRevokedUids.size(); 2355 if (size > 0) { 2356 fout.println("Default restrict background whitelist uids revoked by users:"); 2357 fout.increaseIndent(); 2358 for (int i = 0; i < size; i++) { 2359 fout.print("UID="); 2360 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); 2361 fout.println(); 2362 } 2363 fout.decreaseIndent(); 2364 } 2365 2366 final SparseBooleanArray knownUids = new SparseBooleanArray(); 2367 collectKeys(mUidState, knownUids); 2368 collectKeys(mUidRules, knownUids); 2369 2370 fout.println("Status for all known UIDs:"); 2371 fout.increaseIndent(); 2372 size = knownUids.size(); 2373 for (int i = 0; i < size; i++) { 2374 final int uid = knownUids.keyAt(i); 2375 fout.print("UID="); 2376 fout.print(uid); 2377 2378 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2379 fout.print(" state="); 2380 fout.print(state); 2381 if (state <= ActivityManager.PROCESS_STATE_TOP) { 2382 fout.print(" (fg)"); 2383 } else { 2384 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 2385 ? " (fg svc)" : " (bg)"); 2386 } 2387 2388 final int uidRules = mUidRules.get(uid, RULE_NONE); 2389 fout.print(" rules="); 2390 fout.print(uidRulesToString(uidRules)); 2391 fout.println(); 2392 } 2393 fout.decreaseIndent(); 2394 2395 fout.println("Status for just UIDs with rules:"); 2396 fout.increaseIndent(); 2397 size = mUidRules.size(); 2398 for (int i = 0; i < size; i++) { 2399 final int uid = mUidRules.keyAt(i); 2400 fout.print("UID="); 2401 fout.print(uid); 2402 final int uidRules = mUidRules.get(uid, RULE_NONE); 2403 fout.print(" rules="); 2404 fout.print(uidRulesToString(uidRules)); 2405 fout.println(); 2406 } 2407 fout.decreaseIndent(); 2408 } 2409 } 2410 2411 @Override 2412 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2413 String[] args, ResultReceiver resultReceiver) throws RemoteException { 2414 (new NetworkPolicyManagerShellCommand(mContext, this)).exec( 2415 this, in, out, err, args, resultReceiver); 2416 } 2417 2418 @Override 2419 public boolean isUidForeground(int uid) { 2420 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2421 2422 synchronized (mRulesLock) { 2423 return isUidForegroundLocked(uid); 2424 } 2425 } 2426 2427 private boolean isUidForegroundLocked(int uid) { 2428 return isUidStateForegroundLocked( 2429 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2430 } 2431 2432 private boolean isUidForegroundOnRestrictBackgroundLocked(int uid) { 2433 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2434 return isProcStateAllowedWhileOnRestrictBackgroundLocked(procState); 2435 } 2436 2437 private boolean isUidForegroundOnRestrictPowerLocked(int uid) { 2438 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2439 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState); 2440 } 2441 2442 private boolean isUidStateForegroundLocked(int state) { 2443 // only really in foreground when screen is also on 2444 return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP; 2445 } 2446 2447 /** 2448 * Process state of UID changed; if needed, will trigger 2449 * {@link #updateRulesForDataUsageRestrictionsLocked(int)} and 2450 * {@link #updateRulesForPowerRestrictionsLocked(int)} 2451 */ 2452 private void updateUidStateLocked(int uid, int uidState) { 2453 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2454 if (oldUidState != uidState) { 2455 // state changed, push updated rules 2456 mUidState.put(uid, uidState); 2457 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState); 2458 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 2459 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) { 2460 if (isUidIdle(uid)) { 2461 updateRuleForAppIdleLocked(uid); 2462 } 2463 if (mDeviceIdleMode) { 2464 updateRuleForDeviceIdleLocked(uid); 2465 } 2466 if (mRestrictPower) { 2467 updateRuleForRestrictPowerLocked(uid); 2468 } 2469 updateRulesForPowerRestrictionsLocked(uid); 2470 } 2471 updateNetworkStats(uid, isUidStateForegroundLocked(uidState)); 2472 } 2473 } 2474 2475 private void removeUidStateLocked(int uid) { 2476 final int index = mUidState.indexOfKey(uid); 2477 if (index >= 0) { 2478 final int oldUidState = mUidState.valueAt(index); 2479 mUidState.removeAt(index); 2480 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2481 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, 2482 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2483 if (mDeviceIdleMode) { 2484 updateRuleForDeviceIdleLocked(uid); 2485 } 2486 if (mRestrictPower) { 2487 updateRuleForRestrictPowerLocked(uid); 2488 } 2489 updateRulesForPowerRestrictionsLocked(uid); 2490 updateNetworkStats(uid, false); 2491 } 2492 } 2493 } 2494 2495 // adjust stats accounting based on foreground status 2496 private void updateNetworkStats(int uid, boolean uidForeground) { 2497 try { 2498 mNetworkStats.setUidForeground(uid, uidForeground); 2499 } catch (RemoteException e) { 2500 // ignored; service lives in system_server 2501 } 2502 } 2503 2504 private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState, 2505 int newUidState) { 2506 final boolean oldForeground = 2507 isProcStateAllowedWhileOnRestrictBackgroundLocked(oldUidState); 2508 final boolean newForeground = 2509 isProcStateAllowedWhileOnRestrictBackgroundLocked(newUidState); 2510 if (oldForeground != newForeground) { 2511 updateRulesForDataUsageRestrictionsLocked(uid); 2512 } 2513 } 2514 2515 private void updateScreenOn() { 2516 synchronized (mRulesLock) { 2517 try { 2518 mScreenOn = mPowerManager.isInteractive(); 2519 } catch (RemoteException e) { 2520 // ignored; service lives in system_server 2521 } 2522 updateRulesForScreenLocked(); 2523 } 2524 } 2525 2526 /** 2527 * Update rules that might be changed by {@link #mScreenOn} value. 2528 */ 2529 private void updateRulesForScreenLocked() { 2530 // only update rules for anyone with foreground activities 2531 final int size = mUidState.size(); 2532 for (int i = 0; i < size; i++) { 2533 if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 2534 final int uid = mUidState.keyAt(i); 2535 updateRestrictionRulesForUidLocked(uid); 2536 } 2537 } 2538 } 2539 2540 static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) { 2541 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2542 } 2543 2544 static boolean isProcStateAllowedWhileOnRestrictBackgroundLocked(int procState) { 2545 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2546 } 2547 2548 void updateRulesForRestrictPowerLocked() { 2549 updateRulesForWhitelistedPowerSaveLocked(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 2550 mUidFirewallPowerSaveRules); 2551 } 2552 2553 void updateRuleForRestrictPowerLocked(int uid) { 2554 updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2555 } 2556 2557 void updateRulesForDeviceIdleLocked() { 2558 updateRulesForWhitelistedPowerSaveLocked(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 2559 mUidFirewallDozableRules); 2560 } 2561 2562 void updateRuleForDeviceIdleLocked(int uid) { 2563 updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 2564 } 2565 2566 // NOTE: since both fw_dozable and fw_powersave uses the same map 2567 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2568 private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain, 2569 SparseIntArray rules) { 2570 if (enabled) { 2571 // Sync the whitelists before enabling the chain. We don't care about the rules if 2572 // we are disabling the chain. 2573 final SparseIntArray uidRules = rules; 2574 uidRules.clear(); 2575 final List<UserInfo> users = mUserManager.getUsers(); 2576 for (int ui = users.size() - 1; ui >= 0; ui--) { 2577 UserInfo user = users.get(ui); 2578 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2579 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) { 2580 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2581 int uid = UserHandle.getUid(user.id, appId); 2582 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2583 } 2584 } 2585 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { 2586 int appId = mPowerSaveWhitelistAppIds.keyAt(i); 2587 int uid = UserHandle.getUid(user.id, appId); 2588 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2589 } 2590 } 2591 for (int i = mUidState.size() - 1; i >= 0; i--) { 2592 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 2593 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2594 } 2595 } 2596 setUidFirewallRules(chain, uidRules); 2597 } 2598 2599 enableFirewallChainLocked(chain, enabled); 2600 } 2601 2602 private void updateRulesForNonMeteredNetworksLocked() { 2603 2604 } 2605 2606 private boolean isWhitelistedBatterySaverLocked(int uid) { 2607 final int appId = UserHandle.getAppId(uid); 2608 return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); 2609 } 2610 2611 // NOTE: since both fw_dozable and fw_powersave uses the same map 2612 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2613 private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) { 2614 if (enabled) { 2615 if (isWhitelistedBatterySaverLocked(uid) 2616 || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) { 2617 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 2618 } else { 2619 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 2620 } 2621 } 2622 } 2623 2624 void updateRulesForAppIdleLocked() { 2625 final SparseIntArray uidRules = mUidFirewallStandbyRules; 2626 uidRules.clear(); 2627 2628 // Fully update the app idle firewall chain. 2629 final List<UserInfo> users = mUserManager.getUsers(); 2630 for (int ui = users.size() - 1; ui >= 0; ui--) { 2631 UserInfo user = users.get(ui); 2632 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2633 for (int uid : idleUids) { 2634 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2635 // quick check: if this uid doesn't have INTERNET permission, it 2636 // doesn't have network access anyway, so it is a waste to mess 2637 // with it here. 2638 if (hasInternetPermissions(uid)) { 2639 uidRules.put(uid, FIREWALL_RULE_DENY); 2640 } 2641 } 2642 } 2643 } 2644 2645 setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); 2646 } 2647 2648 void updateRuleForAppIdleLocked(int uid) { 2649 if (!isUidValidForBlacklistRules(uid)) return; 2650 2651 int appId = UserHandle.getAppId(uid); 2652 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) 2653 && !isUidForegroundOnRestrictPowerLocked(uid)) { 2654 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2655 } else { 2656 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2657 } 2658 } 2659 2660 void updateRulesForAppIdleParoleLocked() { 2661 boolean enableChain = !mUsageStats.isAppIdleParoleOn(); 2662 enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); 2663 } 2664 2665 /** 2666 * Update rules that might be changed by {@link #mRestrictBackground}, 2667 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 2668 */ 2669 private void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) { 2670 long start; 2671 if (LOGD) start = System.currentTimeMillis(); 2672 2673 updateRulesForDeviceIdleLocked(); 2674 updateRulesForAppIdleLocked(); 2675 updateRulesForRestrictPowerLocked(); 2676 updateRulesForRestrictBackgroundLocked(); 2677 setRestrictBackgroundLocked(mRestrictBackground); 2678 2679 // If the set of restricted networks may have changed, re-evaluate those. 2680 if (restrictedNetworksChanged) { 2681 normalizePoliciesLocked(); 2682 updateNetworkRulesLocked(); 2683 } 2684 if (LOGD) { 2685 final long delta = System.currentTimeMillis() - start; 2686 Slog.d(TAG, "updateRulesForGlobalChangeLocked(" + restrictedNetworksChanged + ") took " 2687 + delta + "ms"); 2688 } 2689 } 2690 2691 private void updateRulesForRestrictBackgroundLocked() { 2692 final PackageManager pm = mContext.getPackageManager(); 2693 2694 // update rules for all installed applications 2695 final List<UserInfo> users = mUserManager.getUsers(); 2696 final List<ApplicationInfo> apps = pm.getInstalledApplications( 2697 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS 2698 | PackageManager.MATCH_DIRECT_BOOT_AWARE 2699 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2700 2701 final int usersSize = users.size(); 2702 final int appsSize = apps.size(); 2703 for (int i = 0; i < usersSize; i++) { 2704 final UserInfo user = users.get(i); 2705 for (int j = 0; j < appsSize; j++) { 2706 final ApplicationInfo app = apps.get(j); 2707 final int uid = UserHandle.getUid(user.id, app.uid); 2708 updateRulesForDataUsageRestrictionsLocked(uid); 2709 updateRulesForPowerRestrictionsLocked(uid); 2710 } 2711 } 2712 } 2713 2714 private void updateRulesForTempWhitelistChangeLocked() { 2715 final List<UserInfo> users = mUserManager.getUsers(); 2716 for (int i = 0; i < users.size(); i++) { 2717 final UserInfo user = users.get(i); 2718 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { 2719 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); 2720 int uid = UserHandle.getUid(user.id, appId); 2721 // Update external firewall rules. 2722 updateRuleForAppIdleLocked(uid); 2723 updateRuleForDeviceIdleLocked(uid); 2724 updateRuleForRestrictPowerLocked(uid); 2725 // Update internal rules. 2726 updateRulesForPowerRestrictionsLocked(uid); 2727 } 2728 } 2729 } 2730 2731 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 2732 // methods below could be merged into a isUidValidForRules() method. 2733 private boolean isUidValidForBlacklistRules(int uid) { 2734 // allow rules on specific system services, and any apps 2735 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 2736 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) { 2737 return true; 2738 } 2739 2740 return false; 2741 } 2742 2743 private boolean isUidValidForWhitelistRules(int uid) { 2744 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 2745 } 2746 2747 private boolean isUidIdle(int uid) { 2748 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 2749 final int userId = UserHandle.getUserId(uid); 2750 2751 if (!ArrayUtils.isEmpty(packages)) { 2752 for (String packageName : packages) { 2753 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 2754 return false; 2755 } 2756 } 2757 } 2758 return true; 2759 } 2760 2761 /** 2762 * Checks if an uid has INTERNET permissions. 2763 * <p> 2764 * Useful for the cases where the lack of network access can simplify the rules. 2765 */ 2766 private boolean hasInternetPermissions(int uid) { 2767 try { 2768 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) 2769 != PackageManager.PERMISSION_GRANTED) { 2770 return false; 2771 } 2772 } catch (RemoteException e) { 2773 } 2774 return true; 2775 } 2776 2777 /** 2778 * Applies network rules to bandwidth and firewall controllers based on uid policy. 2779 * 2780 * <p>There are currently 4 types of restriction rules: 2781 * <ul> 2782 * <li>Doze mode 2783 * <li>App idle mode 2784 * <li>Battery Saver Mode (also referred as power save). 2785 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data'). 2786 * </ul> 2787 * 2788 * <p>This method changes both the external firewall rules and the internal state. 2789 */ 2790 private void updateRestrictionRulesForUidLocked(int uid) { 2791 // Methods below only changes the firewall rules for the power-related modes. 2792 updateRuleForDeviceIdleLocked(uid); 2793 updateRuleForAppIdleLocked(uid); 2794 updateRuleForRestrictPowerLocked(uid); 2795 2796 // Update internal state for power-related modes. 2797 updateRulesForPowerRestrictionsLocked(uid); 2798 2799 // Update firewall and internal rules for Data Saver Mode. 2800 updateRulesForDataUsageRestrictionsLocked(uid); 2801 } 2802 2803 /** 2804 * Applies network rules to bandwidth controllers based on process state and user-defined 2805 * restrictions (blacklist / whitelist). 2806 * 2807 * <p> 2808 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 2809 * networks: 2810 * <ul> 2811 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). 2812 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're 2813 * also blacklisted. 2814 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 2815 * no UIDs other those whitelisted will have access. 2816 * <ul> 2817 * 2818 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 2819 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / 2820 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist 2821 * respectively): these methods set the proper internal state (blacklist / whitelist), then call 2822 * this ({@link #updateRulesForDataUsageRestrictionsLocked(int)}) to propagate the rules to 2823 * {@link INetworkManagementService}, but this method should also be called in events (like 2824 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 2825 * following rules should also be applied: 2826 * 2827 * <ul> 2828 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 2829 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 2830 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from 2831 * {@code bw_penalty_box}. 2832 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 2833 * </ul> 2834 * 2835 * <p>For optimization, the rules are only applied on user apps that have internet access 2836 * permission, since there is no need to change the {@code iptables} rule if the app does not 2837 * have permission to use the internet. 2838 * 2839 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID. 2840 * 2841 */ 2842 private void updateRulesForDataUsageRestrictionsLocked(int uid) { 2843 updateRulesForDataUsageRestrictionsLocked(uid, false); 2844 } 2845 2846 /** 2847 * Overloaded version of {@link #updateRulesForDataUsageRestrictionsLocked(int)} called when an 2848 * app is removed - it ignores the UID validity check. 2849 */ 2850 private void updateRulesForDataUsageRestrictionsLocked(int uid, boolean uidDeleted) { 2851 if (!uidDeleted && !isUidValidForWhitelistRules(uid)) { 2852 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 2853 return; 2854 } 2855 2856 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2857 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2858 final boolean isForeground = isUidForegroundOnRestrictBackgroundLocked(uid); 2859 2860 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 2861 final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid); 2862 final int oldRule = oldUidRules & MASK_METERED_NETWORKS; 2863 int newRule = RULE_NONE; 2864 2865 // First step: define the new rule based on user restrictions and foreground state. 2866 if (isForeground) { 2867 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { 2868 newRule = RULE_TEMPORARY_ALLOW_METERED; 2869 } else if (isWhitelisted) { 2870 newRule = RULE_ALLOW_METERED; 2871 } 2872 } else { 2873 if (isBlacklisted) { 2874 newRule = RULE_REJECT_METERED; 2875 } else if (mRestrictBackground && isWhitelisted) { 2876 newRule = RULE_ALLOW_METERED; 2877 } 2878 } 2879 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS); 2880 2881 if (LOGV) { 2882 Log.v(TAG, "updateRuleForRestrictBackgroundLocked(" + uid + ")" 2883 + ": isForeground=" +isForeground 2884 + ", isBlacklisted=" + isBlacklisted 2885 + ", isWhitelisted=" + isWhitelisted 2886 + ", oldRule=" + uidRulesToString(oldRule) 2887 + ", newRule=" + uidRulesToString(newRule) 2888 + ", newUidRules=" + uidRulesToString(newUidRules) 2889 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 2890 } 2891 2892 if (newUidRules == RULE_NONE) { 2893 mUidRules.delete(uid); 2894 } else { 2895 mUidRules.put(uid, newUidRules); 2896 } 2897 2898 boolean changed = false; 2899 2900 // Second step: apply bw changes based on change of state. 2901 if (newRule != oldRule) { 2902 changed = true; 2903 2904 if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2905 // Temporarily whitelist foreground app, removing from blacklist if necessary 2906 // (since bw_penalty_box prevails over bw_happy_box). 2907 2908 setMeteredNetworkWhitelist(uid, true); 2909 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, 2910 // but ideally it should be just: 2911 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2912 if (isBlacklisted) { 2913 setMeteredNetworkBlacklist(uid, false); 2914 } 2915 } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2916 // Remove temporary whitelist from app that is not on foreground anymore. 2917 2918 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, 2919 // but ideally they should be just: 2920 // setMeteredNetworkWhitelist(uid, isWhitelisted); 2921 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2922 if (!isWhitelisted) { 2923 setMeteredNetworkWhitelist(uid, false); 2924 } 2925 if (isBlacklisted) { 2926 setMeteredNetworkBlacklist(uid, true); 2927 } 2928 } else if ((newRule & RULE_REJECT_METERED) != 0 2929 || (oldRule & RULE_REJECT_METERED) != 0) { 2930 // Flip state because app was explicitly added or removed to blacklist. 2931 setMeteredNetworkBlacklist(uid, isBlacklisted); 2932 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) { 2933 // Since blacklist prevails over whitelist, we need to handle the special case 2934 // where app is whitelisted and blacklisted at the same time (although such 2935 // scenario should be blocked by the UI), then blacklist is removed. 2936 setMeteredNetworkWhitelist(uid, isWhitelisted); 2937 } 2938 } else if ((newRule & RULE_ALLOW_METERED) != 0 2939 || (oldRule & RULE_ALLOW_METERED) != 0) { 2940 // Flip state because app was explicitly added or removed to whitelist. 2941 setMeteredNetworkWhitelist(uid, isWhitelisted); 2942 } else { 2943 // All scenarios should have been covered above. 2944 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid 2945 + ": foreground=" + isForeground 2946 + ", whitelisted=" + isWhitelisted 2947 + ", blacklisted=" + isBlacklisted 2948 + ", newRule=" + uidRulesToString(newUidRules) 2949 + ", oldRule=" + uidRulesToString(oldUidRules)); 2950 } 2951 2952 // Dispatch changed rule to existing listeners. 2953 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 2954 } 2955 } 2956 2957 /** 2958 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external 2959 * listeners in case of change. 2960 * <p> 2961 * There are 3 power-related rules that affects whether an app has background access on 2962 * non-metered networks, and when the condition applies and the UID is not whitelisted for power 2963 * restriction, it's added to the equivalent firewall chain: 2964 * <ul> 2965 * <li>App is idle: {@code fw_standby} firewall chain. 2966 * <li>Device is idle: {@code fw_dozable} firewall chain. 2967 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain. 2968 * </ul> 2969 * <p> 2970 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on 2971 * these modes, the UID process state (foreground or not), and the UIDwhitelist state. 2972 * <p> 2973 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}. 2974 */ 2975 private void updateRulesForPowerRestrictionsLocked(int uid) { 2976 if (!isUidValidForBlacklistRules(uid)) { 2977 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); 2978 return; 2979 } 2980 2981 final boolean isIdle = isUidIdle(uid); 2982 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; 2983 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2984 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2985 final boolean isForeground = isUidForegroundOnRestrictPowerLocked(uid); 2986 2987 final boolean isWhitelisted = isWhitelistedBatterySaverLocked(uid); 2988 final int oldRule = oldUidRules & MASK_ALL_NETWORKS; 2989 int newRule = RULE_NONE; 2990 2991 // First step: define the new rule based on user restrictions and foreground state. 2992 2993 // NOTE: if statements below could be inlined, but it's easier to understand the logic 2994 // by considering the foreground and non-foreground states. 2995 if (isForeground) { 2996 if (restrictMode) { 2997 newRule = RULE_ALLOW_ALL; 2998 } 2999 } else if (restrictMode) { 3000 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL; 3001 } 3002 3003 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule; 3004 3005 if (LOGV) { 3006 Log.v(TAG, "updateRulesForNonMeteredNetworksLocked(" + uid + ")" 3007 + ", isIdle: " + isIdle 3008 + ", mRestrictPower: " + mRestrictPower 3009 + ", mDeviceIdleMode: " + mDeviceIdleMode 3010 + ", isForeground=" + isForeground 3011 + ", isWhitelisted=" + isWhitelisted 3012 + ", oldRule=" + uidRulesToString(oldRule) 3013 + ", newRule=" + uidRulesToString(newRule) 3014 + ", newUidRules=" + uidRulesToString(newUidRules) 3015 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 3016 } 3017 3018 if (newUidRules == RULE_NONE) { 3019 mUidRules.delete(uid); 3020 } else { 3021 mUidRules.put(uid, newUidRules); 3022 } 3023 3024 // Second step: notify listeners if state changed. 3025 if (newRule != oldRule) { 3026 if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) { 3027 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid); 3028 } else if ((newRule & RULE_REJECT_ALL) != 0) { 3029 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid); 3030 } else { 3031 // All scenarios should have been covered above 3032 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid 3033 + ": foreground=" + isForeground 3034 + ", whitelisted=" + isWhitelisted 3035 + ", newRule=" + uidRulesToString(newUidRules) 3036 + ", oldRule=" + uidRulesToString(oldUidRules)); 3037 } 3038 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 3039 } 3040 } 3041 3042 private class AppIdleStateChangeListener 3043 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 3044 3045 @Override 3046 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 3047 try { 3048 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 3049 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 3050 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle); 3051 synchronized (mRulesLock) { 3052 updateRuleForAppIdleLocked(uid); 3053 updateRulesForPowerRestrictionsLocked(uid); 3054 } 3055 } catch (NameNotFoundException nnfe) { 3056 } 3057 } 3058 3059 @Override 3060 public void onParoleStateChanged(boolean isParoleOn) { 3061 synchronized (mRulesLock) { 3062 updateRulesForAppIdleParoleLocked(); 3063 } 3064 } 3065 } 3066 3067 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { 3068 if (listener != null) { 3069 try { 3070 listener.onUidRulesChanged(uid, uidRules); 3071 } catch (RemoteException ignored) { 3072 } 3073 } 3074 } 3075 3076 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, 3077 String[] meteredIfaces) { 3078 if (listener != null) { 3079 try { 3080 listener.onMeteredIfacesChanged(meteredIfaces); 3081 } catch (RemoteException ignored) { 3082 } 3083 } 3084 } 3085 3086 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, 3087 boolean restrictBackground) { 3088 if (listener != null) { 3089 try { 3090 listener.onRestrictBackgroundChanged(restrictBackground); 3091 } catch (RemoteException ignored) { 3092 } 3093 } 3094 } 3095 3096 private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener, 3097 int uid, boolean whitelisted) { 3098 if (listener != null) { 3099 try { 3100 listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted); 3101 } catch (RemoteException ignored) { 3102 } 3103 } 3104 } 3105 3106 private void dispatchRestrictBackgroundBlacklistChanged(INetworkPolicyListener listener, 3107 int uid, boolean blacklisted) { 3108 if (listener != null) { 3109 try { 3110 listener.onRestrictBackgroundBlacklistChanged(uid, blacklisted); 3111 } catch (RemoteException ignored) { 3112 } 3113 } 3114 } 3115 3116 private Handler.Callback mHandlerCallback = new Handler.Callback() { 3117 @Override 3118 public boolean handleMessage(Message msg) { 3119 switch (msg.what) { 3120 case MSG_RULES_CHANGED: { 3121 final int uid = msg.arg1; 3122 final int uidRules = msg.arg2; 3123 dispatchUidRulesChanged(mConnectivityListener, uid, uidRules); 3124 final int length = mListeners.beginBroadcast(); 3125 for (int i = 0; i < length; i++) { 3126 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3127 dispatchUidRulesChanged(listener, uid, uidRules); 3128 } 3129 mListeners.finishBroadcast(); 3130 return true; 3131 } 3132 case MSG_METERED_IFACES_CHANGED: { 3133 final String[] meteredIfaces = (String[]) msg.obj; 3134 dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces); 3135 final int length = mListeners.beginBroadcast(); 3136 for (int i = 0; i < length; i++) { 3137 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3138 dispatchMeteredIfacesChanged(listener, meteredIfaces); 3139 } 3140 mListeners.finishBroadcast(); 3141 return true; 3142 } 3143 case MSG_LIMIT_REACHED: { 3144 final String iface = (String) msg.obj; 3145 3146 maybeRefreshTrustedTime(); 3147 synchronized (mRulesLock) { 3148 if (mMeteredIfaces.contains(iface)) { 3149 try { 3150 // force stats update to make sure we have 3151 // numbers that caused alert to trigger. 3152 mNetworkStats.forceUpdate(); 3153 } catch (RemoteException e) { 3154 // ignored; service lives in system_server 3155 } 3156 3157 updateNetworkEnabledLocked(); 3158 updateNotificationsLocked(); 3159 } 3160 } 3161 return true; 3162 } 3163 case MSG_RESTRICT_BACKGROUND_CHANGED: { 3164 final boolean restrictBackground = msg.arg1 != 0; 3165 dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground); 3166 final int length = mListeners.beginBroadcast(); 3167 for (int i = 0; i < length; i++) { 3168 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3169 dispatchRestrictBackgroundChanged(listener, restrictBackground); 3170 } 3171 mListeners.finishBroadcast(); 3172 final Intent intent = 3173 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3174 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3175 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3176 return true; 3177 } 3178 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { 3179 // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: 3180 // - when an app is whitelisted 3181 // - when an app is blacklisted 3182 // 3183 // Whether the internal listeners (INetworkPolicyListener implementations) or 3184 // app broadcast receivers are notified depend on the following rules: 3185 // 3186 // - App receivers are only notified when the app status changed (msg.arg2 = 1) 3187 // - Listeners are only notified when app was whitelisted (msg.obj is not null), 3188 // since blacklist notifications are handled through MSG_RULES_CHANGED). 3189 final int uid = msg.arg1; 3190 final boolean changed = msg.arg2 == 1; 3191 final Boolean whitelisted = (Boolean) msg.obj; 3192 3193 // First notify internal listeners... 3194 if (whitelisted != null) { 3195 final boolean whitelistedBool = whitelisted.booleanValue(); 3196 dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid, 3197 whitelistedBool); 3198 final int length = mListeners.beginBroadcast(); 3199 for (int i = 0; i < length; i++) { 3200 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3201 dispatchRestrictBackgroundWhitelistChanged(listener, uid, 3202 whitelistedBool); 3203 } 3204 mListeners.finishBroadcast(); 3205 } 3206 final PackageManager pm = mContext.getPackageManager(); 3207 final String[] packages = pm.getPackagesForUid(uid); 3208 if (changed && packages != null) { 3209 // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 3210 final int userId = UserHandle.getUserId(uid); 3211 for (String packageName : packages) { 3212 final Intent intent = new Intent( 3213 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3214 intent.setPackage(packageName); 3215 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3216 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 3217 } 3218 } 3219 return true; 3220 } 3221 case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: { 3222 final int uid = msg.arg1; 3223 final boolean blacklisted = msg.arg2 == 1; 3224 3225 dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid, 3226 blacklisted); 3227 final int length = mListeners.beginBroadcast(); 3228 for (int i = 0; i < length; i++) { 3229 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3230 dispatchRestrictBackgroundBlacklistChanged(listener, uid, 3231 blacklisted); 3232 } 3233 mListeners.finishBroadcast(); 3234 return true; 3235 } 3236 case MSG_ADVISE_PERSIST_THRESHOLD: { 3237 final long lowestRule = (Long) msg.obj; 3238 try { 3239 // make sure stats are recorded frequently enough; we aim 3240 // for 2MB threshold for 2GB/month rules. 3241 final long persistThreshold = lowestRule / 1000; 3242 mNetworkStats.advisePersistThreshold(persistThreshold); 3243 } catch (RemoteException e) { 3244 // ignored; service lives in system_server 3245 } 3246 return true; 3247 } 3248 case MSG_SCREEN_ON_CHANGED: { 3249 updateScreenOn(); 3250 return true; 3251 } 3252 case MSG_UPDATE_INTERFACE_QUOTA: { 3253 removeInterfaceQuota((String) msg.obj); 3254 // int params need to be stitched back into a long 3255 setInterfaceQuota((String) msg.obj, 3256 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); 3257 return true; 3258 } 3259 case MSG_REMOVE_INTERFACE_QUOTA: { 3260 removeInterfaceQuota((String) msg.obj); 3261 return true; 3262 } 3263 default: { 3264 return false; 3265 } 3266 } 3267 } 3268 }; 3269 3270 private void setInterfaceQuota(String iface, long quotaBytes) { 3271 try { 3272 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 3273 } catch (IllegalStateException e) { 3274 Log.wtf(TAG, "problem setting interface quota", e); 3275 } catch (RemoteException e) { 3276 // ignored; service lives in system_server 3277 } 3278 } 3279 3280 private void removeInterfaceQuota(String iface) { 3281 try { 3282 mNetworkManager.removeInterfaceQuota(iface); 3283 } catch (IllegalStateException e) { 3284 Log.wtf(TAG, "problem removing interface quota", e); 3285 } catch (RemoteException e) { 3286 // ignored; service lives in system_server 3287 } 3288 } 3289 3290 private void setMeteredNetworkBlacklist(int uid, boolean enable) { 3291 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); 3292 try { 3293 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); 3294 } catch (IllegalStateException e) { 3295 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); 3296 } catch (RemoteException e) { 3297 // ignored; service lives in system_server 3298 } 3299 } 3300 3301 private void setMeteredNetworkWhitelist(int uid, boolean enable) { 3302 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); 3303 try { 3304 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); 3305 } catch (IllegalStateException e) { 3306 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); 3307 } catch (RemoteException e) { 3308 // ignored; service lives in system_server 3309 } 3310 } 3311 3312 /** 3313 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 3314 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 3315 * specified here. 3316 */ 3317 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 3318 try { 3319 int size = uidRules.size(); 3320 int[] uids = new int[size]; 3321 int[] rules = new int[size]; 3322 for(int index = size - 1; index >= 0; --index) { 3323 uids[index] = uidRules.keyAt(index); 3324 rules[index] = uidRules.valueAt(index); 3325 } 3326 mNetworkManager.setFirewallUidRules(chain, uids, rules); 3327 } catch (IllegalStateException e) { 3328 Log.wtf(TAG, "problem setting firewall uid rules", e); 3329 } catch (RemoteException e) { 3330 // ignored; service lives in system_server 3331 } 3332 } 3333 3334 /** 3335 * Add or remove a uid to the firewall blacklist for all network ifaces. 3336 */ 3337 private void setUidFirewallRule(int chain, int uid, int rule) { 3338 if (chain == FIREWALL_CHAIN_DOZABLE) { 3339 mUidFirewallDozableRules.put(uid, rule); 3340 } else if (chain == FIREWALL_CHAIN_STANDBY) { 3341 mUidFirewallStandbyRules.put(uid, rule); 3342 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 3343 mUidFirewallPowerSaveRules.put(uid, rule); 3344 } 3345 3346 try { 3347 mNetworkManager.setFirewallUidRule(chain, uid, rule); 3348 } catch (IllegalStateException e) { 3349 Log.wtf(TAG, "problem setting firewall uid rules", e); 3350 } catch (RemoteException e) { 3351 // ignored; service lives in system_server 3352 } 3353 } 3354 3355 /** 3356 * Add or remove a uid to the firewall blacklist for all network ifaces. 3357 */ 3358 private void enableFirewallChainLocked(int chain, boolean enable) { 3359 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 3360 mFirewallChainStates.get(chain) == enable) { 3361 // All is the same, nothing to do. 3362 return; 3363 } 3364 mFirewallChainStates.put(chain, enable); 3365 try { 3366 mNetworkManager.setFirewallChainEnabled(chain, enable); 3367 } catch (IllegalStateException e) { 3368 Log.wtf(TAG, "problem enable firewall chain", e); 3369 } catch (RemoteException e) { 3370 // ignored; service lives in system_server 3371 } 3372 } 3373 3374 private long getTotalBytes(NetworkTemplate template, long start, long end) { 3375 try { 3376 return mNetworkStats.getNetworkTotalBytes(template, start, end); 3377 } catch (RuntimeException e) { 3378 Slog.w(TAG, "problem reading network stats: " + e); 3379 return 0; 3380 } catch (RemoteException e) { 3381 // ignored; service lives in system_server 3382 return 0; 3383 } 3384 } 3385 3386 private boolean isBandwidthControlEnabled() { 3387 final long token = Binder.clearCallingIdentity(); 3388 try { 3389 return mNetworkManager.isBandwidthControlEnabled(); 3390 } catch (RemoteException e) { 3391 // ignored; service lives in system_server 3392 return false; 3393 } finally { 3394 Binder.restoreCallingIdentity(token); 3395 } 3396 } 3397 3398 /** 3399 * Try refreshing {@link #mTime} when stale. 3400 */ 3401 void maybeRefreshTrustedTime() { 3402 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3403 mTime.forceRefresh(); 3404 } 3405 } 3406 3407 private long currentTimeMillis() { 3408 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3409 } 3410 3411 private static Intent buildAllowBackgroundDataIntent() { 3412 return new Intent(ACTION_ALLOW_BACKGROUND); 3413 } 3414 3415 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 3416 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 3417 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3418 return intent; 3419 } 3420 3421 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 3422 final Intent intent = new Intent(); 3423 intent.setComponent(new ComponentName( 3424 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 3425 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3426 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3427 return intent; 3428 } 3429 3430 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 3431 final Intent intent = new Intent(); 3432 intent.setComponent(new ComponentName( 3433 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 3434 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3435 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3436 return intent; 3437 } 3438 3439 @VisibleForTesting 3440 public void addIdleHandler(IdleHandler handler) { 3441 mHandler.getLooper().getQueue().addIdleHandler(handler); 3442 } 3443 3444 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3445 final int size = source.size(); 3446 for (int i = 0; i < size; i++) { 3447 target.put(source.keyAt(i), true); 3448 } 3449 } 3450 3451 @Override 3452 public void factoryReset(String subscriber) { 3453 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 3454 3455 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3456 return; 3457 } 3458 3459 // Turn mobile data limit off 3460 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 3461 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 3462 for (NetworkPolicy policy : policies) { 3463 if (policy.template.equals(template)) { 3464 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 3465 policy.inferred = false; 3466 policy.clearSnooze(); 3467 } 3468 } 3469 setNetworkPolicies(policies); 3470 3471 // Turn restrict background data off 3472 setRestrictBackground(false); 3473 3474 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 3475 // Remove app's "restrict background data" flag 3476 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 3477 setUidPolicy(uid, POLICY_NONE); 3478 } 3479 } 3480 } 3481 3482 private class MyPackageMonitor extends PackageMonitor { 3483 3484 @Override 3485 public void onPackageRemoved(String packageName, int uid) { 3486 if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); 3487 synchronized (mRulesLock) { 3488 removeRestrictBackgroundWhitelistedUidLocked(uid, true, true); 3489 updateRestrictionRulesForUidLocked(uid); 3490 } 3491 } 3492 } 3493 3494 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal { 3495 3496 @Override 3497 public void resetUserState(int userId) { 3498 synchronized (mRulesLock) { 3499 boolean changed = removeUserStateLocked(userId, false); 3500 changed = addDefaultRestrictBackgroundWhitelistUidsLocked(userId) || changed; 3501 if (changed) { 3502 writePolicyLocked(); 3503 } 3504 } 3505 } 3506 } 3507 } 3508