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