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