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