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