NetworkPolicyManagerService.java revision 908109c1f909cbeeb766f551c16121ddd1a3adba
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.TYPE_MOBILE; 33import static android.net.ConnectivityManager.TYPE_WIMAX; 34import static android.net.ConnectivityManager.isNetworkTypeMobile; 35import static android.net.NetworkPolicy.CYCLE_NONE; 36import static android.net.NetworkPolicy.LIMIT_DISABLED; 37import static android.net.NetworkPolicy.SNOOZE_NEVER; 38import static android.net.NetworkPolicy.WARNING_DISABLED; 39import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 40import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; 41import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; 42import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 43import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; 44import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; 45import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE; 46import static android.net.NetworkPolicyManager.POLICY_NONE; 47import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 48import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 49import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 50import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 51import static android.net.NetworkPolicyManager.dumpPolicy; 52import static android.net.NetworkPolicyManager.dumpRules; 53import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 54import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 55import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 56import static android.net.NetworkTemplate.MATCH_WIFI; 57import static android.net.NetworkTemplate.buildTemplateMobileAll; 58import static android.net.TrafficStats.MB_IN_BYTES; 59import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 60import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 61import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 62import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 63import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 64import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 65import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 66import static android.text.format.DateUtils.DAY_IN_MILLIS; 67import static com.android.internal.util.ArrayUtils.appendInt; 68import static com.android.internal.util.Preconditions.checkNotNull; 69import static com.android.internal.util.XmlUtils.readBooleanAttribute; 70import static com.android.internal.util.XmlUtils.readIntAttribute; 71import static com.android.internal.util.XmlUtils.readLongAttribute; 72import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 73import static com.android.internal.util.XmlUtils.writeIntAttribute; 74import static com.android.internal.util.XmlUtils.writeLongAttribute; 75import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 76import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 77import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 78import static org.xmlpull.v1.XmlPullParser.START_TAG; 79 80import android.Manifest; 81import android.app.ActivityManager; 82import android.app.AppGlobals; 83import android.app.AppOpsManager; 84import android.app.IActivityManager; 85import android.app.INotificationManager; 86import android.app.IUidObserver; 87import android.app.Notification; 88import android.app.PendingIntent; 89import android.app.usage.UsageStatsManagerInternal; 90import android.content.BroadcastReceiver; 91import android.content.ComponentName; 92import android.content.Context; 93import android.content.Intent; 94import android.content.IntentFilter; 95import android.content.pm.ApplicationInfo; 96import android.content.pm.IPackageManager; 97import android.content.pm.PackageManager; 98import android.content.pm.PackageManager.NameNotFoundException; 99import android.content.pm.UserInfo; 100import android.content.res.Resources; 101import android.net.ConnectivityManager; 102import android.net.IConnectivityManager; 103import android.net.INetworkManagementEventObserver; 104import android.net.INetworkPolicyListener; 105import android.net.INetworkPolicyManager; 106import android.net.INetworkStatsService; 107import android.net.LinkProperties; 108import android.net.NetworkIdentity; 109import android.net.NetworkInfo; 110import android.net.NetworkPolicy; 111import android.net.NetworkQuotaInfo; 112import android.net.NetworkState; 113import android.net.NetworkTemplate; 114import android.net.wifi.WifiConfiguration; 115import android.net.wifi.WifiInfo; 116import android.net.wifi.WifiManager; 117import android.os.Binder; 118import android.os.Environment; 119import android.os.Handler; 120import android.os.HandlerThread; 121import android.os.IDeviceIdleController; 122import android.os.INetworkManagementService; 123import android.os.IPowerManager; 124import android.os.Message; 125import android.os.MessageQueue.IdleHandler; 126import android.os.PowerManager; 127import android.os.PowerManagerInternal; 128import android.os.RemoteCallbackList; 129import android.os.RemoteException; 130import android.os.ServiceManager; 131import android.os.UserHandle; 132import android.os.UserManager; 133import android.provider.Settings; 134import android.telephony.SubscriptionManager; 135import android.telephony.TelephonyManager; 136import android.text.format.Formatter; 137import android.text.format.Time; 138import android.util.ArrayMap; 139import android.util.ArraySet; 140import android.util.AtomicFile; 141import android.util.Log; 142import android.util.NtpTrustedTime; 143import android.util.Pair; 144import android.util.Slog; 145import android.util.SparseBooleanArray; 146import android.util.SparseIntArray; 147import android.util.TrustedTime; 148import android.util.Xml; 149 150import com.android.server.DeviceIdleController; 151import com.android.server.EventLogTags; 152import libcore.io.IoUtils; 153 154import com.android.internal.R; 155import com.android.internal.annotations.VisibleForTesting; 156import com.android.internal.util.ArrayUtils; 157import com.android.internal.util.FastXmlSerializer; 158import com.android.internal.util.IndentingPrintWriter; 159import com.android.server.LocalServices; 160import com.google.android.collect.Lists; 161 162import org.xmlpull.v1.XmlPullParser; 163import org.xmlpull.v1.XmlPullParserException; 164import org.xmlpull.v1.XmlSerializer; 165 166import java.io.File; 167import java.io.FileDescriptor; 168import java.io.FileInputStream; 169import java.io.FileNotFoundException; 170import java.io.FileOutputStream; 171import java.io.IOException; 172import java.io.PrintWriter; 173import java.nio.charset.StandardCharsets; 174import java.util.ArrayList; 175import java.util.Arrays; 176import java.util.List; 177 178/** 179 * Service that maintains low-level network policy rules, using 180 * {@link NetworkStatsService} statistics to drive those rules. 181 * <p> 182 * Derives active rules by combining a given policy with other system status, 183 * and delivers to listeners, such as {@link ConnectivityManager}, for 184 * enforcement. 185 */ 186public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 187 private static final String TAG = "NetworkPolicy"; 188 private static final boolean LOGD = false; 189 private static final boolean LOGV = false; 190 191 private static final int VERSION_INIT = 1; 192 private static final int VERSION_ADDED_SNOOZE = 2; 193 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 194 private static final int VERSION_ADDED_METERED = 4; 195 private static final int VERSION_SPLIT_SNOOZE = 5; 196 private static final int VERSION_ADDED_TIMEZONE = 6; 197 private static final int VERSION_ADDED_INFERRED = 7; 198 private static final int VERSION_SWITCH_APP_ID = 8; 199 private static final int VERSION_ADDED_NETWORK_ID = 9; 200 private static final int VERSION_SWITCH_UID = 10; 201 private static final int VERSION_LATEST = VERSION_SWITCH_UID; 202 203 @VisibleForTesting 204 public static final int TYPE_WARNING = 0x1; 205 @VisibleForTesting 206 public static final int TYPE_LIMIT = 0x2; 207 @VisibleForTesting 208 public static final int TYPE_LIMIT_SNOOZED = 0x3; 209 210 private static final String TAG_POLICY_LIST = "policy-list"; 211 private static final String TAG_NETWORK_POLICY = "network-policy"; 212 private static final String TAG_UID_POLICY = "uid-policy"; 213 private static final String TAG_APP_POLICY = "app-policy"; 214 215 private static final String ATTR_VERSION = "version"; 216 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 217 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 218 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 219 private static final String ATTR_NETWORK_ID = "networkId"; 220 private static final String ATTR_CYCLE_DAY = "cycleDay"; 221 private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 222 private static final String ATTR_WARNING_BYTES = "warningBytes"; 223 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 224 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 225 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 226 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 227 private static final String ATTR_METERED = "metered"; 228 private static final String ATTR_INFERRED = "inferred"; 229 private static final String ATTR_UID = "uid"; 230 private static final String ATTR_APP_ID = "appId"; 231 private static final String ATTR_POLICY = "policy"; 232 233 private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground"; 234 235 private static final String ACTION_ALLOW_BACKGROUND = 236 "com.android.server.net.action.ALLOW_BACKGROUND"; 237 private static final String ACTION_SNOOZE_WARNING = 238 "com.android.server.net.action.SNOOZE_WARNING"; 239 240 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 241 242 private static final int MSG_RULES_CHANGED = 1; 243 private static final int MSG_METERED_IFACES_CHANGED = 2; 244 private static final int MSG_LIMIT_REACHED = 5; 245 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 246 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 247 private static final int MSG_SCREEN_ON_CHANGED = 8; 248 249 private final Context mContext; 250 private final IActivityManager mActivityManager; 251 private final IPowerManager mPowerManager; 252 private final INetworkStatsService mNetworkStats; 253 private final INetworkManagementService mNetworkManager; 254 private UsageStatsManagerInternal mUsageStats; 255 private final TrustedTime mTime; 256 private final UserManager mUserManager; 257 258 private IConnectivityManager mConnManager; 259 private INotificationManager mNotifManager; 260 private PowerManagerInternal mPowerManagerInternal; 261 private IDeviceIdleController mDeviceIdleController; 262 263 final Object mRulesLock = new Object(); 264 265 volatile boolean mSystemReady; 266 volatile boolean mScreenOn; 267 volatile boolean mRestrictBackground; 268 volatile boolean mRestrictPower; 269 volatile boolean mDeviceIdleMode; 270 271 private final boolean mSuppressDefaultPolicy; 272 273 /** Defined network policies. */ 274 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); 275 /** Currently active network rules for ifaces. */ 276 final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>(); 277 278 /** Defined UID policies. */ 279 final SparseIntArray mUidPolicy = new SparseIntArray(); 280 /** Currently derived rules for each UID. */ 281 final SparseIntArray mUidRules = new SparseIntArray(); 282 283 /** 284 * UIDs that have been white-listed to always be able to have network access 285 * in power save mode, except device idle (doze) still applies. 286 * TODO: An int array might be sufficient 287 */ 288 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 289 290 /** 291 * UIDs that have been white-listed to always be able to have network access 292 * in power save mode. 293 * TODO: An int array might be sufficient 294 */ 295 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); 296 297 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); 298 299 /** Set of ifaces that are metered. */ 300 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 301 /** Set of over-limit templates that have been notified. */ 302 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>(); 303 304 /** Set of currently active {@link Notification} tags. */ 305 private final ArraySet<String> mActiveNotifs = new ArraySet<String>(); 306 307 /** Foreground at UID granularity. */ 308 final SparseIntArray mUidState = new SparseIntArray(); 309 310 private final RemoteCallbackList<INetworkPolicyListener> 311 mListeners = new RemoteCallbackList<>(); 312 313 final Handler mHandler; 314 315 private final AtomicFile mPolicyFile; 316 317 private final AppOpsManager mAppOps; 318 319 // TODO: keep whitelist of system-critical services that should never have 320 // rules enforced, such as system, phone, and radio UIDs. 321 322 // TODO: migrate notifications to SystemUI 323 324 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 325 IPowerManager powerManager, INetworkStatsService networkStats, 326 INetworkManagementService networkManagement) { 327 this(context, activityManager, powerManager, networkStats, networkManagement, 328 NtpTrustedTime.getInstance(context), getSystemDir(), false); 329 } 330 331 private static File getSystemDir() { 332 return new File(Environment.getDataDirectory(), "system"); 333 } 334 335 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 336 IPowerManager powerManager, INetworkStatsService networkStats, 337 INetworkManagementService networkManagement, TrustedTime time, File systemDir, 338 boolean suppressDefaultPolicy) { 339 mContext = checkNotNull(context, "missing context"); 340 mActivityManager = checkNotNull(activityManager, "missing activityManager"); 341 mPowerManager = checkNotNull(powerManager, "missing powerManager"); 342 mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 343 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 344 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService( 345 Context.DEVICE_IDLE_CONTROLLER)); 346 mTime = checkNotNull(time, "missing TrustedTime"); 347 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 348 349 HandlerThread thread = new HandlerThread(TAG); 350 thread.start(); 351 mHandler = new Handler(thread.getLooper(), mHandlerCallback); 352 353 mSuppressDefaultPolicy = suppressDefaultPolicy; 354 355 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 356 357 mAppOps = context.getSystemService(AppOpsManager.class); 358 } 359 360 public void bindConnectivityManager(IConnectivityManager connManager) { 361 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 362 } 363 364 public void bindNotificationManager(INotificationManager notifManager) { 365 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 366 } 367 368 void updatePowerSaveWhitelistLocked() { 369 try { 370 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle(); 371 mPowerSaveWhitelistExceptIdleAppIds.clear(); 372 if (whitelist != null) { 373 for (int uid : whitelist) { 374 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); 375 } 376 } 377 whitelist = mDeviceIdleController.getAppIdWhitelist(); 378 mPowerSaveWhitelistAppIds.clear(); 379 if (whitelist != null) { 380 for (int uid : whitelist) { 381 mPowerSaveWhitelistAppIds.put(uid, true); 382 } 383 } 384 } catch (RemoteException e) { 385 } 386 } 387 388 void updatePowerSaveTempWhitelistLocked() { 389 try { 390 // Clear the states of the current whitelist 391 final int N = mPowerSaveTempWhitelistAppIds.size(); 392 for (int i = 0; i < N; i++) { 393 mPowerSaveTempWhitelistAppIds.setValueAt(i, false); 394 } 395 // Update the states with the new whitelist 396 final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist(); 397 if (whitelist != null) { 398 for (int uid : whitelist) { 399 mPowerSaveTempWhitelistAppIds.put(uid, true); 400 } 401 } 402 } catch (RemoteException e) { 403 } 404 } 405 406 /** 407 * Remove unnecessary entries in the temp whitelist 408 */ 409 void purgePowerSaveTempWhitelistLocked() { 410 final int N = mPowerSaveTempWhitelistAppIds.size(); 411 for (int i = N - 1; i >= 0; i--) { 412 if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) { 413 mPowerSaveTempWhitelistAppIds.removeAt(i); 414 } 415 } 416 } 417 418 public void systemReady() { 419 if (!isBandwidthControlEnabled()) { 420 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 421 return; 422 } 423 424 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); 425 426 synchronized (mRulesLock) { 427 updatePowerSaveWhitelistLocked(); 428 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 429 mPowerManagerInternal.registerLowPowerModeObserver( 430 new PowerManagerInternal.LowPowerModeListener() { 431 @Override 432 public void onLowPowerModeChanged(boolean enabled) { 433 synchronized (mRulesLock) { 434 if (mRestrictPower != enabled) { 435 mRestrictPower = enabled; 436 updateRulesForGlobalChangeLocked(true); 437 } 438 } 439 } 440 }); 441 mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled(); 442 mSystemReady = true; 443 444 // read policy from disk 445 readPolicyLocked(); 446 447 if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) { 448 updateRulesForGlobalChangeLocked(false); 449 updateNotificationsLocked(); 450 } else { 451 // If we are not in any special mode, we just need to make sure the current 452 // app idle state is updated. 453 updateRulesForAppIdleLocked(); 454 } 455 } 456 457 updateScreenOn(); 458 459 try { 460 mActivityManager.registerUidObserver(mUidObserver); 461 mNetworkManager.registerObserver(mAlertObserver); 462 } catch (RemoteException e) { 463 // ignored; both services live in system_server 464 } 465 466 // TODO: traverse existing processes to know foreground state, or have 467 // activitymanager dispatch current state when new observer attached. 468 469 final IntentFilter screenFilter = new IntentFilter(); 470 screenFilter.addAction(Intent.ACTION_SCREEN_ON); 471 screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 472 mContext.registerReceiver(mScreenReceiver, screenFilter); 473 474 // listen for changes to power save whitelist 475 final IntentFilter whitelistFilter = new IntentFilter( 476 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 477 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); 478 479 DeviceIdleController.LocalService deviceIdleService 480 = LocalServices.getService(DeviceIdleController.LocalService.class); 481 deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback); 482 483 // watch for network interfaces to be claimed 484 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 485 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 486 487 // listen for package changes to update policy 488 final IntentFilter packageFilter = new IntentFilter(); 489 packageFilter.addAction(ACTION_PACKAGE_ADDED); 490 packageFilter.addDataScheme("package"); 491 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 492 493 // listen for UID changes to update policy 494 mContext.registerReceiver( 495 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 496 497 // listen for user changes to update policy 498 final IntentFilter userFilter = new IntentFilter(); 499 userFilter.addAction(ACTION_USER_ADDED); 500 userFilter.addAction(ACTION_USER_REMOVED); 501 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 502 503 // listen for stats update events 504 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 505 mContext.registerReceiver( 506 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 507 508 // listen for restrict background changes from notifications 509 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 510 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 511 512 // listen for snooze warning from notifications 513 final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING); 514 mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter, 515 MANAGE_NETWORK_POLICY, mHandler); 516 517 // listen for configured wifi networks to be removed 518 final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); 519 mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler); 520 521 // listen for wifi state changes to catch metered hint 522 final IntentFilter wifiStateFilter = new IntentFilter( 523 WifiManager.NETWORK_STATE_CHANGED_ACTION); 524 mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); 525 526 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); 527 528 } 529 530 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 531 @Override public void onUidStateChanged(int uid, int procState) throws RemoteException { 532 synchronized (mRulesLock) { 533 updateUidStateLocked(uid, procState); 534 } 535 } 536 537 @Override public void onUidGone(int uid) throws RemoteException { 538 synchronized (mRulesLock) { 539 removeUidStateLocked(uid); 540 } 541 } 542 }; 543 544 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { 545 @Override 546 public void onReceive(Context context, Intent intent) { 547 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected 548 synchronized (mRulesLock) { 549 updatePowerSaveWhitelistLocked(); 550 updateRulesForGlobalChangeLocked(false); 551 } 552 } 553 }; 554 555 final private Runnable mTempPowerSaveChangedCallback = new Runnable() { 556 @Override 557 public void run() { 558 synchronized (mRulesLock) { 559 updatePowerSaveTempWhitelistLocked(); 560 updateRulesForTempWhitelistChangeLocked(); 561 purgePowerSaveTempWhitelistLocked(); 562 } 563 } 564 }; 565 566 final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 567 @Override 568 public void onReceive(Context context, Intent intent) { 569 // screen-related broadcasts are protected by system, no need 570 // for permissions check. 571 mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); 572 } 573 }; 574 575 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 576 @Override 577 public void onReceive(Context context, Intent intent) { 578 // on background handler thread, and PACKAGE_ADDED is protected 579 580 final String action = intent.getAction(); 581 final int uid = intent.getIntExtra(EXTRA_UID, -1); 582 if (uid == -1) return; 583 584 if (ACTION_PACKAGE_ADDED.equals(action)) { 585 // update rules for UID, since it might be subject to 586 // global background data policy 587 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 588 synchronized (mRulesLock) { 589 updateRulesForUidLocked(uid); 590 } 591 } 592 } 593 }; 594 595 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 596 @Override 597 public void onReceive(Context context, Intent intent) { 598 // on background handler thread, and UID_REMOVED is protected 599 600 final int uid = intent.getIntExtra(EXTRA_UID, -1); 601 if (uid == -1) return; 602 603 // remove any policy and update rules to clean up 604 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 605 synchronized (mRulesLock) { 606 mUidPolicy.delete(uid); 607 updateRulesForUidLocked(uid); 608 writePolicyLocked(); 609 } 610 } 611 }; 612 613 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 614 @Override 615 public void onReceive(Context context, Intent intent) { 616 // on background handler thread, and USER_ADDED and USER_REMOVED 617 // broadcasts are protected 618 619 final String action = intent.getAction(); 620 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 621 if (userId == -1) return; 622 623 switch (action) { 624 case ACTION_USER_REMOVED: 625 case ACTION_USER_ADDED: 626 synchronized (mRulesLock) { 627 // Remove any policies for given user; both cleaning up after a 628 // USER_REMOVED, and one last sanity check during USER_ADDED 629 removePoliciesForUserLocked(userId); 630 // Update global restrict for new user 631 updateRulesForGlobalChangeLocked(true); 632 } 633 break; 634 } 635 } 636 }; 637 638 /** 639 * Receiver that watches for {@link INetworkStatsService} updates, which we 640 * use to check against {@link NetworkPolicy#warningBytes}. 641 */ 642 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 643 @Override 644 public void onReceive(Context context, Intent intent) { 645 // on background handler thread, and verified 646 // READ_NETWORK_USAGE_HISTORY permission above. 647 648 maybeRefreshTrustedTime(); 649 synchronized (mRulesLock) { 650 updateNetworkEnabledLocked(); 651 updateNotificationsLocked(); 652 } 653 } 654 }; 655 656 /** 657 * Receiver that watches for {@link Notification} control of 658 * {@link #mRestrictBackground}. 659 */ 660 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 661 @Override 662 public void onReceive(Context context, Intent intent) { 663 // on background handler thread, and verified MANAGE_NETWORK_POLICY 664 // permission above. 665 666 setRestrictBackground(false); 667 } 668 }; 669 670 /** 671 * Receiver that watches for {@link Notification} control of 672 * {@link NetworkPolicy#lastWarningSnooze}. 673 */ 674 final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { 675 @Override 676 public void onReceive(Context context, Intent intent) { 677 // on background handler thread, and verified MANAGE_NETWORK_POLICY 678 // permission above. 679 680 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 681 performSnooze(template, TYPE_WARNING); 682 } 683 }; 684 685 /** 686 * Receiver that watches for {@link WifiConfiguration} to be changed. 687 */ 688 final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { 689 @Override 690 public void onReceive(Context context, Intent intent) { 691 // on background handler thread, and verified CONNECTIVITY_INTERNAL 692 // permission above. 693 694 final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED); 695 if (reason == CHANGE_REASON_REMOVED) { 696 final WifiConfiguration config = intent.getParcelableExtra( 697 EXTRA_WIFI_CONFIGURATION); 698 if (config.SSID != null) { 699 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID); 700 synchronized (mRulesLock) { 701 if (mNetworkPolicy.containsKey(template)) { 702 mNetworkPolicy.remove(template); 703 writePolicyLocked(); 704 } 705 } 706 } 707 } 708 } 709 }; 710 711 /** 712 * Receiver that watches {@link WifiInfo} state changes to infer metered 713 * state. Ignores hints when policy is user-defined. 714 */ 715 final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 716 @Override 717 public void onReceive(Context context, Intent intent) { 718 // on background handler thread, and verified CONNECTIVITY_INTERNAL 719 // permission above. 720 721 // ignore when not connected 722 final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 723 if (!netInfo.isConnected()) return; 724 725 final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO); 726 final boolean meteredHint = info.getMeteredHint(); 727 728 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID()); 729 synchronized (mRulesLock) { 730 NetworkPolicy policy = mNetworkPolicy.get(template); 731 if (policy == null && meteredHint) { 732 // policy doesn't exist, and AP is hinting that it's 733 // metered: create an inferred policy. 734 policy = new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC, 735 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, 736 meteredHint, true); 737 addNetworkPolicyLocked(policy); 738 739 } else if (policy != null && policy.inferred) { 740 // policy exists, and was inferred: update its current 741 // metered state. 742 policy.metered = meteredHint; 743 744 // since this is inferred for each wifi session, just update 745 // rules without persisting. 746 updateNetworkRulesLocked(); 747 } 748 } 749 } 750 }; 751 752 /** 753 * Observer that watches for {@link INetworkManagementService} alerts. 754 */ 755 final private INetworkManagementEventObserver mAlertObserver 756 = new BaseNetworkObserver() { 757 @Override 758 public void limitReached(String limitName, String iface) { 759 // only someone like NMS should be calling us 760 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 761 762 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 763 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 764 } 765 } 766 }; 767 768 /** 769 * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 770 * to show visible notifications as needed. 771 */ 772 void updateNotificationsLocked() { 773 if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 774 775 // keep track of previously active notifications 776 final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs); 777 mActiveNotifs.clear(); 778 779 // TODO: when switching to kernel notifications, compute next future 780 // cycle boundary to recompute notifications. 781 782 // examine stats for each active policy 783 final long currentTime = currentTimeMillis(); 784 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 785 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 786 // ignore policies that aren't relevant to user 787 if (!isTemplateRelevant(policy.template)) continue; 788 if (!policy.hasCycle()) continue; 789 790 final long start = computeLastCycleBoundary(currentTime, policy); 791 final long end = currentTime; 792 final long totalBytes = getTotalBytes(policy.template, start, end); 793 794 if (policy.isOverLimit(totalBytes)) { 795 if (policy.lastLimitSnooze >= start) { 796 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 797 } else { 798 enqueueNotification(policy, TYPE_LIMIT, totalBytes); 799 notifyOverLimitLocked(policy.template); 800 } 801 802 } else { 803 notifyUnderLimitLocked(policy.template); 804 805 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) { 806 enqueueNotification(policy, TYPE_WARNING, totalBytes); 807 } 808 } 809 } 810 811 // ongoing notification when restricting background data 812 if (mRestrictBackground) { 813 enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND); 814 } 815 816 // cancel stale notifications that we didn't renew above 817 for (int i = beforeNotifs.size()-1; i >= 0; i--) { 818 final String tag = beforeNotifs.valueAt(i); 819 if (!mActiveNotifs.contains(tag)) { 820 cancelNotification(tag); 821 } 822 } 823 } 824 825 /** 826 * Test if given {@link NetworkTemplate} is relevant to user based on 827 * current device state, such as when 828 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 829 * data connection status. 830 */ 831 private boolean isTemplateRelevant(NetworkTemplate template) { 832 if (template.isMatchRuleMobile()) { 833 final TelephonyManager tele = TelephonyManager.from(mContext); 834 final SubscriptionManager sub = SubscriptionManager.from(mContext); 835 836 // Mobile template is relevant when any active subscriber matches 837 final int[] subIds = sub.getActiveSubscriptionIdList(); 838 for (int subId : subIds) { 839 final String subscriberId = tele.getSubscriberId(subId); 840 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 841 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false); 842 if (template.matches(probeIdent)) { 843 return true; 844 } 845 } 846 return false; 847 } else { 848 return true; 849 } 850 } 851 852 /** 853 * Notify that given {@link NetworkTemplate} is over 854 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 855 */ 856 private void notifyOverLimitLocked(NetworkTemplate template) { 857 if (!mOverLimitNotified.contains(template)) { 858 mContext.startActivity(buildNetworkOverLimitIntent(template)); 859 mOverLimitNotified.add(template); 860 } 861 } 862 863 private void notifyUnderLimitLocked(NetworkTemplate template) { 864 mOverLimitNotified.remove(template); 865 } 866 867 /** 868 * Build unique tag that identifies an active {@link NetworkPolicy} 869 * notification of a specific type, like {@link #TYPE_LIMIT}. 870 */ 871 private String buildNotificationTag(NetworkPolicy policy, int type) { 872 return TAG + ":" + policy.template.hashCode() + ":" + type; 873 } 874 875 /** 876 * Show notification for combined {@link NetworkPolicy} and specific type, 877 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 878 */ 879 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 880 final String tag = buildNotificationTag(policy, type); 881 final Notification.Builder builder = new Notification.Builder(mContext); 882 builder.setOnlyAlertOnce(true); 883 builder.setWhen(0L); 884 builder.setColor(mContext.getColor( 885 com.android.internal.R.color.system_notification_accent_color)); 886 887 final Resources res = mContext.getResources(); 888 switch (type) { 889 case TYPE_WARNING: { 890 final CharSequence title = res.getText(R.string.data_usage_warning_title); 891 final CharSequence body = res.getString(R.string.data_usage_warning_body); 892 893 builder.setSmallIcon(R.drawable.stat_notify_error); 894 builder.setTicker(title); 895 builder.setContentTitle(title); 896 builder.setContentText(body); 897 898 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template); 899 builder.setDeleteIntent(PendingIntent.getBroadcast( 900 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 901 902 final Intent viewIntent = buildViewDataUsageIntent(policy.template); 903 builder.setContentIntent(PendingIntent.getActivity( 904 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 905 906 break; 907 } 908 case TYPE_LIMIT: { 909 final CharSequence body = res.getText(R.string.data_usage_limit_body); 910 911 final CharSequence title; 912 int icon = R.drawable.stat_notify_disabled_data; 913 switch (policy.template.getMatchRule()) { 914 case MATCH_MOBILE_3G_LOWER: 915 title = res.getText(R.string.data_usage_3g_limit_title); 916 break; 917 case MATCH_MOBILE_4G: 918 title = res.getText(R.string.data_usage_4g_limit_title); 919 break; 920 case MATCH_MOBILE_ALL: 921 title = res.getText(R.string.data_usage_mobile_limit_title); 922 break; 923 case MATCH_WIFI: 924 title = res.getText(R.string.data_usage_wifi_limit_title); 925 icon = R.drawable.stat_notify_error; 926 break; 927 default: 928 title = null; 929 break; 930 } 931 932 builder.setOngoing(true); 933 builder.setSmallIcon(icon); 934 builder.setTicker(title); 935 builder.setContentTitle(title); 936 builder.setContentText(body); 937 938 final Intent intent = buildNetworkOverLimitIntent(policy.template); 939 builder.setContentIntent(PendingIntent.getActivity( 940 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 941 break; 942 } 943 case TYPE_LIMIT_SNOOZED: { 944 final long overBytes = totalBytes - policy.limitBytes; 945 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 946 Formatter.formatFileSize(mContext, overBytes)); 947 948 final CharSequence title; 949 switch (policy.template.getMatchRule()) { 950 case MATCH_MOBILE_3G_LOWER: 951 title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 952 break; 953 case MATCH_MOBILE_4G: 954 title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 955 break; 956 case MATCH_MOBILE_ALL: 957 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 958 break; 959 case MATCH_WIFI: 960 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 961 break; 962 default: 963 title = null; 964 break; 965 } 966 967 builder.setOngoing(true); 968 builder.setSmallIcon(R.drawable.stat_notify_error); 969 builder.setTicker(title); 970 builder.setContentTitle(title); 971 builder.setContentText(body); 972 973 final Intent intent = buildViewDataUsageIntent(policy.template); 974 builder.setContentIntent(PendingIntent.getActivity( 975 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 976 break; 977 } 978 } 979 980 // TODO: move to NotificationManager once we can mock it 981 // XXX what to do about multi-user? 982 try { 983 final String packageName = mContext.getPackageName(); 984 final int[] idReceived = new int[1]; 985 mNotifManager.enqueueNotificationWithTag( 986 packageName, packageName, tag, 0x0, builder.getNotification(), idReceived, 987 UserHandle.USER_OWNER); 988 mActiveNotifs.add(tag); 989 } catch (RemoteException e) { 990 // ignored; service lives in system_server 991 } 992 } 993 994 /** 995 * Show ongoing notification to reflect that {@link #mRestrictBackground} 996 * has been enabled. 997 */ 998 private void enqueueRestrictedNotification(String tag) { 999 final Resources res = mContext.getResources(); 1000 final Notification.Builder builder = new Notification.Builder(mContext); 1001 1002 final CharSequence title = res.getText(R.string.data_usage_restricted_title); 1003 final CharSequence body = res.getString(R.string.data_usage_restricted_body); 1004 1005 builder.setOnlyAlertOnce(true); 1006 builder.setOngoing(true); 1007 builder.setSmallIcon(R.drawable.stat_notify_error); 1008 builder.setTicker(title); 1009 builder.setContentTitle(title); 1010 builder.setContentText(body); 1011 builder.setColor(mContext.getColor( 1012 com.android.internal.R.color.system_notification_accent_color)); 1013 1014 final Intent intent = buildAllowBackgroundDataIntent(); 1015 builder.setContentIntent( 1016 PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1017 1018 // TODO: move to NotificationManager once we can mock it 1019 // XXX what to do about multi-user? 1020 try { 1021 final String packageName = mContext.getPackageName(); 1022 final int[] idReceived = new int[1]; 1023 mNotifManager.enqueueNotificationWithTag(packageName, packageName, tag, 1024 0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER); 1025 mActiveNotifs.add(tag); 1026 } catch (RemoteException e) { 1027 // ignored; service lives in system_server 1028 } 1029 } 1030 1031 private void cancelNotification(String tag) { 1032 // TODO: move to NotificationManager once we can mock it 1033 // XXX what to do about multi-user? 1034 try { 1035 final String packageName = mContext.getPackageName(); 1036 mNotifManager.cancelNotificationWithTag( 1037 packageName, tag, 0x0, UserHandle.USER_OWNER); 1038 } catch (RemoteException e) { 1039 // ignored; service lives in system_server 1040 } 1041 } 1042 1043 /** 1044 * Receiver that watches for {@link IConnectivityManager} to claim network 1045 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 1046 */ 1047 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 1048 @Override 1049 public void onReceive(Context context, Intent intent) { 1050 // on background handler thread, and verified CONNECTIVITY_INTERNAL 1051 // permission above. 1052 1053 maybeRefreshTrustedTime(); 1054 synchronized (mRulesLock) { 1055 ensureActiveMobilePolicyLocked(); 1056 normalizePoliciesLocked(); 1057 updateNetworkEnabledLocked(); 1058 updateNetworkRulesLocked(); 1059 updateNotificationsLocked(); 1060 } 1061 } 1062 }; 1063 1064 /** 1065 * Proactively control network data connections when they exceed 1066 * {@link NetworkPolicy#limitBytes}. 1067 */ 1068 void updateNetworkEnabledLocked() { 1069 if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()"); 1070 1071 // TODO: reset any policy-disabled networks when any policy is removed 1072 // completely, which is currently rare case. 1073 1074 final long currentTime = currentTimeMillis(); 1075 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1076 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1077 // shortcut when policy has no limit 1078 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 1079 setNetworkTemplateEnabled(policy.template, true); 1080 continue; 1081 } 1082 1083 final long start = computeLastCycleBoundary(currentTime, policy); 1084 final long end = currentTime; 1085 final long totalBytes = getTotalBytes(policy.template, start, end); 1086 1087 // disable data connection when over limit and not snoozed 1088 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 1089 && policy.lastLimitSnooze < start; 1090 final boolean networkEnabled = !overLimitWithoutSnooze; 1091 1092 setNetworkTemplateEnabled(policy.template, networkEnabled); 1093 } 1094 } 1095 1096 /** 1097 * Proactively disable networks that match the given 1098 * {@link NetworkTemplate}. 1099 */ 1100 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 1101 // TODO: reach into ConnectivityManager to proactively disable bringing 1102 // up this network, since we know that traffic will be blocked. 1103 } 1104 1105 /** 1106 * Examine all connected {@link NetworkState}, looking for 1107 * {@link NetworkPolicy} that need to be enforced. When matches found, set 1108 * remaining quota based on usage cycle and historical stats. 1109 */ 1110 void updateNetworkRulesLocked() { 1111 if (LOGV) Slog.v(TAG, "updateNetworkRulesLocked()"); 1112 1113 final NetworkState[] states; 1114 try { 1115 states = mConnManager.getAllNetworkState(); 1116 } catch (RemoteException e) { 1117 // ignored; service lives in system_server 1118 return; 1119 } 1120 1121 // If we are in restrict power mode, we want to treat all interfaces 1122 // as metered, to restrict access to the network by uid. However, we 1123 // will not have a bandwidth limit. Also only do this if restrict 1124 // background data use is *not* enabled, since that takes precendence 1125 // use over those networks can have a cost associated with it). 1126 final boolean powerSave = mRestrictPower && !mRestrictBackground; 1127 1128 // First, generate identities of all connected networks so we can 1129 // quickly compare them against all defined policies below. 1130 final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); 1131 final ArraySet<String> connIfaces = new ArraySet<String>(states.length); 1132 for (NetworkState state : states) { 1133 if (state.networkInfo.isConnected()) { 1134 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1135 1136 final String baseIface = state.linkProperties.getInterfaceName(); 1137 if (baseIface != null) { 1138 connIdents.add(Pair.create(baseIface, ident)); 1139 if (powerSave) { 1140 connIfaces.add(baseIface); 1141 } 1142 } 1143 1144 // Stacked interfaces are considered to have same identity as 1145 // their parent network. 1146 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); 1147 for (LinkProperties stackedLink : stackedLinks) { 1148 final String stackedIface = stackedLink.getInterfaceName(); 1149 if (stackedIface != null) { 1150 connIdents.add(Pair.create(stackedIface, ident)); 1151 if (powerSave) { 1152 connIfaces.add(stackedIface); 1153 } 1154 } 1155 } 1156 } 1157 } 1158 1159 // Apply policies against all connected interfaces found above 1160 mNetworkRules.clear(); 1161 final ArrayList<String> ifaceList = Lists.newArrayList(); 1162 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1163 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1164 1165 ifaceList.clear(); 1166 for (int j = connIdents.size() - 1; j >= 0; j--) { 1167 final Pair<String, NetworkIdentity> ident = connIdents.get(j); 1168 if (policy.template.matches(ident.second)) { 1169 ifaceList.add(ident.first); 1170 } 1171 } 1172 1173 if (ifaceList.size() > 0) { 1174 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 1175 mNetworkRules.put(policy, ifaces); 1176 } 1177 } 1178 1179 long lowestRule = Long.MAX_VALUE; 1180 final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length); 1181 1182 // apply each policy that we found ifaces for; compute remaining data 1183 // based on current cycle and historical stats, and push to kernel. 1184 final long currentTime = currentTimeMillis(); 1185 for (int i = mNetworkRules.size()-1; i >= 0; i--) { 1186 final NetworkPolicy policy = mNetworkRules.keyAt(i); 1187 final String[] ifaces = mNetworkRules.valueAt(i); 1188 1189 final long start; 1190 final long totalBytes; 1191 if (policy.hasCycle()) { 1192 start = computeLastCycleBoundary(currentTime, policy); 1193 totalBytes = getTotalBytes(policy.template, start, currentTime); 1194 } else { 1195 start = Long.MAX_VALUE; 1196 totalBytes = 0; 1197 } 1198 1199 if (LOGD) { 1200 Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " 1201 + Arrays.toString(ifaces)); 1202 } 1203 1204 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 1205 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 1206 if (hasLimit || policy.metered) { 1207 final long quotaBytes; 1208 if (!hasLimit) { 1209 // metered network, but no policy limit; we still need to 1210 // restrict apps, so push really high quota. 1211 quotaBytes = Long.MAX_VALUE; 1212 } else if (policy.lastLimitSnooze >= start) { 1213 // snoozing past quota, but we still need to restrict apps, 1214 // so push really high quota. 1215 quotaBytes = Long.MAX_VALUE; 1216 } else { 1217 // remaining "quota" bytes are based on total usage in 1218 // current cycle. kernel doesn't like 0-byte rules, so we 1219 // set 1-byte quota and disable the radio later. 1220 quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 1221 } 1222 1223 if (ifaces.length > 1) { 1224 // TODO: switch to shared quota once NMS supports 1225 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 1226 } 1227 1228 for (String iface : ifaces) { 1229 removeInterfaceQuota(iface); 1230 setInterfaceQuota(iface, quotaBytes); 1231 newMeteredIfaces.add(iface); 1232 if (powerSave) { 1233 connIfaces.remove(iface); 1234 } 1235 } 1236 } 1237 1238 // keep track of lowest warning or limit of active policies 1239 if (hasWarning && policy.warningBytes < lowestRule) { 1240 lowestRule = policy.warningBytes; 1241 } 1242 if (hasLimit && policy.limitBytes < lowestRule) { 1243 lowestRule = policy.limitBytes; 1244 } 1245 } 1246 1247 for (int i = connIfaces.size()-1; i >= 0; i--) { 1248 String iface = connIfaces.valueAt(i); 1249 removeInterfaceQuota(iface); 1250 setInterfaceQuota(iface, Long.MAX_VALUE); 1251 newMeteredIfaces.add(iface); 1252 } 1253 1254 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 1255 1256 // remove quota on any trailing interfaces 1257 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) { 1258 final String iface = mMeteredIfaces.valueAt(i); 1259 if (!newMeteredIfaces.contains(iface)) { 1260 removeInterfaceQuota(iface); 1261 } 1262 } 1263 mMeteredIfaces = newMeteredIfaces; 1264 1265 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 1266 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 1267 } 1268 1269 /** 1270 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 1271 * have at least a default mobile policy defined. 1272 */ 1273 private void ensureActiveMobilePolicyLocked() { 1274 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 1275 if (mSuppressDefaultPolicy) return; 1276 1277 final TelephonyManager tele = TelephonyManager.from(mContext); 1278 final SubscriptionManager sub = SubscriptionManager.from(mContext); 1279 1280 final int[] subIds = sub.getActiveSubscriptionIdList(); 1281 for (int subId : subIds) { 1282 final String subscriberId = tele.getSubscriberId(subId); 1283 ensureActiveMobilePolicyLocked(subscriberId); 1284 } 1285 } 1286 1287 private void ensureActiveMobilePolicyLocked(String subscriberId) { 1288 // Poke around to see if we already have a policy 1289 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1290 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false); 1291 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1292 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1293 if (template.matches(probeIdent)) { 1294 if (LOGD) { 1295 Slog.d(TAG, "Found template " + template + " which matches subscriber " 1296 + NetworkIdentity.scrubSubscriberId(subscriberId)); 1297 } 1298 return; 1299 } 1300 } 1301 1302 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId) 1303 + "; generating default policy"); 1304 1305 // Build default mobile policy, and assume usage cycle starts today 1306 final long warningBytes = mContext.getResources().getInteger( 1307 com.android.internal.R.integer.config_networkPolicyDefaultWarning) * MB_IN_BYTES; 1308 1309 final Time time = new Time(); 1310 time.setToNow(); 1311 1312 final int cycleDay = time.monthDay; 1313 final String cycleTimezone = time.timezone; 1314 1315 final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 1316 final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, 1317 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true); 1318 addNetworkPolicyLocked(policy); 1319 } 1320 1321 private void readPolicyLocked() { 1322 if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 1323 1324 // clear any existing policy and read from disk 1325 mNetworkPolicy.clear(); 1326 mUidPolicy.clear(); 1327 1328 FileInputStream fis = null; 1329 try { 1330 fis = mPolicyFile.openRead(); 1331 final XmlPullParser in = Xml.newPullParser(); 1332 in.setInput(fis, StandardCharsets.UTF_8.name()); 1333 1334 int type; 1335 int version = VERSION_INIT; 1336 while ((type = in.next()) != END_DOCUMENT) { 1337 final String tag = in.getName(); 1338 if (type == START_TAG) { 1339 if (TAG_POLICY_LIST.equals(tag)) { 1340 version = readIntAttribute(in, ATTR_VERSION); 1341 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 1342 mRestrictBackground = readBooleanAttribute( 1343 in, ATTR_RESTRICT_BACKGROUND); 1344 } else { 1345 mRestrictBackground = false; 1346 } 1347 1348 } else if (TAG_NETWORK_POLICY.equals(tag)) { 1349 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 1350 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 1351 final String networkId; 1352 if (version >= VERSION_ADDED_NETWORK_ID) { 1353 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 1354 } else { 1355 networkId = null; 1356 } 1357 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 1358 final String cycleTimezone; 1359 if (version >= VERSION_ADDED_TIMEZONE) { 1360 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 1361 } else { 1362 cycleTimezone = Time.TIMEZONE_UTC; 1363 } 1364 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 1365 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 1366 final long lastLimitSnooze; 1367 if (version >= VERSION_SPLIT_SNOOZE) { 1368 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 1369 } else if (version >= VERSION_ADDED_SNOOZE) { 1370 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 1371 } else { 1372 lastLimitSnooze = SNOOZE_NEVER; 1373 } 1374 final boolean metered; 1375 if (version >= VERSION_ADDED_METERED) { 1376 metered = readBooleanAttribute(in, ATTR_METERED); 1377 } else { 1378 switch (networkTemplate) { 1379 case MATCH_MOBILE_3G_LOWER: 1380 case MATCH_MOBILE_4G: 1381 case MATCH_MOBILE_ALL: 1382 metered = true; 1383 break; 1384 default: 1385 metered = false; 1386 } 1387 } 1388 final long lastWarningSnooze; 1389 if (version >= VERSION_SPLIT_SNOOZE) { 1390 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 1391 } else { 1392 lastWarningSnooze = SNOOZE_NEVER; 1393 } 1394 final boolean inferred; 1395 if (version >= VERSION_ADDED_INFERRED) { 1396 inferred = readBooleanAttribute(in, ATTR_INFERRED); 1397 } else { 1398 inferred = false; 1399 } 1400 1401 final NetworkTemplate template = new NetworkTemplate(networkTemplate, 1402 subscriberId, networkId); 1403 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, 1404 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, 1405 lastLimitSnooze, metered, inferred)); 1406 1407 } else if (TAG_UID_POLICY.equals(tag)) { 1408 final int uid = readIntAttribute(in, ATTR_UID); 1409 final int policy = readIntAttribute(in, ATTR_POLICY); 1410 1411 if (UserHandle.isApp(uid)) { 1412 setUidPolicyUncheckedLocked(uid, policy, false); 1413 } else { 1414 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1415 } 1416 } else if (TAG_APP_POLICY.equals(tag)) { 1417 final int appId = readIntAttribute(in, ATTR_APP_ID); 1418 final int policy = readIntAttribute(in, ATTR_POLICY); 1419 1420 // TODO: set for other users during upgrade 1421 final int uid = UserHandle.getUid(UserHandle.USER_OWNER, appId); 1422 if (UserHandle.isApp(uid)) { 1423 setUidPolicyUncheckedLocked(uid, policy, false); 1424 } else { 1425 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1426 } 1427 } 1428 } 1429 } 1430 1431 } catch (FileNotFoundException e) { 1432 // missing policy is okay, probably first boot 1433 upgradeLegacyBackgroundData(); 1434 } catch (IOException e) { 1435 Log.wtf(TAG, "problem reading network policy", e); 1436 } catch (XmlPullParserException e) { 1437 Log.wtf(TAG, "problem reading network policy", e); 1438 } finally { 1439 IoUtils.closeQuietly(fis); 1440 } 1441 } 1442 1443 /** 1444 * Upgrade legacy background data flags, notifying listeners of one last 1445 * change to always-true. 1446 */ 1447 private void upgradeLegacyBackgroundData() { 1448 mRestrictBackground = Settings.Secure.getInt( 1449 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 1450 1451 // kick off one last broadcast if restricted 1452 if (mRestrictBackground) { 1453 final Intent broadcast = new Intent( 1454 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 1455 mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL); 1456 } 1457 } 1458 1459 void writePolicyLocked() { 1460 if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 1461 1462 FileOutputStream fos = null; 1463 try { 1464 fos = mPolicyFile.startWrite(); 1465 1466 XmlSerializer out = new FastXmlSerializer(); 1467 out.setOutput(fos, StandardCharsets.UTF_8.name()); 1468 out.startDocument(null, true); 1469 1470 out.startTag(null, TAG_POLICY_LIST); 1471 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 1472 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 1473 1474 // write all known network policies 1475 for (int i = 0; i < mNetworkPolicy.size(); i++) { 1476 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1477 final NetworkTemplate template = policy.template; 1478 1479 out.startTag(null, TAG_NETWORK_POLICY); 1480 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 1481 final String subscriberId = template.getSubscriberId(); 1482 if (subscriberId != null) { 1483 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 1484 } 1485 final String networkId = template.getNetworkId(); 1486 if (networkId != null) { 1487 out.attribute(null, ATTR_NETWORK_ID, networkId); 1488 } 1489 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 1490 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone); 1491 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 1492 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 1493 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 1494 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 1495 writeBooleanAttribute(out, ATTR_METERED, policy.metered); 1496 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 1497 out.endTag(null, TAG_NETWORK_POLICY); 1498 } 1499 1500 // write all known uid policies 1501 for (int i = 0; i < mUidPolicy.size(); i++) { 1502 final int uid = mUidPolicy.keyAt(i); 1503 final int policy = mUidPolicy.valueAt(i); 1504 1505 // skip writing empty policies 1506 if (policy == POLICY_NONE) continue; 1507 1508 out.startTag(null, TAG_UID_POLICY); 1509 writeIntAttribute(out, ATTR_UID, uid); 1510 writeIntAttribute(out, ATTR_POLICY, policy); 1511 out.endTag(null, TAG_UID_POLICY); 1512 } 1513 1514 out.endTag(null, TAG_POLICY_LIST); 1515 out.endDocument(); 1516 1517 mPolicyFile.finishWrite(fos); 1518 } catch (IOException e) { 1519 if (fos != null) { 1520 mPolicyFile.failWrite(fos); 1521 } 1522 } 1523 } 1524 1525 @Override 1526 public void setUidPolicy(int uid, int policy) { 1527 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1528 1529 if (!UserHandle.isApp(uid)) { 1530 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1531 } 1532 1533 synchronized (mRulesLock) { 1534 final long token = Binder.clearCallingIdentity(); 1535 try { 1536 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1537 if (oldPolicy != policy) { 1538 setUidPolicyUncheckedLocked(uid, policy, true); 1539 } 1540 } finally { 1541 Binder.restoreCallingIdentity(token); 1542 } 1543 } 1544 } 1545 1546 @Override 1547 public void addUidPolicy(int uid, int policy) { 1548 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1549 1550 if (!UserHandle.isApp(uid)) { 1551 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1552 } 1553 1554 synchronized (mRulesLock) { 1555 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1556 policy |= oldPolicy; 1557 if (oldPolicy != policy) { 1558 setUidPolicyUncheckedLocked(uid, policy, true); 1559 } 1560 } 1561 } 1562 1563 @Override 1564 public void removeUidPolicy(int uid, int policy) { 1565 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1566 1567 if (!UserHandle.isApp(uid)) { 1568 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1569 } 1570 1571 synchronized (mRulesLock) { 1572 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1573 policy = oldPolicy & ~policy; 1574 if (oldPolicy != policy) { 1575 setUidPolicyUncheckedLocked(uid, policy, true); 1576 } 1577 } 1578 } 1579 1580 private void setUidPolicyUncheckedLocked(int uid, int policy, boolean persist) { 1581 mUidPolicy.put(uid, policy); 1582 1583 // uid policy changed, recompute rules and persist policy. 1584 updateRulesForUidLocked(uid); 1585 if (persist) { 1586 writePolicyLocked(); 1587 } 1588 } 1589 1590 @Override 1591 public int getUidPolicy(int uid) { 1592 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1593 1594 synchronized (mRulesLock) { 1595 return mUidPolicy.get(uid, POLICY_NONE); 1596 } 1597 } 1598 1599 @Override 1600 public int[] getUidsWithPolicy(int policy) { 1601 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1602 1603 int[] uids = new int[0]; 1604 synchronized (mRulesLock) { 1605 for (int i = 0; i < mUidPolicy.size(); i++) { 1606 final int uid = mUidPolicy.keyAt(i); 1607 final int uidPolicy = mUidPolicy.valueAt(i); 1608 if (uidPolicy == policy) { 1609 uids = appendInt(uids, uid); 1610 } 1611 } 1612 } 1613 return uids; 1614 } 1615 1616 /** 1617 * Remove any policies associated with given {@link UserHandle}, persisting 1618 * if any changes are made. 1619 */ 1620 void removePoliciesForUserLocked(int userId) { 1621 if (LOGV) Slog.v(TAG, "removePoliciesForUserLocked()"); 1622 1623 int[] uids = new int[0]; 1624 for (int i = 0; i < mUidPolicy.size(); i++) { 1625 final int uid = mUidPolicy.keyAt(i); 1626 if (UserHandle.getUserId(uid) == userId) { 1627 uids = appendInt(uids, uid); 1628 } 1629 } 1630 1631 if (uids.length > 0) { 1632 for (int uid : uids) { 1633 mUidPolicy.delete(uid); 1634 updateRulesForUidLocked(uid); 1635 } 1636 writePolicyLocked(); 1637 } 1638 } 1639 1640 @Override 1641 public void registerListener(INetworkPolicyListener listener) { 1642 // TODO: create permission for observing network policy 1643 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1644 1645 mListeners.register(listener); 1646 1647 // TODO: consider dispatching existing rules to new listeners 1648 } 1649 1650 @Override 1651 public void unregisterListener(INetworkPolicyListener listener) { 1652 // TODO: create permission for observing network policy 1653 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1654 1655 mListeners.unregister(listener); 1656 } 1657 1658 @Override 1659 public void setNetworkPolicies(NetworkPolicy[] policies) { 1660 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1661 1662 maybeRefreshTrustedTime(); 1663 synchronized (mRulesLock) { 1664 normalizePoliciesLocked(policies); 1665 updateNetworkEnabledLocked(); 1666 updateNetworkRulesLocked(); 1667 updateNotificationsLocked(); 1668 writePolicyLocked(); 1669 } 1670 } 1671 1672 void addNetworkPolicyLocked(NetworkPolicy policy) { 1673 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 1674 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy); 1675 setNetworkPolicies(policies); 1676 } 1677 1678 @Override 1679 public NetworkPolicy[] getNetworkPolicies(String callingPackage) { 1680 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1681 try { 1682 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); 1683 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED 1684 // permission 1685 } catch (SecurityException e) { 1686 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 1687 1688 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 1689 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1690 return new NetworkPolicy[0]; 1691 } 1692 } 1693 1694 synchronized (mRulesLock) { 1695 final int size = mNetworkPolicy.size(); 1696 final NetworkPolicy[] policies = new NetworkPolicy[size]; 1697 for (int i = 0; i < size; i++) { 1698 policies[i] = mNetworkPolicy.valueAt(i); 1699 } 1700 return policies; 1701 } 1702 } 1703 1704 private void normalizePoliciesLocked() { 1705 normalizePoliciesLocked(getNetworkPolicies(mContext.getOpPackageName())); 1706 } 1707 1708 private void normalizePoliciesLocked(NetworkPolicy[] policies) { 1709 final TelephonyManager tele = TelephonyManager.from(mContext); 1710 final String[] merged = tele.getMergedSubscriberIds(); 1711 1712 mNetworkPolicy.clear(); 1713 for (NetworkPolicy policy : policies) { 1714 // When two normalized templates conflict, prefer the most 1715 // restrictive policy 1716 policy.template = NetworkTemplate.normalize(policy.template, merged); 1717 final NetworkPolicy existing = mNetworkPolicy.get(policy.template); 1718 if (existing == null || existing.compareTo(policy) > 0) { 1719 if (existing != null) { 1720 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy); 1721 } 1722 mNetworkPolicy.put(policy.template, policy); 1723 } 1724 } 1725 } 1726 1727 @Override 1728 public void snoozeLimit(NetworkTemplate template) { 1729 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1730 1731 final long token = Binder.clearCallingIdentity(); 1732 try { 1733 performSnooze(template, TYPE_LIMIT); 1734 } finally { 1735 Binder.restoreCallingIdentity(token); 1736 } 1737 } 1738 1739 void performSnooze(NetworkTemplate template, int type) { 1740 maybeRefreshTrustedTime(); 1741 final long currentTime = currentTimeMillis(); 1742 synchronized (mRulesLock) { 1743 // find and snooze local policy that matches 1744 final NetworkPolicy policy = mNetworkPolicy.get(template); 1745 if (policy == null) { 1746 throw new IllegalArgumentException("unable to find policy for " + template); 1747 } 1748 1749 switch (type) { 1750 case TYPE_WARNING: 1751 policy.lastWarningSnooze = currentTime; 1752 break; 1753 case TYPE_LIMIT: 1754 policy.lastLimitSnooze = currentTime; 1755 break; 1756 default: 1757 throw new IllegalArgumentException("unexpected type"); 1758 } 1759 1760 normalizePoliciesLocked(); 1761 updateNetworkEnabledLocked(); 1762 updateNetworkRulesLocked(); 1763 updateNotificationsLocked(); 1764 writePolicyLocked(); 1765 } 1766 } 1767 1768 @Override 1769 public void setRestrictBackground(boolean restrictBackground) { 1770 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1771 1772 maybeRefreshTrustedTime(); 1773 synchronized (mRulesLock) { 1774 mRestrictBackground = restrictBackground; 1775 updateRulesForGlobalChangeLocked(false); 1776 updateNotificationsLocked(); 1777 writePolicyLocked(); 1778 } 1779 1780 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 1781 .sendToTarget(); 1782 } 1783 1784 @Override 1785 public boolean getRestrictBackground() { 1786 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1787 1788 synchronized (mRulesLock) { 1789 return mRestrictBackground; 1790 } 1791 } 1792 1793 @Override 1794 public void setDeviceIdleMode(boolean enabled) { 1795 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1796 1797 synchronized (mRulesLock) { 1798 if (mDeviceIdleMode != enabled) { 1799 mDeviceIdleMode = enabled; 1800 if (mSystemReady) { 1801 updateRulesForDeviceIdleLocked(); 1802 } 1803 if (enabled) { 1804 EventLogTags.writeDeviceIdleOnPhase("net"); 1805 } else { 1806 EventLogTags.writeDeviceIdleOffPhase("net"); 1807 } 1808 } 1809 } 1810 } 1811 1812 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 1813 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1814 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1815 if (policy.template.matches(ident)) { 1816 return policy; 1817 } 1818 } 1819 return null; 1820 } 1821 1822 @Override 1823 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 1824 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 1825 1826 // only returns usage summary, so we don't require caller to have 1827 // READ_NETWORK_USAGE_HISTORY. 1828 final long token = Binder.clearCallingIdentity(); 1829 try { 1830 return getNetworkQuotaInfoUnchecked(state); 1831 } finally { 1832 Binder.restoreCallingIdentity(token); 1833 } 1834 } 1835 1836 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 1837 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1838 1839 final NetworkPolicy policy; 1840 synchronized (mRulesLock) { 1841 policy = findPolicyForNetworkLocked(ident); 1842 } 1843 1844 if (policy == null || !policy.hasCycle()) { 1845 // missing policy means we can't derive useful quota info 1846 return null; 1847 } 1848 1849 final long currentTime = currentTimeMillis(); 1850 1851 // find total bytes used under policy 1852 final long start = computeLastCycleBoundary(currentTime, policy); 1853 final long end = currentTime; 1854 final long totalBytes = getTotalBytes(policy.template, start, end); 1855 1856 // report soft and hard limits under policy 1857 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 1858 : NetworkQuotaInfo.NO_LIMIT; 1859 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 1860 : NetworkQuotaInfo.NO_LIMIT; 1861 1862 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 1863 } 1864 1865 @Override 1866 public boolean isNetworkMetered(NetworkState state) { 1867 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1868 1869 // roaming networks are always considered metered 1870 if (ident.getRoaming()) { 1871 return true; 1872 } 1873 1874 final NetworkPolicy policy; 1875 synchronized (mRulesLock) { 1876 policy = findPolicyForNetworkLocked(ident); 1877 } 1878 1879 if (policy != null) { 1880 return policy.metered; 1881 } else { 1882 final int type = state.networkInfo.getType(); 1883 if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 1884 return true; 1885 } 1886 return false; 1887 } 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 1892 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 1893 1894 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 1895 1896 final ArraySet<String> argSet = new ArraySet<String>(args.length); 1897 for (String arg : args) { 1898 argSet.add(arg); 1899 } 1900 1901 synchronized (mRulesLock) { 1902 if (argSet.contains("--unsnooze")) { 1903 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1904 mNetworkPolicy.valueAt(i).clearSnooze(); 1905 } 1906 1907 normalizePoliciesLocked(); 1908 updateNetworkEnabledLocked(); 1909 updateNetworkRulesLocked(); 1910 updateNotificationsLocked(); 1911 writePolicyLocked(); 1912 1913 fout.println("Cleared snooze timestamps"); 1914 return; 1915 } 1916 1917 fout.print("System ready: "); fout.println(mSystemReady); 1918 fout.print("Restrict background: "); fout.println(mRestrictBackground); 1919 fout.print("Restrict power: "); fout.println(mRestrictPower); 1920 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 1921 fout.println("Network policies:"); 1922 fout.increaseIndent(); 1923 for (int i = 0; i < mNetworkPolicy.size(); i++) { 1924 fout.println(mNetworkPolicy.valueAt(i).toString()); 1925 } 1926 fout.decreaseIndent(); 1927 1928 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 1929 1930 fout.println("Policy for UIDs:"); 1931 fout.increaseIndent(); 1932 int size = mUidPolicy.size(); 1933 for (int i = 0; i < size; i++) { 1934 final int uid = mUidPolicy.keyAt(i); 1935 final int policy = mUidPolicy.valueAt(i); 1936 fout.print("UID="); 1937 fout.print(uid); 1938 fout.print(" policy="); 1939 dumpPolicy(fout, policy); 1940 fout.println(); 1941 } 1942 fout.decreaseIndent(); 1943 1944 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 1945 if (size > 0) { 1946 fout.println("Power save whitelist (except idle) app ids:"); 1947 fout.increaseIndent(); 1948 for (int i = 0; i < size; i++) { 1949 fout.print("UID="); 1950 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 1951 fout.print(": "); 1952 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 1953 fout.println(); 1954 } 1955 fout.decreaseIndent(); 1956 } 1957 1958 size = mPowerSaveWhitelistAppIds.size(); 1959 if (size > 0) { 1960 fout.println("Power save whitelist app ids:"); 1961 fout.increaseIndent(); 1962 for (int i = 0; i < size; i++) { 1963 fout.print("UID="); 1964 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 1965 fout.print(": "); 1966 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 1967 fout.println(); 1968 } 1969 fout.decreaseIndent(); 1970 } 1971 1972 final SparseBooleanArray knownUids = new SparseBooleanArray(); 1973 collectKeys(mUidState, knownUids); 1974 collectKeys(mUidRules, knownUids); 1975 1976 fout.println("Status for known UIDs:"); 1977 fout.increaseIndent(); 1978 size = knownUids.size(); 1979 for (int i = 0; i < size; i++) { 1980 final int uid = knownUids.keyAt(i); 1981 fout.print("UID="); 1982 fout.print(uid); 1983 1984 int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 1985 fout.print(" state="); 1986 fout.print(state); 1987 fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)"); 1988 1989 fout.print(" rules="); 1990 final int rulesIndex = mUidRules.indexOfKey(uid); 1991 if (rulesIndex < 0) { 1992 fout.print("UNKNOWN"); 1993 } else { 1994 dumpRules(fout, mUidRules.valueAt(rulesIndex)); 1995 } 1996 1997 fout.println(); 1998 } 1999 fout.decreaseIndent(); 2000 } 2001 } 2002 2003 @Override 2004 public boolean isUidForeground(int uid) { 2005 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2006 2007 synchronized (mRulesLock) { 2008 return isUidForegroundLocked(uid); 2009 } 2010 } 2011 2012 boolean isUidForegroundLocked(int uid) { 2013 // only really in foreground when screen is also on 2014 return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY) 2015 <= ActivityManager.PROCESS_STATE_TOP; 2016 } 2017 2018 /** 2019 * Process state of UID changed; if needed, will trigger 2020 * {@link #updateRulesForUidLocked(int)}. 2021 */ 2022 void updateUidStateLocked(int uid, int uidState) { 2023 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2024 if (oldUidState != uidState) { 2025 // state changed, push updated rules 2026 mUidState.put(uid, uidState); 2027 updateRulesForUidStateChangeLocked(uid, oldUidState, uidState); 2028 if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState) 2029 != isProcStateAllowedWhileIdle(uidState)) { 2030 updateRulesForDeviceIdleLocked(); 2031 } 2032 } 2033 } 2034 2035 void removeUidStateLocked(int uid) { 2036 final int index = mUidState.indexOfKey(uid); 2037 if (index >= 0) { 2038 final int oldUidState = mUidState.valueAt(index); 2039 mUidState.removeAt(index); 2040 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2041 updateRulesForUidStateChangeLocked(uid, oldUidState, 2042 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2043 if (mDeviceIdleMode) { 2044 updateRulesForDeviceIdleLocked(); 2045 } 2046 } 2047 } 2048 } 2049 2050 void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) { 2051 final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP; 2052 final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP; 2053 if (oldForeground != newForeground) { 2054 updateRulesForUidLocked(uid); 2055 } 2056 } 2057 2058 private void updateScreenOn() { 2059 synchronized (mRulesLock) { 2060 try { 2061 mScreenOn = mPowerManager.isInteractive(); 2062 } catch (RemoteException e) { 2063 // ignored; service lives in system_server 2064 } 2065 updateRulesForScreenLocked(); 2066 } 2067 } 2068 2069 /** 2070 * Update rules that might be changed by {@link #mScreenOn} value. 2071 */ 2072 private void updateRulesForScreenLocked() { 2073 // only update rules for anyone with foreground activities 2074 final int size = mUidState.size(); 2075 for (int i = 0; i < size; i++) { 2076 if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) { 2077 final int uid = mUidState.keyAt(i); 2078 updateRulesForUidLocked(uid); 2079 } 2080 } 2081 } 2082 2083 static boolean isProcStateAllowedWhileIdle(int procState) { 2084 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2085 } 2086 2087 void updateRulesForDeviceIdleLocked() { 2088 if (mDeviceIdleMode) { 2089 // sync the whitelists before enable dozable chain. We don't care about the rules if 2090 // we are disabling the chain. 2091 SparseIntArray uidRules = new SparseIntArray(); 2092 final List<UserInfo> users = mUserManager.getUsers(); 2093 for (int ui = users.size() - 1; ui >= 0; ui--) { 2094 UserInfo user = users.get(ui); 2095 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2096 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) { 2097 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2098 int uid = UserHandle.getUid(user.id, appId); 2099 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2100 } 2101 } 2102 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { 2103 int appId = mPowerSaveWhitelistAppIds.keyAt(i); 2104 int uid = UserHandle.getUid(user.id, appId); 2105 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2106 } 2107 } 2108 for (int i = mUidState.size() - 1; i >= 0; i--) { 2109 if (isProcStateAllowedWhileIdle(mUidState.valueAt(i))) { 2110 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2111 } 2112 } 2113 setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules); 2114 } 2115 enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); 2116 } 2117 2118 void updateRuleForDeviceIdleLocked(int uid) { 2119 if (mDeviceIdleMode) { 2120 int appId = UserHandle.getAppId(uid); 2121 if (mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId) 2122 || isProcStateAllowedWhileIdle(mUidState.get(uid))) { 2123 setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_ALLOW); 2124 } else { 2125 setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT); 2126 } 2127 } 2128 } 2129 2130 void updateRulesForAppIdleLocked() { 2131 // Fully update the app idle firewall chain. 2132 SparseIntArray uidRules = new SparseIntArray(); 2133 final List<UserInfo> users = mUserManager.getUsers(); 2134 for (int ui = users.size() - 1; ui >= 0; ui--) { 2135 UserInfo user = users.get(ui); 2136 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2137 for (int uid : idleUids) { 2138 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2139 uidRules.put(uid, FIREWALL_RULE_DENY); 2140 } 2141 } 2142 } 2143 setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); 2144 } 2145 2146 void updateRuleForAppIdleLocked(int uid) { 2147 if (!isUidValidForRules(uid)) return; 2148 2149 int appId = UserHandle.getAppId(uid); 2150 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)) { 2151 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2152 } else { 2153 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2154 } 2155 } 2156 2157 void updateRulesForAppIdleParoleLocked() { 2158 boolean enableChain = !mUsageStats.isAppIdleParoleOn(); 2159 enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); 2160 } 2161 2162 /** 2163 * Update rules that might be changed by {@link #mRestrictBackground}, 2164 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 2165 */ 2166 void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) { 2167 final PackageManager pm = mContext.getPackageManager(); 2168 2169 updateRulesForDeviceIdleLocked(); 2170 updateRulesForAppIdleLocked(); 2171 2172 // update rules for all installed applications 2173 final List<UserInfo> users = mUserManager.getUsers(); 2174 final List<ApplicationInfo> apps = pm.getInstalledApplications( 2175 PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS); 2176 2177 for (UserInfo user : users) { 2178 for (ApplicationInfo app : apps) { 2179 final int uid = UserHandle.getUid(user.id, app.uid); 2180 updateRulesForUidLocked(uid); 2181 } 2182 } 2183 2184 // limit data usage for some internal system services 2185 updateRulesForUidLocked(android.os.Process.MEDIA_UID); 2186 updateRulesForUidLocked(android.os.Process.DRM_UID); 2187 2188 // If the set of restricted networks may have changed, re-evaluate those. 2189 if (restrictedNetworksChanged) { 2190 normalizePoliciesLocked(); 2191 updateNetworkRulesLocked(); 2192 } 2193 } 2194 2195 void updateRulesForTempWhitelistChangeLocked() { 2196 final List<UserInfo> users = mUserManager.getUsers(); 2197 for (UserInfo user : users) { 2198 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2199 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2200 int uid = UserHandle.getUid(user.id, appId); 2201 updateRuleForAppIdleLocked(uid); 2202 updateRuleForDeviceIdleLocked(uid); 2203 } 2204 } 2205 } 2206 2207 private static boolean isUidValidForRules(int uid) { 2208 // allow rules on specific system services, and any apps 2209 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 2210 || UserHandle.isApp(uid)) { 2211 return true; 2212 } 2213 2214 return false; 2215 } 2216 2217 private boolean isUidIdle(int uid) { 2218 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 2219 final int userId = UserHandle.getUserId(uid); 2220 2221 for (String packageName : packages) { 2222 if (!mUsageStats.isAppIdle(packageName, userId)) { 2223 return false; 2224 } 2225 } 2226 return true; 2227 } 2228 2229 /** 2230 * Applies network rules to bandwidth and firewall controllers based on uid policy. 2231 * @param uid The uid for which to apply the latest policy 2232 */ 2233 void updateRulesForUidLocked(int uid) { 2234 if (!isUidValidForRules(uid)) return; 2235 2236 // quick check: if this uid doesn't have INTERNET permission, it doesn't have 2237 // network access anyway, so it is a waste to mess with it here. 2238 final IPackageManager ipm = AppGlobals.getPackageManager(); 2239 try { 2240 if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid) 2241 != PackageManager.PERMISSION_GRANTED) { 2242 return; 2243 } 2244 } catch (RemoteException e) { 2245 } 2246 2247 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2248 final boolean uidForeground = isUidForegroundLocked(uid); 2249 2250 // derive active rules based on policy and active state 2251 2252 int appId = UserHandle.getAppId(uid); 2253 int uidRules = RULE_ALLOW_ALL; 2254 if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) { 2255 // uid in background, and policy says to block metered data 2256 uidRules = RULE_REJECT_METERED; 2257 } else if (mRestrictBackground) { 2258 if (!uidForeground) { 2259 // uid in background, and global background disabled 2260 uidRules = RULE_REJECT_METERED; 2261 } 2262 } else if (mRestrictPower) { 2263 final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId) 2264 || mPowerSaveTempWhitelistAppIds.get(appId); 2265 if (!whitelisted && !uidForeground 2266 && (uidPolicy & POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) == 0) { 2267 // uid is in background, restrict power use mode is on (so we want to 2268 // restrict all background network access), and this uid is not on the 2269 // white list of those allowed background access. 2270 uidRules = RULE_REJECT_METERED; 2271 } 2272 } 2273 2274 final int oldRules = mUidRules.get(uid); 2275 2276 if (uidRules == RULE_ALLOW_ALL) { 2277 mUidRules.delete(uid); 2278 } else { 2279 mUidRules.put(uid, uidRules); 2280 } 2281 2282 // Update bandwidth rules if necessary 2283 final boolean oldRejectMetered = (oldRules & RULE_REJECT_METERED) != 0; 2284 final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0; 2285 if (oldRejectMetered != rejectMetered) { 2286 setUidNetworkRules(uid, rejectMetered); 2287 } 2288 2289 // dispatch changed rule to existing listeners 2290 if (oldRules != uidRules) { 2291 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget(); 2292 } 2293 2294 try { 2295 // adjust stats accounting based on foreground status 2296 mNetworkStats.setUidForeground(uid, uidForeground); 2297 } catch (RemoteException e) { 2298 // ignored; service lives in system_server 2299 } 2300 } 2301 2302 private class AppIdleStateChangeListener 2303 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 2304 2305 @Override 2306 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 2307 try { 2308 int uid = mContext.getPackageManager().getPackageUid(packageName, userId); 2309 synchronized (mRulesLock) { 2310 updateRuleForAppIdleLocked(uid); 2311 } 2312 } catch (NameNotFoundException nnfe) { 2313 } 2314 } 2315 2316 @Override 2317 public void onParoleStateChanged(boolean isParoleOn) { 2318 synchronized (mRulesLock) { 2319 updateRulesForAppIdleParoleLocked(); 2320 } 2321 } 2322 } 2323 2324 private Handler.Callback mHandlerCallback = new Handler.Callback() { 2325 @Override 2326 public boolean handleMessage(Message msg) { 2327 switch (msg.what) { 2328 case MSG_RULES_CHANGED: { 2329 final int uid = msg.arg1; 2330 final int uidRules = msg.arg2; 2331 final int length = mListeners.beginBroadcast(); 2332 for (int i = 0; i < length; i++) { 2333 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2334 if (listener != null) { 2335 try { 2336 listener.onUidRulesChanged(uid, uidRules); 2337 } catch (RemoteException e) { 2338 } 2339 } 2340 } 2341 mListeners.finishBroadcast(); 2342 return true; 2343 } 2344 case MSG_METERED_IFACES_CHANGED: { 2345 final String[] meteredIfaces = (String[]) msg.obj; 2346 final int length = mListeners.beginBroadcast(); 2347 for (int i = 0; i < length; i++) { 2348 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2349 if (listener != null) { 2350 try { 2351 listener.onMeteredIfacesChanged(meteredIfaces); 2352 } catch (RemoteException e) { 2353 } 2354 } 2355 } 2356 mListeners.finishBroadcast(); 2357 return true; 2358 } 2359 case MSG_LIMIT_REACHED: { 2360 final String iface = (String) msg.obj; 2361 2362 maybeRefreshTrustedTime(); 2363 synchronized (mRulesLock) { 2364 if (mMeteredIfaces.contains(iface)) { 2365 try { 2366 // force stats update to make sure we have 2367 // numbers that caused alert to trigger. 2368 mNetworkStats.forceUpdate(); 2369 } catch (RemoteException e) { 2370 // ignored; service lives in system_server 2371 } 2372 2373 updateNetworkEnabledLocked(); 2374 updateNotificationsLocked(); 2375 } 2376 } 2377 return true; 2378 } 2379 case MSG_RESTRICT_BACKGROUND_CHANGED: { 2380 final boolean restrictBackground = msg.arg1 != 0; 2381 final int length = mListeners.beginBroadcast(); 2382 for (int i = 0; i < length; i++) { 2383 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 2384 if (listener != null) { 2385 try { 2386 listener.onRestrictBackgroundChanged(restrictBackground); 2387 } catch (RemoteException e) { 2388 } 2389 } 2390 } 2391 mListeners.finishBroadcast(); 2392 return true; 2393 } 2394 case MSG_ADVISE_PERSIST_THRESHOLD: { 2395 final long lowestRule = (Long) msg.obj; 2396 try { 2397 // make sure stats are recorded frequently enough; we aim 2398 // for 2MB threshold for 2GB/month rules. 2399 final long persistThreshold = lowestRule / 1000; 2400 mNetworkStats.advisePersistThreshold(persistThreshold); 2401 } catch (RemoteException e) { 2402 // ignored; service lives in system_server 2403 } 2404 return true; 2405 } 2406 case MSG_SCREEN_ON_CHANGED: { 2407 updateScreenOn(); 2408 return true; 2409 } 2410 default: { 2411 return false; 2412 } 2413 } 2414 } 2415 }; 2416 2417 private void setInterfaceQuota(String iface, long quotaBytes) { 2418 try { 2419 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 2420 } catch (IllegalStateException e) { 2421 Log.wtf(TAG, "problem setting interface quota", e); 2422 } catch (RemoteException e) { 2423 // ignored; service lives in system_server 2424 } 2425 } 2426 2427 private void removeInterfaceQuota(String iface) { 2428 try { 2429 mNetworkManager.removeInterfaceQuota(iface); 2430 } catch (IllegalStateException e) { 2431 Log.wtf(TAG, "problem removing interface quota", e); 2432 } catch (RemoteException e) { 2433 // ignored; service lives in system_server 2434 } 2435 } 2436 2437 private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) { 2438 try { 2439 mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 2440 } catch (IllegalStateException e) { 2441 Log.wtf(TAG, "problem setting uid rules", e); 2442 } catch (RemoteException e) { 2443 // ignored; service lives in system_server 2444 } 2445 } 2446 2447 /** 2448 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 2449 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 2450 * specified here. 2451 */ 2452 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 2453 try { 2454 int size = uidRules.size(); 2455 int[] uids = new int[size]; 2456 int[] rules = new int[size]; 2457 for(int index = size - 1; index >= 0; --index) { 2458 uids[index] = uidRules.keyAt(index); 2459 rules[index] = uidRules.valueAt(index); 2460 } 2461 mNetworkManager.setFirewallUidRules(chain, uids, rules); 2462 } catch (IllegalStateException e) { 2463 Log.wtf(TAG, "problem setting firewall uid rules", e); 2464 } catch (RemoteException e) { 2465 // ignored; service lives in system_server 2466 } 2467 } 2468 2469 /** 2470 * Add or remove a uid to the firewall blacklist for all network ifaces. 2471 */ 2472 private void setUidFirewallRule(int chain, int uid, int rule) { 2473 try { 2474 mNetworkManager.setFirewallUidRule(chain, uid, rule); 2475 } catch (IllegalStateException e) { 2476 Log.wtf(TAG, "problem setting firewall uid rules", e); 2477 } catch (RemoteException e) { 2478 // ignored; service lives in system_server 2479 } 2480 } 2481 2482 /** 2483 * Add or remove a uid to the firewall blacklist for all network ifaces. 2484 */ 2485 private void enableFirewallChainLocked(int chain, boolean enable) { 2486 try { 2487 mNetworkManager.setFirewallChainEnabled(chain, enable); 2488 } catch (IllegalStateException e) { 2489 Log.wtf(TAG, "problem enable firewall chain", e); 2490 } catch (RemoteException e) { 2491 // ignored; service lives in system_server 2492 } 2493 } 2494 2495 private long getTotalBytes(NetworkTemplate template, long start, long end) { 2496 try { 2497 return mNetworkStats.getNetworkTotalBytes(template, start, end); 2498 } catch (RuntimeException e) { 2499 Slog.w(TAG, "problem reading network stats: " + e); 2500 return 0; 2501 } catch (RemoteException e) { 2502 // ignored; service lives in system_server 2503 return 0; 2504 } 2505 } 2506 2507 private boolean isBandwidthControlEnabled() { 2508 final long token = Binder.clearCallingIdentity(); 2509 try { 2510 return mNetworkManager.isBandwidthControlEnabled(); 2511 } catch (RemoteException e) { 2512 // ignored; service lives in system_server 2513 return false; 2514 } finally { 2515 Binder.restoreCallingIdentity(token); 2516 } 2517 } 2518 2519 /** 2520 * Try refreshing {@link #mTime} when stale. 2521 */ 2522 void maybeRefreshTrustedTime() { 2523 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 2524 mTime.forceRefresh(); 2525 } 2526 } 2527 2528 private long currentTimeMillis() { 2529 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 2530 } 2531 2532 private static Intent buildAllowBackgroundDataIntent() { 2533 return new Intent(ACTION_ALLOW_BACKGROUND); 2534 } 2535 2536 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 2537 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 2538 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 2539 return intent; 2540 } 2541 2542 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 2543 final Intent intent = new Intent(); 2544 intent.setComponent(new ComponentName( 2545 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 2546 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2547 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 2548 return intent; 2549 } 2550 2551 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 2552 final Intent intent = new Intent(); 2553 intent.setComponent(new ComponentName( 2554 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 2555 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2556 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 2557 return intent; 2558 } 2559 2560 @VisibleForTesting 2561 public void addIdleHandler(IdleHandler handler) { 2562 mHandler.getLooper().getQueue().addIdleHandler(handler); 2563 } 2564 2565 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 2566 final int size = source.size(); 2567 for (int i = 0; i < size; i++) { 2568 target.put(source.keyAt(i), true); 2569 } 2570 } 2571 2572 @Override 2573 public void factoryReset(String subscriber) { 2574 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2575 2576 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 2577 return; 2578 } 2579 2580 // Turn mobile data limit off 2581 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 2582 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 2583 for (NetworkPolicy policy : policies) { 2584 if (policy.template.equals(template)) { 2585 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 2586 policy.inferred = false; 2587 policy.clearSnooze(); 2588 } 2589 } 2590 setNetworkPolicies(policies); 2591 2592 // Turn restrict background data off 2593 setRestrictBackground(false); 2594 2595 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 2596 // Remove app's "restrict background data" flag 2597 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 2598 setUidPolicy(uid, POLICY_NONE); 2599 } 2600 } 2601 } 2602} 2603