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