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