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