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