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