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