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