NetworkPolicyManagerService.java revision 70c8b9b66027409f9dec91872cbe8ae8756d5ea4
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, 1, null) 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 onTetheringChanged(String iface, boolean tethering) { 1903 // No need to enforce permission because setRestrictBackground() will do it. 1904 if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")"); 1905 synchronized (mRulesLock) { 1906 if (mRestrictBackground && tethering) { 1907 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver"); 1908 setRestrictBackground(false); 1909 } 1910 } 1911 } 1912 1913 @Override 1914 public void setRestrictBackground(boolean restrictBackground) { 1915 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1916 final long token = Binder.clearCallingIdentity(); 1917 try { 1918 maybeRefreshTrustedTime(); 1919 synchronized (mRulesLock) { 1920 if (restrictBackground == mRestrictBackground) { 1921 // Ideally, UI should never allow this scenario... 1922 Slog.w(TAG, "setRestrictBackground: already " + restrictBackground); 1923 return; 1924 } 1925 setRestrictBackgroundLocked(restrictBackground); 1926 } 1927 1928 } finally { 1929 Binder.restoreCallingIdentity(token); 1930 } 1931 1932 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 1933 .sendToTarget(); 1934 } 1935 1936 private void setRestrictBackgroundLocked(boolean restrictBackground) { 1937 final boolean oldRestrictBackground = mRestrictBackground; 1938 mRestrictBackground = restrictBackground; 1939 // Must whitelist foreground apps before turning data saver mode on. 1940 // TODO: there is no need to iterate through all apps here, just those in the foreground, 1941 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 1942 updateRulesForRestrictBackgroundLocked(); 1943 try { 1944 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 1945 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 1946 mRestrictBackground = oldRestrictBackground; 1947 // TODO: if it knew the foreground apps (see TODO above), it could call 1948 // updateRulesForRestrictBackgroundLocked() again to restore state. 1949 return; 1950 } 1951 } catch (RemoteException e) { 1952 // ignored; service lives in system_server 1953 } 1954 updateNotificationsLocked(); 1955 writePolicyLocked(); 1956 } 1957 1958 @Override 1959 public void addRestrictBackgroundWhitelistedUid(int uid) { 1960 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1961 final boolean oldStatus; 1962 final boolean needFirewallRules; 1963 synchronized (mRulesLock) { 1964 oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 1965 if (oldStatus) { 1966 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); 1967 return; 1968 } 1969 needFirewallRules = isUidValidForWhitelistRules(uid); 1970 Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); 1971 mRestrictBackgroundWhitelistUids.append(uid, true); 1972 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 1973 && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 1974 if (LOGD) Slog.d(TAG, "Removing uid " + uid 1975 + " from revoked restrict background whitelist"); 1976 mRestrictBackgroundWhitelistRevokedUids.delete(uid); 1977 } 1978 if (needFirewallRules) { 1979 // Only update firewall rules if necessary... 1980 updateRuleForRestrictBackgroundLocked(uid); 1981 } 1982 // ...but always persists the whitelist request. 1983 writePolicyLocked(); 1984 } 1985 int changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; 1986 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, 1987 Boolean.TRUE).sendToTarget(); 1988 } 1989 1990 @Override 1991 public void removeRestrictBackgroundWhitelistedUid(int uid) { 1992 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1993 final boolean changed; 1994 synchronized (mRulesLock) { 1995 changed = removeRestrictBackgroundWhitelistedUidLocked(uid, false, true); 1996 } 1997 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, 1998 Boolean.FALSE).sendToTarget(); 1999 } 2000 2001 /** 2002 * Removes a uid from the restricted background whitelist, returning whether its current 2003 * {@link ConnectivityManager.RestrictBackgroundStatus} changed. 2004 */ 2005 private boolean removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean uidDeleted, 2006 boolean updateNow) { 2007 final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2008 if (!oldStatus) { 2009 if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before"); 2010 return false; 2011 } 2012 final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid); 2013 Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); 2014 mRestrictBackgroundWhitelistUids.delete(uid); 2015 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2016 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2017 if (LOGD) Slog.d(TAG, "Adding uid " + uid 2018 + " to revoked restrict background whitelist"); 2019 mRestrictBackgroundWhitelistRevokedUids.append(uid, true); 2020 } 2021 if (needFirewallRules) { 2022 // Only update firewall rules if necessary... 2023 updateRuleForRestrictBackgroundLocked(uid, uidDeleted); 2024 } 2025 if (updateNow) { 2026 // ...but always persists the whitelist request. 2027 writePolicyLocked(); 2028 } 2029 // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the 2030 // app was whitelisted before). 2031 return mRestrictBackground && needFirewallRules; 2032 } 2033 2034 @Override 2035 public int[] getRestrictBackgroundWhitelistedUids() { 2036 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2037 synchronized (mRulesLock) { 2038 final int size = mRestrictBackgroundWhitelistUids.size(); 2039 final int[] whitelist = new int[size]; 2040 for (int i = 0; i < size; i++) { 2041 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); 2042 } 2043 if (LOGV) { 2044 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " 2045 + mRestrictBackgroundWhitelistUids); 2046 } 2047 return whitelist; 2048 } 2049 } 2050 2051 @Override 2052 public int getRestrictBackgroundByCaller() { 2053 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2054 final int uid = Binder.getCallingUid(); 2055 2056 synchronized (mRulesLock) { 2057 // Must clear identity because getUidPolicy() is restricted to system. 2058 final long token = Binder.clearCallingIdentity(); 2059 final int policy; 2060 try { 2061 policy = getUidPolicy(uid); 2062 } finally { 2063 Binder.restoreCallingIdentity(token); 2064 } 2065 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 2066 // App is blacklisted. 2067 return RESTRICT_BACKGROUND_STATUS_ENABLED; 2068 } 2069 if (!mRestrictBackground) { 2070 return RESTRICT_BACKGROUND_STATUS_DISABLED; 2071 } 2072 return mRestrictBackgroundWhitelistUids.get(uid) 2073 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 2074 : RESTRICT_BACKGROUND_STATUS_ENABLED; 2075 } 2076 } 2077 2078 @Override 2079 public boolean getRestrictBackground() { 2080 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2081 2082 synchronized (mRulesLock) { 2083 return mRestrictBackground; 2084 } 2085 } 2086 2087 @Override 2088 public void setDeviceIdleMode(boolean enabled) { 2089 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2090 2091 synchronized (mRulesLock) { 2092 if (mDeviceIdleMode != enabled) { 2093 mDeviceIdleMode = enabled; 2094 if (mSystemReady) { 2095 // Device idle change means we need to rebuild rules for all 2096 // known apps, so do a global refresh. 2097 updateRulesForGlobalChangeLocked(false); 2098 } 2099 if (enabled) { 2100 EventLogTags.writeDeviceIdleOnPhase("net"); 2101 } else { 2102 EventLogTags.writeDeviceIdleOffPhase("net"); 2103 } 2104 } 2105 } 2106 } 2107 2108 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 2109 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2110 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2111 if (policy.template.matches(ident)) { 2112 return policy; 2113 } 2114 } 2115 return null; 2116 } 2117 2118 @Override 2119 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 2120 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2121 2122 // only returns usage summary, so we don't require caller to have 2123 // READ_NETWORK_USAGE_HISTORY. 2124 final long token = Binder.clearCallingIdentity(); 2125 try { 2126 return getNetworkQuotaInfoUnchecked(state); 2127 } finally { 2128 Binder.restoreCallingIdentity(token); 2129 } 2130 } 2131 2132 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 2133 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2134 2135 final NetworkPolicy policy; 2136 synchronized (mRulesLock) { 2137 policy = findPolicyForNetworkLocked(ident); 2138 } 2139 2140 if (policy == null || !policy.hasCycle()) { 2141 // missing policy means we can't derive useful quota info 2142 return null; 2143 } 2144 2145 final long currentTime = currentTimeMillis(); 2146 2147 // find total bytes used under policy 2148 final long start = computeLastCycleBoundary(currentTime, policy); 2149 final long end = currentTime; 2150 final long totalBytes = getTotalBytes(policy.template, start, end); 2151 2152 // report soft and hard limits under policy 2153 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 2154 : NetworkQuotaInfo.NO_LIMIT; 2155 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 2156 : NetworkQuotaInfo.NO_LIMIT; 2157 2158 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 2159 } 2160 2161 @Override 2162 public boolean isNetworkMetered(NetworkState state) { 2163 if (state.networkInfo == null) { 2164 return false; 2165 } 2166 2167 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2168 2169 // roaming networks are always considered metered 2170 if (ident.getRoaming()) { 2171 return true; 2172 } 2173 2174 final NetworkPolicy policy; 2175 synchronized (mRulesLock) { 2176 policy = findPolicyForNetworkLocked(ident); 2177 } 2178 2179 if (policy != null) { 2180 return policy.metered; 2181 } else { 2182 final int type = state.networkInfo.getType(); 2183 if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 2184 return true; 2185 } 2186 return false; 2187 } 2188 } 2189 2190 @Override 2191 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2192 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 2193 2194 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 2195 2196 final ArraySet<String> argSet = new ArraySet<String>(args.length); 2197 for (String arg : args) { 2198 argSet.add(arg); 2199 } 2200 2201 synchronized (mRulesLock) { 2202 if (argSet.contains("--unsnooze")) { 2203 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2204 mNetworkPolicy.valueAt(i).clearSnooze(); 2205 } 2206 2207 normalizePoliciesLocked(); 2208 updateNetworkEnabledLocked(); 2209 updateNetworkRulesLocked(); 2210 updateNotificationsLocked(); 2211 writePolicyLocked(); 2212 2213 fout.println("Cleared snooze timestamps"); 2214 return; 2215 } 2216 2217 fout.print("System ready: "); fout.println(mSystemReady); 2218 fout.print("Restrict background: "); fout.println(mRestrictBackground); 2219 fout.print("Restrict power: "); fout.println(mRestrictPower); 2220 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 2221 fout.println("Network policies:"); 2222 fout.increaseIndent(); 2223 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2224 fout.println(mNetworkPolicy.valueAt(i).toString()); 2225 } 2226 fout.decreaseIndent(); 2227 2228 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 2229 2230 fout.println("Policy for UIDs:"); 2231 fout.increaseIndent(); 2232 int size = mUidPolicy.size(); 2233 for (int i = 0; i < size; i++) { 2234 final int uid = mUidPolicy.keyAt(i); 2235 final int policy = mUidPolicy.valueAt(i); 2236 fout.print("UID="); 2237 fout.print(uid); 2238 fout.print(" policy="); 2239 fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy)); 2240 fout.println(); 2241 } 2242 fout.decreaseIndent(); 2243 2244 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2245 if (size > 0) { 2246 fout.println("Power save whitelist (except idle) app ids:"); 2247 fout.increaseIndent(); 2248 for (int i = 0; i < size; i++) { 2249 fout.print("UID="); 2250 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2251 fout.print(": "); 2252 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 2253 fout.println(); 2254 } 2255 fout.decreaseIndent(); 2256 } 2257 2258 size = mPowerSaveWhitelistAppIds.size(); 2259 if (size > 0) { 2260 fout.println("Power save whitelist app ids:"); 2261 fout.increaseIndent(); 2262 for (int i = 0; i < size; i++) { 2263 fout.print("UID="); 2264 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 2265 fout.print(": "); 2266 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 2267 fout.println(); 2268 } 2269 fout.decreaseIndent(); 2270 } 2271 2272 size = mRestrictBackgroundWhitelistUids.size(); 2273 if (size > 0) { 2274 fout.println("Restrict background whitelist uids:"); 2275 fout.increaseIndent(); 2276 for (int i = 0; i < size; i++) { 2277 fout.print("UID="); 2278 fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); 2279 fout.println(); 2280 } 2281 fout.decreaseIndent(); 2282 } 2283 2284 size = mDefaultRestrictBackgroundWhitelistUids.size(); 2285 if (size > 0) { 2286 fout.println("Default restrict background whitelist uids:"); 2287 fout.increaseIndent(); 2288 for (int i = 0; i < size; i++) { 2289 fout.print("UID="); 2290 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); 2291 fout.println(); 2292 } 2293 fout.decreaseIndent(); 2294 } 2295 2296 size = mRestrictBackgroundWhitelistRevokedUids.size(); 2297 if (size > 0) { 2298 fout.println("Default restrict background whitelist uids revoked by users:"); 2299 fout.increaseIndent(); 2300 for (int i = 0; i < size; i++) { 2301 fout.print("UID="); 2302 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); 2303 fout.println(); 2304 } 2305 fout.decreaseIndent(); 2306 } 2307 2308 final SparseBooleanArray knownUids = new SparseBooleanArray(); 2309 collectKeys(mUidState, knownUids); 2310 collectKeys(mUidRules, knownUids); 2311 2312 fout.println("Status for known UIDs:"); 2313 fout.increaseIndent(); 2314 size = knownUids.size(); 2315 for (int i = 0; i < size; i++) { 2316 final int uid = knownUids.keyAt(i); 2317 fout.print("UID="); 2318 fout.print(uid); 2319 2320 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2321 fout.print(" state="); 2322 fout.print(state); 2323 if (state <= ActivityManager.PROCESS_STATE_TOP) { 2324 fout.print(" (fg)"); 2325 } else { 2326 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 2327 ? " (fg svc)" : " (bg)"); 2328 } 2329 2330 final int rule = mUidRules.get(uid, RULE_UNKNOWN); 2331 fout.print(" rule="); 2332 fout.print(ruleToString(rule)); 2333 2334 fout.println(); 2335 } 2336 fout.decreaseIndent(); 2337 } 2338 } 2339 2340 private String ruleToString(int rule) { 2341 return DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule); 2342 } 2343 2344 @Override 2345 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2346 String[] args, ResultReceiver resultReceiver) throws RemoteException { 2347 (new NetworkPolicyManagerShellCommand(mContext, this)).exec( 2348 this, in, out, err, args, resultReceiver); 2349 } 2350 2351 @Override 2352 public boolean isUidForeground(int uid) { 2353 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2354 2355 synchronized (mRulesLock) { 2356 return isUidForegroundLocked(uid); 2357 } 2358 } 2359 2360 private boolean isUidForegroundLocked(int uid) { 2361 return isUidStateForegroundLocked( 2362 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2363 } 2364 2365 private boolean isUidForegroundOnRestrictBackgroundLocked(int uid) { 2366 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2367 return isProcStateAllowedWhileOnRestrictBackgroundLocked(procState); 2368 } 2369 2370 private boolean isUidStateForegroundLocked(int state) { 2371 // only really in foreground when screen is also on 2372 return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP; 2373 } 2374 2375 /** 2376 * Process state of UID changed; if needed, will trigger 2377 * {@link #updateRuleForRestrictBackgroundLocked(int)}. 2378 */ 2379 private void updateUidStateLocked(int uid, int uidState) { 2380 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2381 if (oldUidState != uidState) { 2382 // state changed, push updated rules 2383 mUidState.put(uid, uidState); 2384 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState); 2385 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 2386 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) { 2387 if (mDeviceIdleMode) { 2388 updateRuleForDeviceIdleLocked(uid); 2389 } 2390 if (mRestrictPower) { 2391 updateRuleForRestrictPowerLocked(uid); 2392 } 2393 } 2394 updateNetworkStats(uid, isUidStateForegroundLocked(uidState)); 2395 } 2396 } 2397 2398 private void removeUidStateLocked(int uid) { 2399 final int index = mUidState.indexOfKey(uid); 2400 if (index >= 0) { 2401 final int oldUidState = mUidState.valueAt(index); 2402 mUidState.removeAt(index); 2403 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2404 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, 2405 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2406 if (mDeviceIdleMode) { 2407 updateRuleForDeviceIdleLocked(uid); 2408 } 2409 if (mRestrictPower) { 2410 updateRuleForRestrictPowerLocked(uid); 2411 } 2412 updateNetworkStats(uid, false); 2413 } 2414 } 2415 } 2416 2417 // adjust stats accounting based on foreground status 2418 private void updateNetworkStats(int uid, boolean uidForeground) { 2419 try { 2420 mNetworkStats.setUidForeground(uid, uidForeground); 2421 } catch (RemoteException e) { 2422 // ignored; service lives in system_server 2423 } 2424 } 2425 2426 private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState, 2427 int newUidState) { 2428 final boolean oldForeground = 2429 isProcStateAllowedWhileOnRestrictBackgroundLocked(oldUidState); 2430 final boolean newForeground = 2431 isProcStateAllowedWhileOnRestrictBackgroundLocked(newUidState); 2432 if (oldForeground != newForeground) { 2433 updateRuleForRestrictBackgroundLocked(uid); 2434 } 2435 } 2436 2437 private void updateScreenOn() { 2438 synchronized (mRulesLock) { 2439 try { 2440 mScreenOn = mPowerManager.isInteractive(); 2441 } catch (RemoteException e) { 2442 // ignored; service lives in system_server 2443 } 2444 updateRulesForScreenLocked(); 2445 } 2446 } 2447 2448 /** 2449 * Update rules that might be changed by {@link #mScreenOn} value. 2450 */ 2451 private void updateRulesForScreenLocked() { 2452 // only update rules for anyone with foreground activities 2453 final int size = mUidState.size(); 2454 for (int i = 0; i < size; i++) { 2455 if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 2456 final int uid = mUidState.keyAt(i); 2457 updateRestrictionRulesForUidLocked(uid); 2458 } 2459 } 2460 } 2461 2462 static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) { 2463 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2464 } 2465 2466 static boolean isProcStateAllowedWhileOnRestrictBackgroundLocked(int procState) { 2467 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2468 } 2469 2470 void updateRulesForRestrictPowerLocked() { 2471 updateRulesForWhitelistedPowerSaveLocked(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 2472 mUidFirewallPowerSaveRules); 2473 } 2474 2475 void updateRuleForRestrictPowerLocked(int uid) { 2476 updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2477 } 2478 2479 void updateRulesForDeviceIdleLocked() { 2480 updateRulesForWhitelistedPowerSaveLocked(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 2481 mUidFirewallDozableRules); 2482 } 2483 2484 void updateRuleForDeviceIdleLocked(int uid) { 2485 updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 2486 } 2487 2488 // NOTE: since both fw_dozable and fw_powersave uses the same map 2489 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2490 private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain, 2491 SparseIntArray rules) { 2492 if (enabled) { 2493 // Sync the whitelists before enabling the chain. We don't care about the rules if 2494 // we are disabling the chain. 2495 final SparseIntArray uidRules = rules; 2496 uidRules.clear(); 2497 final List<UserInfo> users = mUserManager.getUsers(); 2498 for (int ui = users.size() - 1; ui >= 0; ui--) { 2499 UserInfo user = users.get(ui); 2500 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2501 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) { 2502 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2503 int uid = UserHandle.getUid(user.id, appId); 2504 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2505 } 2506 } 2507 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { 2508 int appId = mPowerSaveWhitelistAppIds.keyAt(i); 2509 int uid = UserHandle.getUid(user.id, appId); 2510 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2511 } 2512 } 2513 for (int i = mUidState.size() - 1; i >= 0; i--) { 2514 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 2515 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2516 } 2517 } 2518 setUidFirewallRules(chain, uidRules); 2519 } 2520 2521 enableFirewallChainLocked(chain, enabled); 2522 } 2523 2524 // NOTE: since both fw_dozable and fw_powersave uses the same map 2525 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. 2526 private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) { 2527 if (enabled) { 2528 int appId = UserHandle.getAppId(uid); 2529 if (mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId) 2530 || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) { 2531 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 2532 } else { 2533 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 2534 } 2535 } 2536 } 2537 2538 void updateRulesForAppIdleLocked() { 2539 final SparseIntArray uidRules = mUidFirewallStandbyRules; 2540 uidRules.clear(); 2541 2542 // Fully update the app idle firewall chain. 2543 final List<UserInfo> users = mUserManager.getUsers(); 2544 for (int ui = users.size() - 1; ui >= 0; ui--) { 2545 UserInfo user = users.get(ui); 2546 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2547 for (int uid : idleUids) { 2548 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2549 // quick check: if this uid doesn't have INTERNET permission, it 2550 // doesn't have network access anyway, so it is a waste to mess 2551 // with it here. 2552 if (hasInternetPermissions(uid)) { 2553 uidRules.put(uid, FIREWALL_RULE_DENY); 2554 } 2555 } 2556 } 2557 } 2558 2559 setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); 2560 } 2561 2562 void updateRuleForAppIdleLocked(int uid) { 2563 if (!isUidValidForBlacklistRules(uid)) return; 2564 2565 int appId = UserHandle.getAppId(uid); 2566 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)) { 2567 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2568 } else { 2569 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2570 } 2571 } 2572 2573 void updateRulesForAppIdleParoleLocked() { 2574 boolean enableChain = !mUsageStats.isAppIdleParoleOn(); 2575 enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); 2576 } 2577 2578 /** 2579 * Update rules that might be changed by {@link #mRestrictBackground}, 2580 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 2581 */ 2582 private void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) { 2583 long start; 2584 if (LOGD) start = System.currentTimeMillis(); 2585 2586 updateRulesForDeviceIdleLocked(); 2587 updateRulesForAppIdleLocked(); 2588 updateRulesForRestrictPowerLocked(); 2589 updateRulesForRestrictBackgroundLocked(); 2590 setRestrictBackgroundLocked(mRestrictBackground); 2591 2592 // If the set of restricted networks may have changed, re-evaluate those. 2593 if (restrictedNetworksChanged) { 2594 normalizePoliciesLocked(); 2595 updateNetworkRulesLocked(); 2596 } 2597 if (LOGD) { 2598 final long delta = System.currentTimeMillis() - start; 2599 Slog.d(TAG, "updateRulesForGlobalChangeLocked(" + restrictedNetworksChanged + ") took " 2600 + delta + "ms"); 2601 } 2602 } 2603 2604 private void updateRulesForRestrictBackgroundLocked() { 2605 final PackageManager pm = mContext.getPackageManager(); 2606 2607 // update rules for all installed applications 2608 final List<UserInfo> users = mUserManager.getUsers(); 2609 final List<ApplicationInfo> apps = pm.getInstalledApplications( 2610 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS 2611 | PackageManager.MATCH_DIRECT_BOOT_AWARE 2612 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2613 2614 final int usersSize = users.size(); 2615 final int appsSize = apps.size(); 2616 for (int i = 0; i < usersSize; i++) { 2617 final UserInfo user = users.get(i); 2618 for (int j = 0; j < appsSize; j++) { 2619 final ApplicationInfo app = apps.get(j); 2620 final int uid = UserHandle.getUid(user.id, app.uid); 2621 updateRuleForRestrictBackgroundLocked(uid); 2622 } 2623 } 2624 } 2625 2626 private void updateRulesForTempWhitelistChangeLocked() { 2627 final List<UserInfo> users = mUserManager.getUsers(); 2628 for (int i = 0; i < users.size(); i++) { 2629 final UserInfo user = users.get(i); 2630 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { 2631 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); 2632 int uid = UserHandle.getUid(user.id, appId); 2633 updateRuleForAppIdleLocked(uid); 2634 updateRuleForDeviceIdleLocked(uid); 2635 updateRuleForRestrictPowerLocked(uid); 2636 } 2637 } 2638 } 2639 2640 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 2641 // methods below could be merged into a isUidValidForRules() method. 2642 private boolean isUidValidForBlacklistRules(int uid) { 2643 // allow rules on specific system services, and any apps 2644 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 2645 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) { 2646 return true; 2647 } 2648 2649 return false; 2650 } 2651 2652 private boolean isUidValidForWhitelistRules(int uid) { 2653 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 2654 } 2655 2656 private boolean isUidIdle(int uid) { 2657 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 2658 final int userId = UserHandle.getUserId(uid); 2659 2660 if (!ArrayUtils.isEmpty(packages)) { 2661 for (String packageName : packages) { 2662 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 2663 return false; 2664 } 2665 } 2666 } 2667 return true; 2668 } 2669 2670 /** 2671 * Checks if an uid has INTERNET permissions. 2672 * <p> 2673 * Useful for the cases where the lack of network access can simplify the rules. 2674 */ 2675 private boolean hasInternetPermissions(int uid) { 2676 try { 2677 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) 2678 != PackageManager.PERMISSION_GRANTED) { 2679 return false; 2680 } 2681 } catch (RemoteException e) { 2682 } 2683 return true; 2684 } 2685 2686 /** 2687 * Applies network rules to bandwidth and firewall controllers based on uid policy. 2688 * 2689 * <p>There are currently 2 types of restriction rules: 2690 * <ul> 2691 * <li>Battery Saver Mode (also referred as power save). 2692 * <li>Data Saver Mode (formerly known as restrict background data). 2693 * </ul> 2694 */ 2695 private void updateRestrictionRulesForUidLocked(int uid) { 2696 updateRuleForRestrictPowerLocked(uid); 2697 updateRuleForRestrictBackgroundLocked(uid); 2698 } 2699 2700 /** 2701 * Applies network rules to bandwidth controllers based on process state and user-defined 2702 * restrictions (blacklist / whitelist). 2703 * 2704 * <p> 2705 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 2706 * networks: 2707 * <ul> 2708 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). 2709 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're 2710 * also blacklisted. 2711 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 2712 * no UIDs other those whitelisted will have access. 2713 * <ul> 2714 * 2715 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 2716 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / 2717 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist 2718 * respectively): these methods set the proper internal state (blacklist / whitelist), then call 2719 * this ({@link #updateRuleForRestrictBackgroundLocked(int)}) to propagate the rules to 2720 * {@link INetworkManagementService}, but this method should also be called in events (like 2721 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 2722 * following rules should also be applied: 2723 * 2724 * <ul> 2725 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 2726 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 2727 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from 2728 * {@code bw_penalty_box}. 2729 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 2730 * </ul> 2731 * 2732 * <p>For optimization, the rules are only applied on user apps that have internet access 2733 * permission, since there is no need to change the {@code iptables} rule if the app does not 2734 * have permission to use the internet. 2735 * 2736 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID. 2737 */ 2738 private void updateRuleForRestrictBackgroundLocked(int uid) { 2739 updateRuleForRestrictBackgroundLocked(uid, false); 2740 } 2741 2742 /** 2743 * Overloaded version of {@link #updateRuleForRestrictBackgroundLocked(int)} called when an 2744 * app is removed - it ignores the UID validity check. 2745 */ 2746 private void updateRuleForRestrictBackgroundLocked(int uid, boolean uidDeleted) { 2747 if (!uidDeleted && !isUidValidForWhitelistRules(uid)) { 2748 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 2749 return; 2750 } 2751 2752 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2753 final boolean isForeground = isUidForegroundOnRestrictBackgroundLocked(uid); 2754 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 2755 final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid); 2756 2757 int newRule = RULE_ALLOW_ALL; 2758 final int oldRule = mUidRules.get(uid); 2759 2760 // First step: define the new rule based on user restrictions and foreground state. 2761 if (isForeground) { 2762 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { 2763 newRule = RULE_TEMPORARY_ALLOW_METERED; 2764 } 2765 } else { 2766 if (isBlacklisted) { 2767 newRule = RULE_REJECT_METERED; 2768 } else if (isWhitelisted) { 2769 newRule = RULE_ALLOW_METERED; 2770 } 2771 } 2772 2773 if (LOGV) { 2774 Log.v(TAG, "updateRuleForRestrictBackgroundLocked(" + uid + "):" 2775 + " isForeground=" +isForeground + ", isBlacklisted: " + isBlacklisted 2776 + ", isWhitelisted: " + isWhitelisted + ", newRule: " + ruleToString(newRule) 2777 + ", oldRule: " + ruleToString(oldRule)); 2778 } 2779 2780 2781 if (newRule == RULE_ALLOW_ALL) { 2782 mUidRules.delete(uid); 2783 } else { 2784 mUidRules.put(uid, newRule); 2785 } 2786 2787 // Second step: apply bw changes based on change of state. 2788 if (newRule != oldRule) { 2789 if (newRule == RULE_TEMPORARY_ALLOW_METERED) { 2790 // Temporarily whitelist foreground app, removing from blacklist if necessary 2791 // (since bw_penalty_box prevails over bw_happy_box). 2792 2793 setMeteredNetworkWhitelist(uid, true); 2794 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, 2795 // but ideally it should be just: 2796 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2797 if (isBlacklisted) { 2798 setMeteredNetworkBlacklist(uid, false); 2799 } 2800 } else if (oldRule == RULE_TEMPORARY_ALLOW_METERED) { 2801 // Remove temporary whitelist from app that is not on foreground anymore. 2802 2803 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, 2804 // but ideally they should be just: 2805 // setMeteredNetworkWhitelist(uid, isWhitelisted); 2806 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2807 if (!isWhitelisted) { 2808 setMeteredNetworkWhitelist(uid, false); 2809 } 2810 if (isBlacklisted) { 2811 setMeteredNetworkBlacklist(uid, true); 2812 } 2813 } else if (newRule == RULE_REJECT_METERED || oldRule == RULE_REJECT_METERED) { 2814 // Flip state because app was explicitly added or removed to blacklist. 2815 setMeteredNetworkBlacklist(uid, isBlacklisted); 2816 if (oldRule == RULE_REJECT_METERED && isWhitelisted) { 2817 // Since blacklist prevails over whitelist, we need to handle the special case 2818 // where app is whitelisted and blacklisted at the same time (although such 2819 // scenario should be blocked by the UI), then blacklist is removed. 2820 setMeteredNetworkWhitelist(uid, isWhitelisted); 2821 } 2822 } else if (newRule == RULE_ALLOW_METERED || oldRule == RULE_ALLOW_METERED) { 2823 // Flip state because app was explicitly added or removed to whitelist. 2824 setMeteredNetworkWhitelist(uid, isWhitelisted); 2825 } else { 2826 // All scenarios should have been covered above 2827 Log.wtf(TAG, "Unexpected change of state for " + uid 2828 + ": foreground=" + isForeground + ", whitelisted=" + isWhitelisted 2829 + ", blacklisted=" + isBlacklisted + ", newRule=" 2830 + ruleToString(newRule) + ", oldRule=" + ruleToString(oldRule)); 2831 } 2832 2833 // dispatch changed rule to existing listeners 2834 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newRule).sendToTarget(); 2835 } 2836 } 2837 2838 private class AppIdleStateChangeListener 2839 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 2840 2841 @Override 2842 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 2843 try { 2844 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 2845 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 2846 synchronized (mRulesLock) { 2847 updateRuleForAppIdleLocked(uid); 2848 } 2849 } catch (NameNotFoundException nnfe) { 2850 } 2851 } 2852 2853 @Override 2854 public void onParoleStateChanged(boolean isParoleOn) { 2855 synchronized (mRulesLock) { 2856 updateRulesForAppIdleParoleLocked(); 2857 } 2858 } 2859 } 2860 2861 private Handler.Callback mHandlerCallback = new Handler.Callback() { 2862 @Override 2863 public boolean handleMessage(Message msg) { 2864 switch (msg.what) { 2865 case MSG_RULES_CHANGED: { 2866 final int uid = msg.arg1; 2867 final int uidRules = msg.arg2; 2868 final int length = mListeners.beginBroadcast(); 2869 for (int i = 0; i < length; i++) { 2870 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2871 if (listener != null) { 2872 try { 2873 listener.onUidRulesChanged(uid, uidRules); 2874 } catch (RemoteException e) { 2875 } 2876 } 2877 } 2878 mListeners.finishBroadcast(); 2879 return true; 2880 } 2881 case MSG_METERED_IFACES_CHANGED: { 2882 final String[] meteredIfaces = (String[]) msg.obj; 2883 final int length = mListeners.beginBroadcast(); 2884 for (int i = 0; i < length; i++) { 2885 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2886 if (listener != null) { 2887 try { 2888 listener.onMeteredIfacesChanged(meteredIfaces); 2889 } catch (RemoteException e) { 2890 } 2891 } 2892 } 2893 mListeners.finishBroadcast(); 2894 return true; 2895 } 2896 case MSG_LIMIT_REACHED: { 2897 final String iface = (String) msg.obj; 2898 2899 maybeRefreshTrustedTime(); 2900 synchronized (mRulesLock) { 2901 if (mMeteredIfaces.contains(iface)) { 2902 try { 2903 // force stats update to make sure we have 2904 // numbers that caused alert to trigger. 2905 mNetworkStats.forceUpdate(); 2906 } catch (RemoteException e) { 2907 // ignored; service lives in system_server 2908 } 2909 2910 updateNetworkEnabledLocked(); 2911 updateNotificationsLocked(); 2912 } 2913 } 2914 return true; 2915 } 2916 case MSG_RESTRICT_BACKGROUND_CHANGED: { 2917 final boolean restrictBackground = msg.arg1 != 0; 2918 final int length = mListeners.beginBroadcast(); 2919 for (int i = 0; i < length; i++) { 2920 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2921 if (listener != null) { 2922 try { 2923 listener.onRestrictBackgroundChanged(restrictBackground); 2924 } catch (RemoteException e) { 2925 } 2926 } 2927 } 2928 mListeners.finishBroadcast(); 2929 final Intent intent = 2930 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 2931 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2932 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 2933 return true; 2934 } 2935 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { 2936 // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: 2937 // - when an app is whitelisted 2938 // - when an app is blacklisted 2939 // 2940 // Whether the internal listeners (INetworkPolicyListener implementations) or 2941 // app broadcast receivers are notified depend on the following rules: 2942 // 2943 // - App receivers are only notified when the app status changed (msg.arg2 = 1) 2944 // - Listeners are only notified when app was whitelisted (msg.obj is not null), 2945 // since blacklist notifications are handled through MSG_RULES_CHANGED). 2946 final int uid = msg.arg1; 2947 final boolean changed = msg.arg2 == 1; 2948 final Boolean whitelisted = (Boolean) msg.obj; 2949 2950 if (whitelisted != null) { 2951 final int length = mListeners.beginBroadcast(); 2952 for (int i = 0; i < length; i++) { 2953 // First notify internal listeners... 2954 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2955 if (listener != null) { 2956 try { 2957 listener.onRestrictBackgroundWhitelistChanged(uid, 2958 whitelisted.booleanValue()); 2959 } catch (RemoteException e) { 2960 } 2961 } 2962 } 2963 mListeners.finishBroadcast(); 2964 } 2965 2966 final PackageManager pm = mContext.getPackageManager(); 2967 final String[] packages = pm.getPackagesForUid(uid); 2968 if (changed && packages != null) { 2969 // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 2970 final int userId = UserHandle.getUserId(uid); 2971 for (String packageName : packages) { 2972 final Intent intent = new Intent( 2973 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 2974 intent.setPackage(packageName); 2975 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2976 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 2977 } 2978 } 2979 return true; 2980 } 2981 case MSG_ADVISE_PERSIST_THRESHOLD: { 2982 final long lowestRule = (Long) msg.obj; 2983 try { 2984 // make sure stats are recorded frequently enough; we aim 2985 // for 2MB threshold for 2GB/month rules. 2986 final long persistThreshold = lowestRule / 1000; 2987 mNetworkStats.advisePersistThreshold(persistThreshold); 2988 } catch (RemoteException e) { 2989 // ignored; service lives in system_server 2990 } 2991 return true; 2992 } 2993 case MSG_SCREEN_ON_CHANGED: { 2994 updateScreenOn(); 2995 return true; 2996 } 2997 case MSG_UPDATE_INTERFACE_QUOTA: { 2998 removeInterfaceQuota((String) msg.obj); 2999 // int params need to be stitched back into a long 3000 setInterfaceQuota((String) msg.obj, 3001 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); 3002 return true; 3003 } 3004 case MSG_REMOVE_INTERFACE_QUOTA: { 3005 removeInterfaceQuota((String) msg.obj); 3006 return true; 3007 } 3008 default: { 3009 return false; 3010 } 3011 } 3012 } 3013 }; 3014 3015 private void setInterfaceQuota(String iface, long quotaBytes) { 3016 try { 3017 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 3018 } catch (IllegalStateException e) { 3019 Log.wtf(TAG, "problem setting interface quota", e); 3020 } catch (RemoteException e) { 3021 // ignored; service lives in system_server 3022 } 3023 } 3024 3025 private void removeInterfaceQuota(String iface) { 3026 try { 3027 mNetworkManager.removeInterfaceQuota(iface); 3028 } catch (IllegalStateException e) { 3029 Log.wtf(TAG, "problem removing interface quota", e); 3030 } catch (RemoteException e) { 3031 // ignored; service lives in system_server 3032 } 3033 } 3034 3035 private void setMeteredNetworkBlacklist(int uid, boolean enable) { 3036 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); 3037 try { 3038 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); 3039 } catch (IllegalStateException e) { 3040 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); 3041 } catch (RemoteException e) { 3042 // ignored; service lives in system_server 3043 } 3044 } 3045 3046 private void setMeteredNetworkWhitelist(int uid, boolean enable) { 3047 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); 3048 try { 3049 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); 3050 } catch (IllegalStateException e) { 3051 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); 3052 } catch (RemoteException e) { 3053 // ignored; service lives in system_server 3054 } 3055 } 3056 3057 /** 3058 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 3059 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 3060 * specified here. 3061 */ 3062 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 3063 try { 3064 int size = uidRules.size(); 3065 int[] uids = new int[size]; 3066 int[] rules = new int[size]; 3067 for(int index = size - 1; index >= 0; --index) { 3068 uids[index] = uidRules.keyAt(index); 3069 rules[index] = uidRules.valueAt(index); 3070 } 3071 mNetworkManager.setFirewallUidRules(chain, uids, rules); 3072 } catch (IllegalStateException e) { 3073 Log.wtf(TAG, "problem setting firewall uid rules", e); 3074 } catch (RemoteException e) { 3075 // ignored; service lives in system_server 3076 } 3077 } 3078 3079 /** 3080 * Add or remove a uid to the firewall blacklist for all network ifaces. 3081 */ 3082 private void setUidFirewallRule(int chain, int uid, int rule) { 3083 if (chain == FIREWALL_CHAIN_DOZABLE) { 3084 mUidFirewallDozableRules.put(uid, rule); 3085 } else if (chain == FIREWALL_CHAIN_STANDBY) { 3086 mUidFirewallStandbyRules.put(uid, rule); 3087 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 3088 mUidFirewallPowerSaveRules.put(uid, rule); 3089 } 3090 3091 try { 3092 mNetworkManager.setFirewallUidRule(chain, uid, rule); 3093 } catch (IllegalStateException e) { 3094 Log.wtf(TAG, "problem setting firewall uid rules", e); 3095 } catch (RemoteException e) { 3096 // ignored; service lives in system_server 3097 } 3098 } 3099 3100 /** 3101 * Add or remove a uid to the firewall blacklist for all network ifaces. 3102 */ 3103 private void enableFirewallChainLocked(int chain, boolean enable) { 3104 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 3105 mFirewallChainStates.get(chain) == enable) { 3106 // All is the same, nothing to do. 3107 return; 3108 } 3109 mFirewallChainStates.put(chain, enable); 3110 try { 3111 mNetworkManager.setFirewallChainEnabled(chain, enable); 3112 } catch (IllegalStateException e) { 3113 Log.wtf(TAG, "problem enable firewall chain", e); 3114 } catch (RemoteException e) { 3115 // ignored; service lives in system_server 3116 } 3117 } 3118 3119 private long getTotalBytes(NetworkTemplate template, long start, long end) { 3120 try { 3121 return mNetworkStats.getNetworkTotalBytes(template, start, end); 3122 } catch (RuntimeException e) { 3123 Slog.w(TAG, "problem reading network stats: " + e); 3124 return 0; 3125 } catch (RemoteException e) { 3126 // ignored; service lives in system_server 3127 return 0; 3128 } 3129 } 3130 3131 private boolean isBandwidthControlEnabled() { 3132 final long token = Binder.clearCallingIdentity(); 3133 try { 3134 return mNetworkManager.isBandwidthControlEnabled(); 3135 } catch (RemoteException e) { 3136 // ignored; service lives in system_server 3137 return false; 3138 } finally { 3139 Binder.restoreCallingIdentity(token); 3140 } 3141 } 3142 3143 /** 3144 * Try refreshing {@link #mTime} when stale. 3145 */ 3146 void maybeRefreshTrustedTime() { 3147 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3148 mTime.forceRefresh(); 3149 } 3150 } 3151 3152 private long currentTimeMillis() { 3153 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3154 } 3155 3156 private static Intent buildAllowBackgroundDataIntent() { 3157 return new Intent(ACTION_ALLOW_BACKGROUND); 3158 } 3159 3160 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 3161 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 3162 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3163 return intent; 3164 } 3165 3166 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 3167 final Intent intent = new Intent(); 3168 intent.setComponent(new ComponentName( 3169 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 3170 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3171 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3172 return intent; 3173 } 3174 3175 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 3176 final Intent intent = new Intent(); 3177 intent.setComponent(new ComponentName( 3178 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 3179 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3180 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3181 return intent; 3182 } 3183 3184 @VisibleForTesting 3185 public void addIdleHandler(IdleHandler handler) { 3186 mHandler.getLooper().getQueue().addIdleHandler(handler); 3187 } 3188 3189 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3190 final int size = source.size(); 3191 for (int i = 0; i < size; i++) { 3192 target.put(source.keyAt(i), true); 3193 } 3194 } 3195 3196 @Override 3197 public void factoryReset(String subscriber) { 3198 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 3199 3200 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3201 return; 3202 } 3203 3204 // Turn mobile data limit off 3205 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 3206 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 3207 for (NetworkPolicy policy : policies) { 3208 if (policy.template.equals(template)) { 3209 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 3210 policy.inferred = false; 3211 policy.clearSnooze(); 3212 } 3213 } 3214 setNetworkPolicies(policies); 3215 3216 // Turn restrict background data off 3217 setRestrictBackground(false); 3218 3219 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 3220 // Remove app's "restrict background data" flag 3221 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 3222 setUidPolicy(uid, POLICY_NONE); 3223 } 3224 } 3225 } 3226 3227 private class MyPackageMonitor extends PackageMonitor { 3228 3229 @Override 3230 public void onPackageRemoved(String packageName, int uid) { 3231 if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); 3232 synchronized (mRulesLock) { 3233 removeRestrictBackgroundWhitelistedUidLocked(uid, true, true); 3234 } 3235 } 3236 } 3237} 3238