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