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