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