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