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