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.RESTRICT_BACKGROUND_STATUS_DISABLED; 33 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 34 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; 35 import static android.net.ConnectivityManager.TYPE_MOBILE; 36 import static android.net.ConnectivityManager.TYPE_WIMAX; 37 import static android.net.ConnectivityManager.isNetworkTypeMobile; 38 import static android.net.NetworkPolicy.CYCLE_NONE; 39 import static android.net.NetworkPolicy.LIMIT_DISABLED; 40 import static android.net.NetworkPolicy.SNOOZE_NEVER; 41 import static android.net.NetworkPolicy.WARNING_DISABLED; 42 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 43 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; 44 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; 45 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; 46 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; 47 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 48 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; 49 import static android.net.NetworkPolicyManager.POLICY_NONE; 50 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 51 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 52 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 53 import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; 54 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; 55 import static android.net.NetworkPolicyManager.RULE_NONE; 56 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 57 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 58 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 59 import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 60 import static android.net.NetworkPolicyManager.uidRulesToString; 61 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 62 import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 63 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 64 import static android.net.NetworkTemplate.MATCH_WIFI; 65 import static android.net.NetworkTemplate.buildTemplateMobileAll; 66 import static android.net.TrafficStats.MB_IN_BYTES; 67 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 68 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 69 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 70 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 71 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 72 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 73 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 74 import static android.text.format.DateUtils.DAY_IN_MILLIS; 75 76 import static com.android.internal.util.ArrayUtils.appendInt; 77 import static com.android.internal.util.Preconditions.checkNotNull; 78 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 79 import static com.android.internal.util.XmlUtils.readIntAttribute; 80 import static com.android.internal.util.XmlUtils.readLongAttribute; 81 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 82 import static com.android.internal.util.XmlUtils.writeIntAttribute; 83 import static com.android.internal.util.XmlUtils.writeLongAttribute; 84 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 85 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 86 87 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 88 import static org.xmlpull.v1.XmlPullParser.END_TAG; 89 import static org.xmlpull.v1.XmlPullParser.START_TAG; 90 91 import android.Manifest; 92 import android.app.ActivityManager; 93 import android.app.AppGlobals; 94 import android.app.AppOpsManager; 95 import android.app.IActivityManager; 96 import android.app.INotificationManager; 97 import android.app.IUidObserver; 98 import android.app.Notification; 99 import android.app.PendingIntent; 100 import android.app.usage.UsageStatsManagerInternal; 101 import android.content.BroadcastReceiver; 102 import android.content.ComponentName; 103 import android.content.Context; 104 import android.content.Intent; 105 import android.content.IntentFilter; 106 import android.content.pm.ApplicationInfo; 107 import android.content.pm.IPackageManager; 108 import android.content.pm.PackageManager; 109 import android.content.pm.PackageManager.NameNotFoundException; 110 import android.content.pm.UserInfo; 111 import android.content.res.Resources; 112 import android.net.ConnectivityManager; 113 import android.net.IConnectivityManager; 114 import android.net.INetworkManagementEventObserver; 115 import android.net.INetworkPolicyListener; 116 import android.net.INetworkPolicyManager; 117 import android.net.INetworkStatsService; 118 import android.net.LinkProperties; 119 import android.net.NetworkIdentity; 120 import android.net.NetworkInfo; 121 import android.net.NetworkPolicy; 122 import android.net.NetworkPolicyManager; 123 import android.net.NetworkQuotaInfo; 124 import android.net.NetworkState; 125 import android.net.NetworkTemplate; 126 import android.net.wifi.WifiConfiguration; 127 import android.net.wifi.WifiInfo; 128 import android.net.wifi.WifiManager; 129 import android.os.Binder; 130 import android.os.Environment; 131 import android.os.Handler; 132 import android.os.HandlerThread; 133 import android.os.IDeviceIdleController; 134 import android.os.INetworkManagementService; 135 import android.os.IPowerManager; 136 import android.os.Message; 137 import android.os.MessageQueue.IdleHandler; 138 import android.os.PowerManager; 139 import android.os.PowerManagerInternal; 140 import android.os.RemoteCallbackList; 141 import android.os.RemoteException; 142 import android.os.ResultReceiver; 143 import android.os.ServiceManager; 144 import android.os.UserHandle; 145 import android.os.UserManager; 146 import android.provider.Settings; 147 import android.telephony.SubscriptionManager; 148 import android.telephony.TelephonyManager; 149 import android.text.format.Formatter; 150 import android.text.format.Time; 151 import android.util.ArrayMap; 152 import android.util.ArraySet; 153 import android.util.AtomicFile; 154 import android.util.DebugUtils; 155 import android.util.Log; 156 import android.util.NtpTrustedTime; 157 import android.util.Pair; 158 import android.util.Slog; 159 import android.util.SparseBooleanArray; 160 import android.util.SparseIntArray; 161 import android.util.TrustedTime; 162 import android.util.Xml; 163 164 import com.android.internal.R; 165 import com.android.internal.annotations.VisibleForTesting; 166 import com.android.internal.content.PackageMonitor; 167 import com.android.internal.util.ArrayUtils; 168 import com.android.internal.util.FastXmlSerializer; 169 import com.android.internal.util.IndentingPrintWriter; 170 import com.android.server.DeviceIdleController; 171 import com.android.server.EventLogTags; 172 import com.android.server.LocalServices; 173 import com.android.server.SystemConfig; 174 175 import libcore.io.IoUtils; 176 177 import com.google.android.collect.Lists; 178 179 import org.xmlpull.v1.XmlPullParser; 180 import org.xmlpull.v1.XmlPullParserException; 181 import org.xmlpull.v1.XmlSerializer; 182 183 import java.io.File; 184 import java.io.FileDescriptor; 185 import java.io.FileInputStream; 186 import java.io.FileNotFoundException; 187 import java.io.FileOutputStream; 188 import java.io.IOException; 189 import java.io.PrintWriter; 190 import java.nio.charset.StandardCharsets; 191 import java.util.ArrayList; 192 import java.util.Arrays; 193 import java.util.List; 194 195 /** 196 * Service that maintains low-level network policy rules, using 197 * {@link NetworkStatsService} statistics to drive those rules. 198 * <p> 199 * Derives active rules by combining a given policy with other system status, 200 * and delivers to listeners, such as {@link ConnectivityManager}, for 201 * enforcement. 202 */ 203 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 204 static final String TAG = "NetworkPolicy"; 205 private static final boolean LOGD = false; 206 private static final boolean LOGV = false; 207 208 private static final int VERSION_INIT = 1; 209 private static final int VERSION_ADDED_SNOOZE = 2; 210 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 211 private static final int VERSION_ADDED_METERED = 4; 212 private static final int VERSION_SPLIT_SNOOZE = 5; 213 private static final int VERSION_ADDED_TIMEZONE = 6; 214 private static final int VERSION_ADDED_INFERRED = 7; 215 private static final int VERSION_SWITCH_APP_ID = 8; 216 private static final int VERSION_ADDED_NETWORK_ID = 9; 217 private static final int VERSION_SWITCH_UID = 10; 218 private static final int VERSION_LATEST = VERSION_SWITCH_UID; 219 220 @VisibleForTesting 221 public static final int TYPE_WARNING = 0x1; 222 @VisibleForTesting 223 public static final int TYPE_LIMIT = 0x2; 224 @VisibleForTesting 225 public static final int TYPE_LIMIT_SNOOZED = 0x3; 226 227 private static final String TAG_POLICY_LIST = "policy-list"; 228 private static final String TAG_NETWORK_POLICY = "network-policy"; 229 private static final String TAG_UID_POLICY = "uid-policy"; 230 private static final String TAG_APP_POLICY = "app-policy"; 231 private static final String TAG_WHITELIST = "whitelist"; 232 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; 233 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background"; 234 235 private static final String ATTR_VERSION = "version"; 236 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 237 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 238 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 239 private static final String ATTR_NETWORK_ID = "networkId"; 240 private static final String ATTR_CYCLE_DAY = "cycleDay"; 241 private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 242 private static final String ATTR_WARNING_BYTES = "warningBytes"; 243 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 244 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 245 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 246 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 247 private static final String ATTR_METERED = "metered"; 248 private static final String ATTR_INFERRED = "inferred"; 249 private static final String ATTR_UID = "uid"; 250 private static final String ATTR_APP_ID = "appId"; 251 private static final String ATTR_POLICY = "policy"; 252 253 private static final String ACTION_ALLOW_BACKGROUND = 254 "com.android.server.net.action.ALLOW_BACKGROUND"; 255 private static final String ACTION_SNOOZE_WARNING = 256 "com.android.server.net.action.SNOOZE_WARNING"; 257 258 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 259 260 private static final int MSG_RULES_CHANGED = 1; 261 private static final int MSG_METERED_IFACES_CHANGED = 2; 262 private static final int MSG_LIMIT_REACHED = 5; 263 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 264 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 265 private static final int MSG_SCREEN_ON_CHANGED = 8; 266 private static final int MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED = 9; 267 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10; 268 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11; 269 private static final int MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED = 12; 270 271 private final Context mContext; 272 private final IActivityManager mActivityManager; 273 private final IPowerManager mPowerManager; 274 private final INetworkStatsService mNetworkStats; 275 private final INetworkManagementService mNetworkManager; 276 private UsageStatsManagerInternal mUsageStats; 277 private final TrustedTime mTime; 278 private final UserManager mUserManager; 279 280 private IConnectivityManager mConnManager; 281 private INotificationManager mNotifManager; 282 private PowerManagerInternal mPowerManagerInternal; 283 private IDeviceIdleController mDeviceIdleController; 284 285 final Object mRulesLock = new Object(); 286 287 volatile boolean mSystemReady; 288 volatile boolean mScreenOn; 289 volatile boolean mRestrictBackground; 290 volatile boolean mRestrictPower; 291 volatile boolean mDeviceIdleMode; 292 293 private final boolean mSuppressDefaultPolicy; 294 295 /** Defined network policies. */ 296 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); 297 /** Currently active network rules for ifaces. */ 298 final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>(); 299 300 /** Defined UID policies. */ 301 final SparseIntArray mUidPolicy = new SparseIntArray(); 302 /** Currently derived rules for each UID. */ 303 final SparseIntArray mUidRules = new SparseIntArray(); 304 305 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 306 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 307 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 308 309 /** Set of states for the child firewall chains. True if the chain is active. */ 310 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 311 312 /** 313 * UIDs that have been white-listed to always be able to have network access 314 * in power save mode, except device idle (doze) still applies. 315 * TODO: An int array might be sufficient 316 */ 317 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 318 319 /** 320 * UIDs that have been white-listed to always be able to have network access 321 * in power save mode. 322 * TODO: An int array might be sufficient 323 */ 324 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); 325 326 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); 327 328 /** 329 * UIDs that have been white-listed to avoid restricted background. 330 */ 331 private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray(); 332 333 /** 334 * UIDs that have been initially white-listed by system to avoid restricted background. 335 */ 336 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids = 337 new SparseBooleanArray(); 338 339 /** 340 * UIDs that have been initially white-listed by system to avoid restricted background, 341 * but later revoked by user. 342 */ 343 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids = 344 new SparseBooleanArray(); 345 346 /** Set of ifaces that are metered. */ 347 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 348 /** Set of over-limit templates that have been notified. */ 349 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>(); 350 351 /** Set of currently active {@link Notification} tags. */ 352 private final ArraySet<String> mActiveNotifs = new ArraySet<String>(); 353 354 /** Foreground at UID granularity. */ 355 final SparseIntArray mUidState = new SparseIntArray(); 356 357 /** Higher priority listener before general event dispatch */ 358 private INetworkPolicyListener mConnectivityListener; 359 360 private final RemoteCallbackList<INetworkPolicyListener> 361 mListeners = new RemoteCallbackList<>(); 362 363 final Handler mHandler; 364 365 private final AtomicFile mPolicyFile; 366 367 private final AppOpsManager mAppOps; 368 369 private final MyPackageMonitor mPackageMonitor; 370 private final IPackageManager mIPm; 371 372 373 // TODO: keep whitelist of system-critical services that should never have 374 // rules enforced, such as system, phone, and radio UIDs. 375 376 // TODO: migrate notifications to SystemUI 377 NetworkPolicyManagerService(Context context, IActivityManager activityManager, IPowerManager powerManager, INetworkStatsService networkStats, INetworkManagementService networkManagement)378 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 379 IPowerManager powerManager, INetworkStatsService networkStats, 380 INetworkManagementService networkManagement) { 381 this(context, activityManager, powerManager, networkStats, networkManagement, 382 NtpTrustedTime.getInstance(context), getSystemDir(), false); 383 } 384 getSystemDir()385 private static File getSystemDir() { 386 return new File(Environment.getDataDirectory(), "system"); 387 } 388 NetworkPolicyManagerService(Context context, IActivityManager activityManager, IPowerManager powerManager, INetworkStatsService networkStats, INetworkManagementService networkManagement, TrustedTime time, File systemDir, boolean suppressDefaultPolicy)389 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 390 IPowerManager powerManager, INetworkStatsService networkStats, 391 INetworkManagementService networkManagement, TrustedTime time, File systemDir, 392 boolean suppressDefaultPolicy) { 393 mContext = checkNotNull(context, "missing context"); 394 mActivityManager = checkNotNull(activityManager, "missing activityManager"); 395 mPowerManager = checkNotNull(powerManager, "missing powerManager"); 396 mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 397 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 398 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService( 399 Context.DEVICE_IDLE_CONTROLLER)); 400 mTime = checkNotNull(time, "missing TrustedTime"); 401 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 402 mIPm = AppGlobals.getPackageManager(); 403 404 HandlerThread thread = new HandlerThread(TAG); 405 thread.start(); 406 mHandler = new Handler(thread.getLooper(), mHandlerCallback); 407 408 mSuppressDefaultPolicy = suppressDefaultPolicy; 409 410 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 411 412 mAppOps = context.getSystemService(AppOpsManager.class); 413 414 mPackageMonitor = new MyPackageMonitor(); 415 416 // Expose private service for system components to use. 417 LocalServices.addService(NetworkPolicyManagerInternal.class, 418 new NetworkPolicyManagerInternalImpl()); 419 } 420 bindConnectivityManager(IConnectivityManager connManager)421 public void bindConnectivityManager(IConnectivityManager connManager) { 422 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 423 } 424 bindNotificationManager(INotificationManager notifManager)425 public void bindNotificationManager(INotificationManager notifManager) { 426 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 427 } 428 updatePowerSaveWhitelistLocked()429 void updatePowerSaveWhitelistLocked() { 430 try { 431 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle(); 432 mPowerSaveWhitelistExceptIdleAppIds.clear(); 433 if (whitelist != null) { 434 for (int uid : whitelist) { 435 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); 436 } 437 } 438 whitelist = mDeviceIdleController.getAppIdWhitelist(); 439 mPowerSaveWhitelistAppIds.clear(); 440 if (whitelist != null) { 441 for (int uid : whitelist) { 442 mPowerSaveWhitelistAppIds.put(uid, true); 443 } 444 } 445 } catch (RemoteException e) { 446 } 447 } 448 449 /** 450 * Whitelists pre-defined apps for restrict background, but only if the user didn't already 451 * revoke the whitelist. 452 * 453 * @return whether any uid has been added to {@link #mRestrictBackgroundWhitelistUids}. 454 */ addDefaultRestrictBackgroundWhitelistUidsLocked()455 boolean addDefaultRestrictBackgroundWhitelistUidsLocked() { 456 final List<UserInfo> users = mUserManager.getUsers(); 457 final int numberUsers = users.size(); 458 459 boolean changed = false; 460 for (int i = 0; i < numberUsers; i++) { 461 final UserInfo user = users.get(i); 462 changed = addDefaultRestrictBackgroundWhitelistUidsLocked(user.id) || changed; 463 } 464 return changed; 465 } 466 addDefaultRestrictBackgroundWhitelistUidsLocked(int userId)467 private boolean addDefaultRestrictBackgroundWhitelistUidsLocked(int userId) { 468 final SystemConfig sysConfig = SystemConfig.getInstance(); 469 final PackageManager pm = mContext.getPackageManager(); 470 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave(); 471 boolean changed = false; 472 for (int i = 0; i < allowDataUsage.size(); i++) { 473 final String pkg = allowDataUsage.valueAt(i); 474 if (LOGD) 475 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg 476 + " and user " + userId); 477 final ApplicationInfo app; 478 try { 479 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId); 480 } catch (PackageManager.NameNotFoundException e) { 481 // Should not happen 482 Slog.wtf(TAG, "No ApplicationInfo for package " + pkg); 483 continue; 484 } 485 if (!app.isPrivilegedApp()) { 486 Slog.wtf(TAG, "pm.getApplicationInfoAsUser() returned non-privileged app: " + pkg); 487 continue; 488 } 489 final int uid = UserHandle.getUid(userId, app.uid); 490 mDefaultRestrictBackgroundWhitelistUids.append(uid, true); 491 if (LOGD) 492 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted " 493 + "background whitelist. Revoked status: " 494 + mRestrictBackgroundWhitelistRevokedUids.get(uid)); 495 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 496 Slog.i(TAG, "adding default package " + pkg + " (uid " + uid + " for user " 497 + userId + ") to restrict background whitelist"); 498 mRestrictBackgroundWhitelistUids.append(uid, true); 499 changed = true; 500 } 501 } 502 return changed; 503 } 504 updatePowerSaveTempWhitelistLocked()505 void updatePowerSaveTempWhitelistLocked() { 506 try { 507 // Clear the states of the current whitelist 508 final int N = mPowerSaveTempWhitelistAppIds.size(); 509 for (int i = 0; i < N; i++) { 510 mPowerSaveTempWhitelistAppIds.setValueAt(i, false); 511 } 512 // Update the states with the new whitelist 513 final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist(); 514 if (whitelist != null) { 515 for (int uid : whitelist) { 516 mPowerSaveTempWhitelistAppIds.put(uid, true); 517 } 518 } 519 } catch (RemoteException e) { 520 } 521 } 522 523 /** 524 * Remove unnecessary entries in the temp whitelist 525 */ purgePowerSaveTempWhitelistLocked()526 void purgePowerSaveTempWhitelistLocked() { 527 final int N = mPowerSaveTempWhitelistAppIds.size(); 528 for (int i = N - 1; i >= 0; i--) { 529 if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) { 530 mPowerSaveTempWhitelistAppIds.removeAt(i); 531 } 532 } 533 } 534 systemReady()535 public void systemReady() { 536 if (!isBandwidthControlEnabled()) { 537 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 538 return; 539 } 540 541 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); 542 543 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); 544 545 synchronized (mRulesLock) { 546 updatePowerSaveWhitelistLocked(); 547 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 548 mPowerManagerInternal.registerLowPowerModeObserver( 549 new PowerManagerInternal.LowPowerModeListener() { 550 @Override 551 public void onLowPowerModeChanged(boolean enabled) { 552 if (LOGD) Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")"); 553 synchronized (mRulesLock) { 554 if (mRestrictPower != enabled) { 555 mRestrictPower = enabled; 556 updateRulesForRestrictPowerLocked(); 557 updateRulesForGlobalChangeLocked(true); 558 } 559 } 560 } 561 }); 562 mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled(); 563 564 mSystemReady = true; 565 566 // read policy from disk 567 readPolicyLocked(); 568 569 if (addDefaultRestrictBackgroundWhitelistUidsLocked()) { 570 writePolicyLocked(); 571 } 572 573 updateRulesForGlobalChangeLocked(false); 574 updateNotificationsLocked(); 575 } 576 577 updateScreenOn(); 578 579 try { 580 mActivityManager.registerUidObserver(mUidObserver, 581 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE); 582 mNetworkManager.registerObserver(mAlertObserver); 583 } catch (RemoteException e) { 584 // ignored; both services live in system_server 585 } 586 587 // TODO: traverse existing processes to know foreground state, or have 588 // activitymanager dispatch current state when new observer attached. 589 590 final IntentFilter screenFilter = new IntentFilter(); 591 screenFilter.addAction(Intent.ACTION_SCREEN_ON); 592 screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 593 mContext.registerReceiver(mScreenReceiver, screenFilter); 594 595 // listen for changes to power save whitelist 596 final IntentFilter whitelistFilter = new IntentFilter( 597 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 598 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); 599 600 DeviceIdleController.LocalService deviceIdleService 601 = LocalServices.getService(DeviceIdleController.LocalService.class); 602 deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback); 603 604 // watch for network interfaces to be claimed 605 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 606 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 607 608 // listen for package changes to update policy 609 final IntentFilter packageFilter = new IntentFilter(); 610 packageFilter.addAction(ACTION_PACKAGE_ADDED); 611 packageFilter.addDataScheme("package"); 612 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 613 614 // listen for UID changes to update policy 615 mContext.registerReceiver( 616 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 617 618 // listen for user changes to update policy 619 final IntentFilter userFilter = new IntentFilter(); 620 userFilter.addAction(ACTION_USER_ADDED); 621 userFilter.addAction(ACTION_USER_REMOVED); 622 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 623 624 // listen for stats update events 625 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 626 mContext.registerReceiver( 627 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 628 629 // listen for restrict background changes from notifications 630 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 631 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 632 633 // listen for snooze warning from notifications 634 final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING); 635 mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter, 636 MANAGE_NETWORK_POLICY, mHandler); 637 638 // listen for configured wifi networks to be removed 639 final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); 640 mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler); 641 642 // listen for wifi state changes to catch metered hint 643 final IntentFilter wifiStateFilter = new IntentFilter( 644 WifiManager.NETWORK_STATE_CHANGED_ACTION); 645 mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); 646 647 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); 648 649 } 650 651 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 652 @Override public void onUidStateChanged(int uid, int procState) throws RemoteException { 653 synchronized (mRulesLock) { 654 updateUidStateLocked(uid, procState); 655 } 656 } 657 658 @Override public void onUidGone(int uid) throws RemoteException { 659 synchronized (mRulesLock) { 660 removeUidStateLocked(uid); 661 } 662 } 663 664 @Override public void onUidActive(int uid) throws RemoteException { 665 } 666 667 @Override public void onUidIdle(int uid) throws RemoteException { 668 } 669 }; 670 671 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { 672 @Override 673 public void onReceive(Context context, Intent intent) { 674 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected 675 synchronized (mRulesLock) { 676 updatePowerSaveWhitelistLocked(); 677 updateRulesForGlobalChangeLocked(false); 678 } 679 } 680 }; 681 682 final private Runnable mTempPowerSaveChangedCallback = new Runnable() { 683 @Override 684 public void run() { 685 synchronized (mRulesLock) { 686 updatePowerSaveTempWhitelistLocked(); 687 updateRulesForTempWhitelistChangeLocked(); 688 purgePowerSaveTempWhitelistLocked(); 689 } 690 } 691 }; 692 693 final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 694 @Override 695 public void onReceive(Context context, Intent intent) { 696 // screen-related broadcasts are protected by system, no need 697 // for permissions check. 698 mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); 699 } 700 }; 701 702 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 703 @Override 704 public void onReceive(Context context, Intent intent) { 705 // on background handler thread, and PACKAGE_ADDED is protected 706 707 final String action = intent.getAction(); 708 final int uid = intent.getIntExtra(EXTRA_UID, -1); 709 if (uid == -1) return; 710 711 if (ACTION_PACKAGE_ADDED.equals(action)) { 712 // update rules for UID, since it might be subject to 713 // global background data policy 714 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 715 synchronized (mRulesLock) { 716 updateRestrictionRulesForUidLocked(uid); 717 } 718 } 719 } 720 }; 721 722 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 723 @Override 724 public void onReceive(Context context, Intent intent) { 725 // on background handler thread, and UID_REMOVED is protected 726 727 final int uid = intent.getIntExtra(EXTRA_UID, -1); 728 if (uid == -1) return; 729 730 // remove any policy and update rules to clean up 731 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 732 synchronized (mRulesLock) { 733 mUidPolicy.delete(uid); 734 updateRestrictionRulesForUidLocked(uid); 735 writePolicyLocked(); 736 } 737 } 738 }; 739 740 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 741 @Override 742 public void onReceive(Context context, Intent intent) { 743 // on background handler thread, and USER_ADDED and USER_REMOVED 744 // broadcasts are protected 745 746 final String action = intent.getAction(); 747 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 748 if (userId == -1) return; 749 750 switch (action) { 751 case ACTION_USER_REMOVED: 752 case ACTION_USER_ADDED: 753 synchronized (mRulesLock) { 754 // Remove any persistable state for the given user; both cleaning up after a 755 // USER_REMOVED, and one last sanity check during USER_ADDED 756 removeUserStateLocked(userId, true); 757 if (action == ACTION_USER_ADDED) { 758 // Add apps that are whitelisted by default. 759 addDefaultRestrictBackgroundWhitelistUidsLocked(userId); 760 } 761 // Update global restrict for that user 762 updateRulesForGlobalChangeLocked(true); 763 } 764 break; 765 } 766 } 767 }; 768 769 /** 770 * Receiver that watches for {@link INetworkStatsService} updates, which we 771 * use to check against {@link NetworkPolicy#warningBytes}. 772 */ 773 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 774 @Override 775 public void onReceive(Context context, Intent intent) { 776 // on background handler thread, and verified 777 // READ_NETWORK_USAGE_HISTORY permission above. 778 779 maybeRefreshTrustedTime(); 780 synchronized (mRulesLock) { 781 updateNetworkEnabledLocked(); 782 updateNotificationsLocked(); 783 } 784 } 785 }; 786 787 /** 788 * Receiver that watches for {@link Notification} control of 789 * {@link #mRestrictBackground}. 790 */ 791 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 792 @Override 793 public void onReceive(Context context, Intent intent) { 794 // on background handler thread, and verified MANAGE_NETWORK_POLICY 795 // permission above. 796 797 setRestrictBackground(false); 798 } 799 }; 800 801 /** 802 * Receiver that watches for {@link Notification} control of 803 * {@link NetworkPolicy#lastWarningSnooze}. 804 */ 805 final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { 806 @Override 807 public void onReceive(Context context, Intent intent) { 808 // on background handler thread, and verified MANAGE_NETWORK_POLICY 809 // permission above. 810 811 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 812 performSnooze(template, TYPE_WARNING); 813 } 814 }; 815 816 /** 817 * Receiver that watches for {@link WifiConfiguration} to be changed. 818 */ 819 final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { 820 @Override 821 public void onReceive(Context context, Intent intent) { 822 // on background handler thread, and verified CONNECTIVITY_INTERNAL 823 // permission above. 824 825 final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED); 826 if (reason == CHANGE_REASON_REMOVED) { 827 final WifiConfiguration config = intent.getParcelableExtra( 828 EXTRA_WIFI_CONFIGURATION); 829 if (config.SSID != null) { 830 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID); 831 synchronized (mRulesLock) { 832 if (mNetworkPolicy.containsKey(template)) { 833 mNetworkPolicy.remove(template); 834 writePolicyLocked(); 835 } 836 } 837 } 838 } 839 } 840 }; 841 842 /** 843 * Receiver that watches {@link WifiInfo} state changes to infer metered 844 * state. Ignores hints when policy is user-defined. 845 */ 846 final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 847 @Override 848 public void onReceive(Context context, Intent intent) { 849 // on background handler thread, and verified CONNECTIVITY_INTERNAL 850 // permission above. 851 852 // ignore when not connected 853 final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 854 if (!netInfo.isConnected()) return; 855 856 final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO); 857 final boolean meteredHint = info.getMeteredHint(); 858 859 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID()); 860 synchronized (mRulesLock) { 861 NetworkPolicy policy = mNetworkPolicy.get(template); 862 if (policy == null && meteredHint) { 863 // policy doesn't exist, and AP is hinting that it's 864 // metered: create an inferred policy. 865 policy = newWifiPolicy(template, meteredHint); 866 addNetworkPolicyLocked(policy); 867 868 } else if (policy != null && policy.inferred) { 869 // policy exists, and was inferred: update its current 870 // metered state. 871 policy.metered = meteredHint; 872 873 // since this is inferred for each wifi session, just update 874 // rules without persisting. 875 updateNetworkRulesLocked(); 876 } 877 } 878 } 879 }; 880 newWifiPolicy(NetworkTemplate template, boolean metered)881 static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) { 882 return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC, 883 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, 884 metered, true); 885 } 886 887 /** 888 * Observer that watches for {@link INetworkManagementService} alerts. 889 */ 890 final private INetworkManagementEventObserver mAlertObserver 891 = new BaseNetworkObserver() { 892 @Override 893 public void limitReached(String limitName, String iface) { 894 // only someone like NMS should be calling us 895 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 896 897 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 898 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 899 } 900 } 901 }; 902 903 /** 904 * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 905 * to show visible notifications as needed. 906 */ updateNotificationsLocked()907 void updateNotificationsLocked() { 908 if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 909 910 // keep track of previously active notifications 911 final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs); 912 mActiveNotifs.clear(); 913 914 // TODO: when switching to kernel notifications, compute next future 915 // cycle boundary to recompute notifications. 916 917 // examine stats for each active policy 918 final long currentTime = currentTimeMillis(); 919 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 920 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 921 // ignore policies that aren't relevant to user 922 if (!isTemplateRelevant(policy.template)) continue; 923 if (!policy.hasCycle()) continue; 924 925 final long start = computeLastCycleBoundary(currentTime, policy); 926 final long end = currentTime; 927 final long totalBytes = getTotalBytes(policy.template, start, end); 928 929 if (policy.isOverLimit(totalBytes)) { 930 if (policy.lastLimitSnooze >= start) { 931 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 932 } else { 933 enqueueNotification(policy, TYPE_LIMIT, totalBytes); 934 notifyOverLimitLocked(policy.template); 935 } 936 937 } else { 938 notifyUnderLimitLocked(policy.template); 939 940 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) { 941 enqueueNotification(policy, TYPE_WARNING, totalBytes); 942 } 943 } 944 } 945 946 // cancel stale notifications that we didn't renew above 947 for (int i = beforeNotifs.size()-1; i >= 0; i--) { 948 final String tag = beforeNotifs.valueAt(i); 949 if (!mActiveNotifs.contains(tag)) { 950 cancelNotification(tag); 951 } 952 } 953 } 954 955 /** 956 * Test if given {@link NetworkTemplate} is relevant to user based on 957 * current device state, such as when 958 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 959 * data connection status. 960 */ isTemplateRelevant(NetworkTemplate template)961 private boolean isTemplateRelevant(NetworkTemplate template) { 962 if (template.isMatchRuleMobile()) { 963 final TelephonyManager tele = TelephonyManager.from(mContext); 964 final SubscriptionManager sub = SubscriptionManager.from(mContext); 965 966 // Mobile template is relevant when any active subscriber matches 967 final int[] subIds = sub.getActiveSubscriptionIdList(); 968 for (int subId : subIds) { 969 final String subscriberId = tele.getSubscriberId(subId); 970 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 971 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 972 if (template.matches(probeIdent)) { 973 return true; 974 } 975 } 976 return false; 977 } else { 978 return true; 979 } 980 } 981 982 /** 983 * Notify that given {@link NetworkTemplate} is over 984 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 985 */ notifyOverLimitLocked(NetworkTemplate template)986 private void notifyOverLimitLocked(NetworkTemplate template) { 987 if (!mOverLimitNotified.contains(template)) { 988 mContext.startActivity(buildNetworkOverLimitIntent(template)); 989 mOverLimitNotified.add(template); 990 } 991 } 992 notifyUnderLimitLocked(NetworkTemplate template)993 private void notifyUnderLimitLocked(NetworkTemplate template) { 994 mOverLimitNotified.remove(template); 995 } 996 997 /** 998 * Build unique tag that identifies an active {@link NetworkPolicy} 999 * notification of a specific type, like {@link #TYPE_LIMIT}. 1000 */ buildNotificationTag(NetworkPolicy policy, int type)1001 private String buildNotificationTag(NetworkPolicy policy, int type) { 1002 return TAG + ":" + policy.template.hashCode() + ":" + type; 1003 } 1004 1005 /** 1006 * Show notification for combined {@link NetworkPolicy} and specific type, 1007 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 1008 */ enqueueNotification(NetworkPolicy policy, int type, long totalBytes)1009 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 1010 final String tag = buildNotificationTag(policy, type); 1011 final Notification.Builder builder = new Notification.Builder(mContext); 1012 builder.setOnlyAlertOnce(true); 1013 builder.setWhen(0L); 1014 builder.setColor(mContext.getColor( 1015 com.android.internal.R.color.system_notification_accent_color)); 1016 1017 final Resources res = mContext.getResources(); 1018 switch (type) { 1019 case TYPE_WARNING: { 1020 final CharSequence title = res.getText(R.string.data_usage_warning_title); 1021 final CharSequence body = res.getString(R.string.data_usage_warning_body); 1022 1023 builder.setSmallIcon(R.drawable.stat_notify_error); 1024 builder.setTicker(title); 1025 builder.setContentTitle(title); 1026 builder.setContentText(body); 1027 1028 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template); 1029 builder.setDeleteIntent(PendingIntent.getBroadcast( 1030 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1031 1032 final Intent viewIntent = buildViewDataUsageIntent(policy.template); 1033 builder.setContentIntent(PendingIntent.getActivity( 1034 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1035 1036 break; 1037 } 1038 case TYPE_LIMIT: { 1039 final CharSequence body = res.getText(R.string.data_usage_limit_body); 1040 1041 final CharSequence title; 1042 int icon = R.drawable.stat_notify_disabled_data; 1043 switch (policy.template.getMatchRule()) { 1044 case MATCH_MOBILE_3G_LOWER: 1045 title = res.getText(R.string.data_usage_3g_limit_title); 1046 break; 1047 case MATCH_MOBILE_4G: 1048 title = res.getText(R.string.data_usage_4g_limit_title); 1049 break; 1050 case MATCH_MOBILE_ALL: 1051 title = res.getText(R.string.data_usage_mobile_limit_title); 1052 break; 1053 case MATCH_WIFI: 1054 title = res.getText(R.string.data_usage_wifi_limit_title); 1055 icon = R.drawable.stat_notify_error; 1056 break; 1057 default: 1058 title = null; 1059 break; 1060 } 1061 1062 builder.setOngoing(true); 1063 builder.setSmallIcon(icon); 1064 builder.setTicker(title); 1065 builder.setContentTitle(title); 1066 builder.setContentText(body); 1067 1068 final Intent intent = buildNetworkOverLimitIntent(policy.template); 1069 builder.setContentIntent(PendingIntent.getActivity( 1070 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1071 break; 1072 } 1073 case TYPE_LIMIT_SNOOZED: { 1074 final long overBytes = totalBytes - policy.limitBytes; 1075 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 1076 Formatter.formatFileSize(mContext, overBytes)); 1077 1078 final CharSequence title; 1079 switch (policy.template.getMatchRule()) { 1080 case MATCH_MOBILE_3G_LOWER: 1081 title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 1082 break; 1083 case MATCH_MOBILE_4G: 1084 title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 1085 break; 1086 case MATCH_MOBILE_ALL: 1087 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 1088 break; 1089 case MATCH_WIFI: 1090 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 1091 break; 1092 default: 1093 title = null; 1094 break; 1095 } 1096 1097 builder.setOngoing(true); 1098 builder.setSmallIcon(R.drawable.stat_notify_error); 1099 builder.setTicker(title); 1100 builder.setContentTitle(title); 1101 builder.setContentText(body); 1102 1103 final Intent intent = buildViewDataUsageIntent(policy.template); 1104 builder.setContentIntent(PendingIntent.getActivity( 1105 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1106 break; 1107 } 1108 } 1109 1110 // TODO: move to NotificationManager once we can mock it 1111 try { 1112 final String packageName = mContext.getPackageName(); 1113 final int[] idReceived = new int[1]; 1114 mNotifManager.enqueueNotificationWithTag( 1115 packageName, packageName, tag, 0x0, builder.getNotification(), idReceived, 1116 UserHandle.USER_ALL); 1117 mActiveNotifs.add(tag); 1118 } catch (RemoteException e) { 1119 // ignored; service lives in system_server 1120 } 1121 } 1122 cancelNotification(String tag)1123 private void cancelNotification(String tag) { 1124 // TODO: move to NotificationManager once we can mock it 1125 try { 1126 final String packageName = mContext.getPackageName(); 1127 mNotifManager.cancelNotificationWithTag( 1128 packageName, tag, 0x0, UserHandle.USER_ALL); 1129 } catch (RemoteException e) { 1130 // ignored; service lives in system_server 1131 } 1132 } 1133 1134 /** 1135 * Receiver that watches for {@link IConnectivityManager} to claim network 1136 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 1137 */ 1138 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 1139 @Override 1140 public void onReceive(Context context, Intent intent) { 1141 // on background handler thread, and verified CONNECTIVITY_INTERNAL 1142 // permission above. 1143 1144 maybeRefreshTrustedTime(); 1145 synchronized (mRulesLock) { 1146 ensureActiveMobilePolicyLocked(); 1147 normalizePoliciesLocked(); 1148 updateNetworkEnabledLocked(); 1149 updateNetworkRulesLocked(); 1150 updateNotificationsLocked(); 1151 } 1152 } 1153 }; 1154 1155 /** 1156 * Proactively control network data connections when they exceed 1157 * {@link NetworkPolicy#limitBytes}. 1158 */ updateNetworkEnabledLocked()1159 void updateNetworkEnabledLocked() { 1160 if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()"); 1161 1162 // TODO: reset any policy-disabled networks when any policy is removed 1163 // completely, which is currently rare case. 1164 1165 final long currentTime = currentTimeMillis(); 1166 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1167 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1168 // shortcut when policy has no limit 1169 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 1170 setNetworkTemplateEnabled(policy.template, true); 1171 continue; 1172 } 1173 1174 final long start = computeLastCycleBoundary(currentTime, policy); 1175 final long end = currentTime; 1176 final long totalBytes = getTotalBytes(policy.template, start, end); 1177 1178 // disable data connection when over limit and not snoozed 1179 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 1180 && policy.lastLimitSnooze < start; 1181 final boolean networkEnabled = !overLimitWithoutSnooze; 1182 1183 setNetworkTemplateEnabled(policy.template, networkEnabled); 1184 } 1185 } 1186 1187 /** 1188 * Proactively disable networks that match the given 1189 * {@link NetworkTemplate}. 1190 */ 1191 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 1192 // TODO: reach into ConnectivityManager to proactively disable bringing 1193 // up this network, since we know that traffic will be blocked. 1194 } 1195 1196 /** 1197 * Examine all connected {@link NetworkState}, looking for 1198 * {@link NetworkPolicy} that need to be enforced. When matches found, set 1199 * remaining quota based on usage cycle and historical stats. 1200 */ 1201 void updateNetworkRulesLocked() { 1202 if (LOGV) Slog.v(TAG, "updateNetworkRulesLocked()"); 1203 1204 final NetworkState[] states; 1205 try { 1206 states = mConnManager.getAllNetworkState(); 1207 } catch (RemoteException e) { 1208 // ignored; service lives in system_server 1209 return; 1210 } 1211 1212 // First, generate identities of all connected networks so we can 1213 // quickly compare them against all defined policies below. 1214 final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); 1215 final ArraySet<String> connIfaces = new ArraySet<String>(states.length); 1216 for (NetworkState state : states) { 1217 if (state.networkInfo != null && state.networkInfo.isConnected()) { 1218 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1219 1220 final String baseIface = state.linkProperties.getInterfaceName(); 1221 if (baseIface != null) { 1222 connIdents.add(Pair.create(baseIface, ident)); 1223 } 1224 1225 // Stacked interfaces are considered to have same identity as 1226 // their parent network. 1227 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); 1228 for (LinkProperties stackedLink : stackedLinks) { 1229 final String stackedIface = stackedLink.getInterfaceName(); 1230 if (stackedIface != null) { 1231 connIdents.add(Pair.create(stackedIface, ident)); 1232 } 1233 } 1234 } 1235 } 1236 1237 // Apply policies against all connected interfaces found above 1238 mNetworkRules.clear(); 1239 final ArrayList<String> ifaceList = Lists.newArrayList(); 1240 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1241 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1242 1243 ifaceList.clear(); 1244 for (int j = connIdents.size() - 1; j >= 0; j--) { 1245 final Pair<String, NetworkIdentity> ident = connIdents.get(j); 1246 if (policy.template.matches(ident.second)) { 1247 ifaceList.add(ident.first); 1248 } 1249 } 1250 1251 if (ifaceList.size() > 0) { 1252 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 1253 mNetworkRules.put(policy, ifaces); 1254 } 1255 } 1256 1257 long lowestRule = Long.MAX_VALUE; 1258 final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length); 1259 1260 // apply each policy that we found ifaces for; compute remaining data 1261 // based on current cycle and historical stats, and push to kernel. 1262 final long currentTime = currentTimeMillis(); 1263 for (int i = mNetworkRules.size()-1; i >= 0; i--) { 1264 final NetworkPolicy policy = mNetworkRules.keyAt(i); 1265 final String[] ifaces = mNetworkRules.valueAt(i); 1266 1267 final long start; 1268 final long totalBytes; 1269 if (policy.hasCycle()) { 1270 start = computeLastCycleBoundary(currentTime, policy); 1271 totalBytes = getTotalBytes(policy.template, start, currentTime); 1272 } else { 1273 start = Long.MAX_VALUE; 1274 totalBytes = 0; 1275 } 1276 1277 if (LOGD) { 1278 Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces)); 1279 } 1280 1281 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 1282 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 1283 if (hasLimit || policy.metered) { 1284 final long quotaBytes; 1285 if (!hasLimit) { 1286 // metered network, but no policy limit; we still need to 1287 // restrict apps, so push really high quota. 1288 quotaBytes = Long.MAX_VALUE; 1289 } else if (policy.lastLimitSnooze >= start) { 1290 // snoozing past quota, but we still need to restrict apps, 1291 // so push really high quota. 1292 quotaBytes = Long.MAX_VALUE; 1293 } else { 1294 // remaining "quota" bytes are based on total usage in 1295 // current cycle. kernel doesn't like 0-byte rules, so we 1296 // set 1-byte quota and disable the radio later. 1297 quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 1298 } 1299 1300 if (ifaces.length > 1) { 1301 // TODO: switch to shared quota once NMS supports 1302 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 1303 } 1304 1305 for (String iface : ifaces) { 1306 // long quotaBytes split up into two ints to fit in message 1307 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1308 (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface) 1309 .sendToTarget(); 1310 newMeteredIfaces.add(iface); 1311 } 1312 } 1313 1314 // keep track of lowest warning or limit of active policies 1315 if (hasWarning && policy.warningBytes < lowestRule) { 1316 lowestRule = policy.warningBytes; 1317 } 1318 if (hasLimit && policy.limitBytes < lowestRule) { 1319 lowestRule = policy.limitBytes; 1320 } 1321 } 1322 1323 for (int i = connIfaces.size()-1; i >= 0; i--) { 1324 String iface = connIfaces.valueAt(i); 1325 // long quotaBytes split up into two ints to fit in message 1326 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1327 (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface) 1328 .sendToTarget(); 1329 newMeteredIfaces.add(iface); 1330 } 1331 1332 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 1333 1334 // remove quota on any trailing interfaces 1335 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) { 1336 final String iface = mMeteredIfaces.valueAt(i); 1337 if (!newMeteredIfaces.contains(iface)) { 1338 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface) 1339 .sendToTarget(); 1340 } 1341 } 1342 mMeteredIfaces = newMeteredIfaces; 1343 1344 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 1345 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 1346 } 1347 1348 /** 1349 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 1350 * have at least a default mobile policy defined. 1351 */ ensureActiveMobilePolicyLocked()1352 private void ensureActiveMobilePolicyLocked() { 1353 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 1354 if (mSuppressDefaultPolicy) return; 1355 1356 final TelephonyManager tele = TelephonyManager.from(mContext); 1357 final SubscriptionManager sub = SubscriptionManager.from(mContext); 1358 1359 final int[] subIds = sub.getActiveSubscriptionIdList(); 1360 for (int subId : subIds) { 1361 final String subscriberId = tele.getSubscriberId(subId); 1362 ensureActiveMobilePolicyLocked(subscriberId); 1363 } 1364 } 1365 ensureActiveMobilePolicyLocked(String subscriberId)1366 private void ensureActiveMobilePolicyLocked(String subscriberId) { 1367 // Poke around to see if we already have a policy 1368 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1369 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1370 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1371 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1372 if (template.matches(probeIdent)) { 1373 if (LOGD) { 1374 Slog.d(TAG, "Found template " + template + " which matches subscriber " 1375 + NetworkIdentity.scrubSubscriberId(subscriberId)); 1376 } 1377 return; 1378 } 1379 } 1380 1381 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId) 1382 + "; generating default policy"); 1383 1384 // Build default mobile policy, and assume usage cycle starts today 1385 final long warningBytes = mContext.getResources().getInteger( 1386 com.android.internal.R.integer.config_networkPolicyDefaultWarning) * MB_IN_BYTES; 1387 1388 final Time time = new Time(); 1389 time.setToNow(); 1390 1391 final int cycleDay = time.monthDay; 1392 final String cycleTimezone = time.timezone; 1393 1394 final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 1395 final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, 1396 warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true); 1397 addNetworkPolicyLocked(policy); 1398 } 1399 readPolicyLocked()1400 private void readPolicyLocked() { 1401 if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 1402 1403 // clear any existing policy and read from disk 1404 mNetworkPolicy.clear(); 1405 mUidPolicy.clear(); 1406 1407 FileInputStream fis = null; 1408 try { 1409 fis = mPolicyFile.openRead(); 1410 final XmlPullParser in = Xml.newPullParser(); 1411 in.setInput(fis, StandardCharsets.UTF_8.name()); 1412 1413 int type; 1414 int version = VERSION_INIT; 1415 boolean insideWhitelist = false; 1416 while ((type = in.next()) != END_DOCUMENT) { 1417 final String tag = in.getName(); 1418 if (type == START_TAG) { 1419 if (TAG_POLICY_LIST.equals(tag)) { 1420 final boolean oldValue = mRestrictBackground; 1421 version = readIntAttribute(in, ATTR_VERSION); 1422 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 1423 mRestrictBackground = readBooleanAttribute( 1424 in, ATTR_RESTRICT_BACKGROUND); 1425 } else { 1426 mRestrictBackground = false; 1427 } 1428 if (mRestrictBackground != oldValue) { 1429 // Some early services may have read the default value, 1430 // so notify them that it's changed 1431 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, 1432 mRestrictBackground ? 1 : 0, 0).sendToTarget(); 1433 } 1434 1435 } else if (TAG_NETWORK_POLICY.equals(tag)) { 1436 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 1437 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 1438 final String networkId; 1439 if (version >= VERSION_ADDED_NETWORK_ID) { 1440 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 1441 } else { 1442 networkId = null; 1443 } 1444 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 1445 final String cycleTimezone; 1446 if (version >= VERSION_ADDED_TIMEZONE) { 1447 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 1448 } else { 1449 cycleTimezone = Time.TIMEZONE_UTC; 1450 } 1451 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 1452 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 1453 final long lastLimitSnooze; 1454 if (version >= VERSION_SPLIT_SNOOZE) { 1455 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 1456 } else if (version >= VERSION_ADDED_SNOOZE) { 1457 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 1458 } else { 1459 lastLimitSnooze = SNOOZE_NEVER; 1460 } 1461 final boolean metered; 1462 if (version >= VERSION_ADDED_METERED) { 1463 metered = readBooleanAttribute(in, ATTR_METERED); 1464 } else { 1465 switch (networkTemplate) { 1466 case MATCH_MOBILE_3G_LOWER: 1467 case MATCH_MOBILE_4G: 1468 case MATCH_MOBILE_ALL: 1469 metered = true; 1470 break; 1471 default: 1472 metered = false; 1473 } 1474 } 1475 final long lastWarningSnooze; 1476 if (version >= VERSION_SPLIT_SNOOZE) { 1477 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 1478 } else { 1479 lastWarningSnooze = SNOOZE_NEVER; 1480 } 1481 final boolean inferred; 1482 if (version >= VERSION_ADDED_INFERRED) { 1483 inferred = readBooleanAttribute(in, ATTR_INFERRED); 1484 } else { 1485 inferred = false; 1486 } 1487 1488 final NetworkTemplate template = new NetworkTemplate(networkTemplate, 1489 subscriberId, networkId); 1490 if (template.isPersistable()) { 1491 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, 1492 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, 1493 lastLimitSnooze, metered, inferred)); 1494 } 1495 1496 } else if (TAG_UID_POLICY.equals(tag)) { 1497 final int uid = readIntAttribute(in, ATTR_UID); 1498 final int policy = readIntAttribute(in, ATTR_POLICY); 1499 1500 if (UserHandle.isApp(uid)) { 1501 setUidPolicyUncheckedLocked(uid, policy, false); 1502 } else { 1503 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1504 } 1505 } else if (TAG_APP_POLICY.equals(tag)) { 1506 final int appId = readIntAttribute(in, ATTR_APP_ID); 1507 final int policy = readIntAttribute(in, ATTR_POLICY); 1508 1509 // TODO: set for other users during upgrade 1510 // app policy is deprecated so this is only used in pre system user split. 1511 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId); 1512 if (UserHandle.isApp(uid)) { 1513 setUidPolicyUncheckedLocked(uid, policy, false); 1514 } else { 1515 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1516 } 1517 } else if (TAG_WHITELIST.equals(tag)) { 1518 insideWhitelist = true; 1519 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1520 final int uid = readIntAttribute(in, ATTR_UID); 1521 mRestrictBackgroundWhitelistUids.put(uid, true); 1522 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1523 final int uid = readIntAttribute(in, ATTR_UID); 1524 mRestrictBackgroundWhitelistRevokedUids.put(uid, true); 1525 } 1526 } else if (type == END_TAG) { 1527 if (TAG_WHITELIST.equals(tag)) { 1528 insideWhitelist = false; 1529 } 1530 1531 } 1532 } 1533 1534 } catch (FileNotFoundException e) { 1535 // missing policy is okay, probably first boot 1536 upgradeLegacyBackgroundData(); 1537 } catch (IOException e) { 1538 Log.wtf(TAG, "problem reading network policy", e); 1539 } catch (XmlPullParserException e) { 1540 Log.wtf(TAG, "problem reading network policy", e); 1541 } finally { 1542 IoUtils.closeQuietly(fis); 1543 } 1544 } 1545 1546 /** 1547 * Upgrade legacy background data flags, notifying listeners of one last 1548 * change to always-true. 1549 */ upgradeLegacyBackgroundData()1550 private void upgradeLegacyBackgroundData() { 1551 mRestrictBackground = Settings.Secure.getInt( 1552 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 1553 1554 // kick off one last broadcast if restricted 1555 if (mRestrictBackground) { 1556 final Intent broadcast = new Intent( 1557 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 1558 mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL); 1559 } 1560 } 1561 writePolicyLocked()1562 void writePolicyLocked() { 1563 if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 1564 1565 FileOutputStream fos = null; 1566 try { 1567 fos = mPolicyFile.startWrite(); 1568 1569 XmlSerializer out = new FastXmlSerializer(); 1570 out.setOutput(fos, StandardCharsets.UTF_8.name()); 1571 out.startDocument(null, true); 1572 1573 out.startTag(null, TAG_POLICY_LIST); 1574 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 1575 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 1576 1577 // write all known network policies 1578 for (int i = 0; i < mNetworkPolicy.size(); i++) { 1579 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1580 final NetworkTemplate template = policy.template; 1581 if (!template.isPersistable()) continue; 1582 1583 out.startTag(null, TAG_NETWORK_POLICY); 1584 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 1585 final String subscriberId = template.getSubscriberId(); 1586 if (subscriberId != null) { 1587 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 1588 } 1589 final String networkId = template.getNetworkId(); 1590 if (networkId != null) { 1591 out.attribute(null, ATTR_NETWORK_ID, networkId); 1592 } 1593 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 1594 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone); 1595 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 1596 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 1597 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 1598 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 1599 writeBooleanAttribute(out, ATTR_METERED, policy.metered); 1600 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 1601 out.endTag(null, TAG_NETWORK_POLICY); 1602 } 1603 1604 // write all known uid policies 1605 for (int i = 0; i < mUidPolicy.size(); i++) { 1606 final int uid = mUidPolicy.keyAt(i); 1607 final int policy = mUidPolicy.valueAt(i); 1608 1609 // skip writing empty policies 1610 if (policy == POLICY_NONE) continue; 1611 1612 out.startTag(null, TAG_UID_POLICY); 1613 writeIntAttribute(out, ATTR_UID, uid); 1614 writeIntAttribute(out, ATTR_POLICY, policy); 1615 out.endTag(null, TAG_UID_POLICY); 1616 } 1617 1618 out.endTag(null, TAG_POLICY_LIST); 1619 1620 // write all whitelists 1621 out.startTag(null, TAG_WHITELIST); 1622 1623 // restrict background whitelist 1624 int size = mRestrictBackgroundWhitelistUids.size(); 1625 for (int i = 0; i < size; i++) { 1626 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); 1627 out.startTag(null, TAG_RESTRICT_BACKGROUND); 1628 writeIntAttribute(out, ATTR_UID, uid); 1629 out.endTag(null, TAG_RESTRICT_BACKGROUND); 1630 } 1631 1632 // revoked restrict background whitelist 1633 size = mRestrictBackgroundWhitelistRevokedUids.size(); 1634 for (int i = 0; i < size; i++) { 1635 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 1636 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 1637 writeIntAttribute(out, ATTR_UID, uid); 1638 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 1639 } 1640 1641 out.endTag(null, TAG_WHITELIST); 1642 1643 out.endDocument(); 1644 1645 mPolicyFile.finishWrite(fos); 1646 } catch (IOException e) { 1647 if (fos != null) { 1648 mPolicyFile.failWrite(fos); 1649 } 1650 } 1651 } 1652 1653 @Override setUidPolicy(int uid, int policy)1654 public void setUidPolicy(int uid, int policy) { 1655 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1656 1657 if (!UserHandle.isApp(uid)) { 1658 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1659 } 1660 1661 synchronized (mRulesLock) { 1662 final long token = Binder.clearCallingIdentity(); 1663 try { 1664 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1665 if (oldPolicy != policy) { 1666 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1667 } 1668 } finally { 1669 Binder.restoreCallingIdentity(token); 1670 } 1671 } 1672 } 1673 1674 @Override addUidPolicy(int uid, int policy)1675 public void addUidPolicy(int uid, int policy) { 1676 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1677 1678 if (!UserHandle.isApp(uid)) { 1679 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1680 } 1681 1682 synchronized (mRulesLock) { 1683 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1684 policy |= oldPolicy; 1685 if (oldPolicy != policy) { 1686 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1687 } 1688 } 1689 } 1690 1691 @Override removeUidPolicy(int uid, int policy)1692 public void removeUidPolicy(int uid, int policy) { 1693 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1694 1695 if (!UserHandle.isApp(uid)) { 1696 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1697 } 1698 1699 synchronized (mRulesLock) { 1700 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 1701 policy = oldPolicy & ~policy; 1702 if (oldPolicy != policy) { 1703 setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); 1704 } 1705 } 1706 } 1707 setUidPolicyUncheckedLocked(int uid, int oldPolicy, int policy, boolean persist)1708 private void setUidPolicyUncheckedLocked(int uid, int oldPolicy, int policy, boolean persist) { 1709 setUidPolicyUncheckedLocked(uid, policy, persist); 1710 1711 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND; 1712 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED, uid, 1713 isBlacklisted ? 1 : 0).sendToTarget(); 1714 1715 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; 1716 // Checks if app was added or removed to the blacklist. 1717 if ((oldPolicy == POLICY_NONE && isBlacklisted) 1718 || (wasBlacklisted && policy == POLICY_NONE)) { 1719 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 1, null) 1720 .sendToTarget(); 1721 } 1722 } 1723 setUidPolicyUncheckedLocked(int uid, int policy, boolean persist)1724 private void setUidPolicyUncheckedLocked(int uid, int policy, boolean persist) { 1725 mUidPolicy.put(uid, policy); 1726 1727 // uid policy changed, recompute rules and persist policy. 1728 updateRulesForDataUsageRestrictionsLocked(uid); 1729 if (persist) { 1730 writePolicyLocked(); 1731 } 1732 } 1733 1734 @Override getUidPolicy(int uid)1735 public int getUidPolicy(int uid) { 1736 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1737 1738 synchronized (mRulesLock) { 1739 return mUidPolicy.get(uid, POLICY_NONE); 1740 } 1741 } 1742 1743 @Override getUidsWithPolicy(int policy)1744 public int[] getUidsWithPolicy(int policy) { 1745 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1746 1747 int[] uids = new int[0]; 1748 synchronized (mRulesLock) { 1749 for (int i = 0; i < mUidPolicy.size(); i++) { 1750 final int uid = mUidPolicy.keyAt(i); 1751 final int uidPolicy = mUidPolicy.valueAt(i); 1752 if (uidPolicy == policy) { 1753 uids = appendInt(uids, uid); 1754 } 1755 } 1756 } 1757 return uids; 1758 } 1759 1760 /** 1761 * Removes any persistable state associated with given {@link UserHandle}, persisting 1762 * if any changes that are made. 1763 */ removeUserStateLocked(int userId, boolean writePolicy)1764 boolean removeUserStateLocked(int userId, boolean writePolicy) { 1765 1766 if (LOGV) Slog.v(TAG, "removeUserStateLocked()"); 1767 boolean changed = false; 1768 1769 // Remove entries from restricted background UID whitelist 1770 int[] wlUids = new int[0]; 1771 for (int i = 0; i < mRestrictBackgroundWhitelistUids.size(); i++) { 1772 final int uid = mRestrictBackgroundWhitelistUids.keyAt(i); 1773 if (UserHandle.getUserId(uid) == userId) { 1774 wlUids = appendInt(wlUids, uid); 1775 } 1776 } 1777 1778 if (wlUids.length > 0) { 1779 for (int uid : wlUids) { 1780 removeRestrictBackgroundWhitelistedUidLocked(uid, false, false); 1781 } 1782 changed = true; 1783 } 1784 1785 // Remove entries from revoked default restricted background UID whitelist 1786 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) { 1787 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 1788 if (UserHandle.getUserId(uid) == userId) { 1789 mRestrictBackgroundWhitelistRevokedUids.removeAt(i); 1790 changed = true; 1791 } 1792 } 1793 1794 // Remove associated UID policies 1795 int[] uids = new int[0]; 1796 for (int i = 0; i < mUidPolicy.size(); i++) { 1797 final int uid = mUidPolicy.keyAt(i); 1798 if (UserHandle.getUserId(uid) == userId) { 1799 uids = appendInt(uids, uid); 1800 } 1801 } 1802 1803 if (uids.length > 0) { 1804 for (int uid : uids) { 1805 mUidPolicy.delete(uid); 1806 } 1807 changed = true; 1808 } 1809 1810 updateRulesForGlobalChangeLocked(true); 1811 1812 if (writePolicy && changed) { 1813 writePolicyLocked(); 1814 } 1815 return changed; 1816 } 1817 1818 @Override setConnectivityListener(INetworkPolicyListener listener)1819 public void setConnectivityListener(INetworkPolicyListener listener) { 1820 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1821 if (mConnectivityListener != null) { 1822 throw new IllegalStateException("Connectivity listener already registered"); 1823 } 1824 mConnectivityListener = listener; 1825 } 1826 1827 @Override registerListener(INetworkPolicyListener listener)1828 public void registerListener(INetworkPolicyListener listener) { 1829 // TODO: create permission for observing network policy 1830 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1831 mListeners.register(listener); 1832 } 1833 1834 @Override unregisterListener(INetworkPolicyListener listener)1835 public void unregisterListener(INetworkPolicyListener listener) { 1836 // TODO: create permission for observing network policy 1837 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1838 mListeners.unregister(listener); 1839 } 1840 1841 @Override setNetworkPolicies(NetworkPolicy[] policies)1842 public void setNetworkPolicies(NetworkPolicy[] policies) { 1843 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1844 1845 final long token = Binder.clearCallingIdentity(); 1846 try { 1847 maybeRefreshTrustedTime(); 1848 synchronized (mRulesLock) { 1849 normalizePoliciesLocked(policies); 1850 updateNetworkEnabledLocked(); 1851 updateNetworkRulesLocked(); 1852 updateNotificationsLocked(); 1853 writePolicyLocked(); 1854 } 1855 } finally { 1856 Binder.restoreCallingIdentity(token); 1857 } 1858 } 1859 addNetworkPolicyLocked(NetworkPolicy policy)1860 void addNetworkPolicyLocked(NetworkPolicy policy) { 1861 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 1862 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy); 1863 setNetworkPolicies(policies); 1864 } 1865 1866 @Override getNetworkPolicies(String callingPackage)1867 public NetworkPolicy[] getNetworkPolicies(String callingPackage) { 1868 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1869 try { 1870 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); 1871 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED 1872 // permission 1873 } catch (SecurityException e) { 1874 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 1875 1876 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 1877 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1878 return new NetworkPolicy[0]; 1879 } 1880 } 1881 1882 synchronized (mRulesLock) { 1883 final int size = mNetworkPolicy.size(); 1884 final NetworkPolicy[] policies = new NetworkPolicy[size]; 1885 for (int i = 0; i < size; i++) { 1886 policies[i] = mNetworkPolicy.valueAt(i); 1887 } 1888 return policies; 1889 } 1890 } 1891 normalizePoliciesLocked()1892 private void normalizePoliciesLocked() { 1893 normalizePoliciesLocked(getNetworkPolicies(mContext.getOpPackageName())); 1894 } 1895 normalizePoliciesLocked(NetworkPolicy[] policies)1896 private void normalizePoliciesLocked(NetworkPolicy[] policies) { 1897 final TelephonyManager tele = TelephonyManager.from(mContext); 1898 final String[] merged = tele.getMergedSubscriberIds(); 1899 1900 mNetworkPolicy.clear(); 1901 for (NetworkPolicy policy : policies) { 1902 // When two normalized templates conflict, prefer the most 1903 // restrictive policy 1904 policy.template = NetworkTemplate.normalize(policy.template, merged); 1905 final NetworkPolicy existing = mNetworkPolicy.get(policy.template); 1906 if (existing == null || existing.compareTo(policy) > 0) { 1907 if (existing != null) { 1908 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy); 1909 } 1910 mNetworkPolicy.put(policy.template, policy); 1911 } 1912 } 1913 } 1914 1915 @Override snoozeLimit(NetworkTemplate template)1916 public void snoozeLimit(NetworkTemplate template) { 1917 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1918 1919 final long token = Binder.clearCallingIdentity(); 1920 try { 1921 performSnooze(template, TYPE_LIMIT); 1922 } finally { 1923 Binder.restoreCallingIdentity(token); 1924 } 1925 } 1926 performSnooze(NetworkTemplate template, int type)1927 void performSnooze(NetworkTemplate template, int type) { 1928 maybeRefreshTrustedTime(); 1929 final long currentTime = currentTimeMillis(); 1930 synchronized (mRulesLock) { 1931 // find and snooze local policy that matches 1932 final NetworkPolicy policy = mNetworkPolicy.get(template); 1933 if (policy == null) { 1934 throw new IllegalArgumentException("unable to find policy for " + template); 1935 } 1936 1937 switch (type) { 1938 case TYPE_WARNING: 1939 policy.lastWarningSnooze = currentTime; 1940 break; 1941 case TYPE_LIMIT: 1942 policy.lastLimitSnooze = currentTime; 1943 break; 1944 default: 1945 throw new IllegalArgumentException("unexpected type"); 1946 } 1947 1948 normalizePoliciesLocked(); 1949 updateNetworkEnabledLocked(); 1950 updateNetworkRulesLocked(); 1951 updateNotificationsLocked(); 1952 writePolicyLocked(); 1953 } 1954 } 1955 1956 @Override onTetheringChanged(String iface, boolean tethering)1957 public void onTetheringChanged(String iface, boolean tethering) { 1958 // No need to enforce permission because setRestrictBackground() will do it. 1959 if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")"); 1960 synchronized (mRulesLock) { 1961 if (mRestrictBackground && tethering) { 1962 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver"); 1963 setRestrictBackground(false); 1964 } 1965 } 1966 } 1967 1968 @Override setRestrictBackground(boolean restrictBackground)1969 public void setRestrictBackground(boolean restrictBackground) { 1970 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1971 final long token = Binder.clearCallingIdentity(); 1972 try { 1973 maybeRefreshTrustedTime(); 1974 synchronized (mRulesLock) { 1975 if (restrictBackground == mRestrictBackground) { 1976 // Ideally, UI should never allow this scenario... 1977 Slog.w(TAG, "setRestrictBackground: already " + restrictBackground); 1978 return; 1979 } 1980 setRestrictBackgroundLocked(restrictBackground); 1981 } 1982 1983 } finally { 1984 Binder.restoreCallingIdentity(token); 1985 } 1986 1987 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 1988 .sendToTarget(); 1989 } 1990 setRestrictBackgroundLocked(boolean restrictBackground)1991 private void setRestrictBackgroundLocked(boolean restrictBackground) { 1992 Slog.d(TAG, "setRestrictBackgroundLocked(): " + restrictBackground); 1993 final boolean oldRestrictBackground = mRestrictBackground; 1994 mRestrictBackground = restrictBackground; 1995 // Must whitelist foreground apps before turning data saver mode on. 1996 // TODO: there is no need to iterate through all apps here, just those in the foreground, 1997 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 1998 updateRulesForRestrictBackgroundLocked(); 1999 try { 2000 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 2001 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 2002 mRestrictBackground = oldRestrictBackground; 2003 // TODO: if it knew the foreground apps (see TODO above), it could call 2004 // updateRulesForRestrictBackgroundLocked() again to restore state. 2005 return; 2006 } 2007 } catch (RemoteException e) { 2008 // ignored; service lives in system_server 2009 } 2010 updateNotificationsLocked(); 2011 writePolicyLocked(); 2012 } 2013 2014 @Override addRestrictBackgroundWhitelistedUid(int uid)2015 public void addRestrictBackgroundWhitelistedUid(int uid) { 2016 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2017 final boolean oldStatus; 2018 final boolean needFirewallRules; 2019 synchronized (mRulesLock) { 2020 oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2021 if (oldStatus) { 2022 if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted"); 2023 return; 2024 } 2025 needFirewallRules = isUidValidForWhitelistRules(uid); 2026 Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist"); 2027 mRestrictBackgroundWhitelistUids.append(uid, true); 2028 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2029 && mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2030 if (LOGD) Slog.d(TAG, "Removing uid " + uid 2031 + " from revoked restrict background whitelist"); 2032 mRestrictBackgroundWhitelistRevokedUids.delete(uid); 2033 } 2034 if (needFirewallRules) { 2035 // Only update firewall rules if necessary... 2036 updateRulesForDataUsageRestrictionsLocked(uid); 2037 } 2038 // ...but always persists the whitelist request. 2039 writePolicyLocked(); 2040 } 2041 int changed = (mRestrictBackground && !oldStatus && needFirewallRules) ? 1 : 0; 2042 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed, 2043 Boolean.TRUE).sendToTarget(); 2044 } 2045 2046 @Override removeRestrictBackgroundWhitelistedUid(int uid)2047 public void removeRestrictBackgroundWhitelistedUid(int uid) { 2048 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2049 final boolean changed; 2050 synchronized (mRulesLock) { 2051 changed = removeRestrictBackgroundWhitelistedUidLocked(uid, false, true); 2052 } 2053 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, changed ? 1 : 0, 2054 Boolean.FALSE).sendToTarget(); 2055 } 2056 2057 /** 2058 * Removes a uid from the restricted background whitelist, returning whether its current 2059 * {@link ConnectivityManager.RestrictBackgroundStatus} changed. 2060 */ removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean uidDeleted, boolean updateNow)2061 private boolean removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean uidDeleted, 2062 boolean updateNow) { 2063 final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid); 2064 if (!oldStatus && !uidDeleted) { 2065 if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before"); 2066 return false; 2067 } 2068 final boolean needFirewallRules = uidDeleted || isUidValidForWhitelistRules(uid); 2069 if (oldStatus) { 2070 Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist"); 2071 mRestrictBackgroundWhitelistUids.delete(uid); 2072 } 2073 if (mDefaultRestrictBackgroundWhitelistUids.get(uid) 2074 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2075 if (LOGD) Slog.d(TAG, "Adding uid " + uid 2076 + " to revoked restrict background whitelist"); 2077 mRestrictBackgroundWhitelistRevokedUids.append(uid, true); 2078 } 2079 if (needFirewallRules) { 2080 // Only update firewall rules if necessary... 2081 updateRulesForDataUsageRestrictionsLocked(uid, uidDeleted); 2082 } 2083 if (updateNow) { 2084 // ...but always persists the whitelist request. 2085 writePolicyLocked(); 2086 } 2087 // Status only changes if Data Saver is turned on (otherwise it is DISABLED, even if the 2088 // app was whitelisted before). 2089 return mRestrictBackground && needFirewallRules; 2090 } 2091 2092 @Override getRestrictBackgroundWhitelistedUids()2093 public int[] getRestrictBackgroundWhitelistedUids() { 2094 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2095 synchronized (mRulesLock) { 2096 final int size = mRestrictBackgroundWhitelistUids.size(); 2097 final int[] whitelist = new int[size]; 2098 for (int i = 0; i < size; i++) { 2099 whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i); 2100 } 2101 if (LOGV) { 2102 Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): " 2103 + mRestrictBackgroundWhitelistUids); 2104 } 2105 return whitelist; 2106 } 2107 } 2108 2109 @Override getRestrictBackgroundByCaller()2110 public int getRestrictBackgroundByCaller() { 2111 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2112 final int uid = Binder.getCallingUid(); 2113 2114 synchronized (mRulesLock) { 2115 // Must clear identity because getUidPolicy() is restricted to system. 2116 final long token = Binder.clearCallingIdentity(); 2117 final int policy; 2118 try { 2119 policy = getUidPolicy(uid); 2120 } finally { 2121 Binder.restoreCallingIdentity(token); 2122 } 2123 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 2124 // App is blacklisted. 2125 return RESTRICT_BACKGROUND_STATUS_ENABLED; 2126 } 2127 if (!mRestrictBackground) { 2128 return RESTRICT_BACKGROUND_STATUS_DISABLED; 2129 } 2130 return mRestrictBackgroundWhitelistUids.get(uid) 2131 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 2132 : RESTRICT_BACKGROUND_STATUS_ENABLED; 2133 } 2134 } 2135 2136 @Override getRestrictBackground()2137 public boolean getRestrictBackground() { 2138 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2139 2140 synchronized (mRulesLock) { 2141 return mRestrictBackground; 2142 } 2143 } 2144 2145 @Override setDeviceIdleMode(boolean enabled)2146 public void setDeviceIdleMode(boolean enabled) { 2147 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2148 2149 synchronized (mRulesLock) { 2150 if (mDeviceIdleMode != enabled) { 2151 mDeviceIdleMode = enabled; 2152 if (mSystemReady) { 2153 // Device idle change means we need to rebuild rules for all 2154 // known apps, so do a global refresh. 2155 updateRulesForGlobalChangeLocked(false); 2156 } 2157 if (enabled) { 2158 EventLogTags.writeDeviceIdleOnPhase("net"); 2159 } else { 2160 EventLogTags.writeDeviceIdleOffPhase("net"); 2161 } 2162 } 2163 } 2164 } 2165 findPolicyForNetworkLocked(NetworkIdentity ident)2166 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 2167 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2168 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2169 if (policy.template.matches(ident)) { 2170 return policy; 2171 } 2172 } 2173 return null; 2174 } 2175 2176 @Override getNetworkQuotaInfo(NetworkState state)2177 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 2178 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2179 2180 // only returns usage summary, so we don't require caller to have 2181 // READ_NETWORK_USAGE_HISTORY. 2182 final long token = Binder.clearCallingIdentity(); 2183 try { 2184 return getNetworkQuotaInfoUnchecked(state); 2185 } finally { 2186 Binder.restoreCallingIdentity(token); 2187 } 2188 } 2189 getNetworkQuotaInfoUnchecked(NetworkState state)2190 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 2191 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2192 2193 final NetworkPolicy policy; 2194 synchronized (mRulesLock) { 2195 policy = findPolicyForNetworkLocked(ident); 2196 } 2197 2198 if (policy == null || !policy.hasCycle()) { 2199 // missing policy means we can't derive useful quota info 2200 return null; 2201 } 2202 2203 final long currentTime = currentTimeMillis(); 2204 2205 // find total bytes used under policy 2206 final long start = computeLastCycleBoundary(currentTime, policy); 2207 final long end = currentTime; 2208 final long totalBytes = getTotalBytes(policy.template, start, end); 2209 2210 // report soft and hard limits under policy 2211 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 2212 : NetworkQuotaInfo.NO_LIMIT; 2213 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 2214 : NetworkQuotaInfo.NO_LIMIT; 2215 2216 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 2217 } 2218 2219 @Override isNetworkMetered(NetworkState state)2220 public boolean isNetworkMetered(NetworkState state) { 2221 if (state.networkInfo == null) { 2222 return false; 2223 } 2224 2225 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2226 2227 // roaming networks are always considered metered 2228 if (ident.getRoaming()) { 2229 return true; 2230 } 2231 2232 final NetworkPolicy policy; 2233 synchronized (mRulesLock) { 2234 policy = findPolicyForNetworkLocked(ident); 2235 } 2236 2237 if (policy != null) { 2238 return policy.metered; 2239 } else { 2240 final int type = state.networkInfo.getType(); 2241 if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 2242 return true; 2243 } 2244 return false; 2245 } 2246 } 2247 2248 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)2249 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2250 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 2251 2252 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 2253 2254 final ArraySet<String> argSet = new ArraySet<String>(args.length); 2255 for (String arg : args) { 2256 argSet.add(arg); 2257 } 2258 2259 synchronized (mRulesLock) { 2260 if (argSet.contains("--unsnooze")) { 2261 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2262 mNetworkPolicy.valueAt(i).clearSnooze(); 2263 } 2264 2265 normalizePoliciesLocked(); 2266 updateNetworkEnabledLocked(); 2267 updateNetworkRulesLocked(); 2268 updateNotificationsLocked(); 2269 writePolicyLocked(); 2270 2271 fout.println("Cleared snooze timestamps"); 2272 return; 2273 } 2274 2275 fout.print("System ready: "); fout.println(mSystemReady); 2276 fout.print("Restrict background: "); fout.println(mRestrictBackground); 2277 fout.print("Restrict power: "); fout.println(mRestrictPower); 2278 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 2279 fout.println("Network policies:"); 2280 fout.increaseIndent(); 2281 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2282 fout.println(mNetworkPolicy.valueAt(i).toString()); 2283 } 2284 fout.decreaseIndent(); 2285 2286 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 2287 2288 fout.println("Policy for UIDs:"); 2289 fout.increaseIndent(); 2290 int size = mUidPolicy.size(); 2291 for (int i = 0; i < size; i++) { 2292 final int uid = mUidPolicy.keyAt(i); 2293 final int policy = mUidPolicy.valueAt(i); 2294 fout.print("UID="); 2295 fout.print(uid); 2296 fout.print(" policy="); 2297 fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy)); 2298 fout.println(); 2299 } 2300 fout.decreaseIndent(); 2301 2302 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2303 if (size > 0) { 2304 fout.println("Power save whitelist (except idle) app ids:"); 2305 fout.increaseIndent(); 2306 for (int i = 0; i < size; i++) { 2307 fout.print("UID="); 2308 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2309 fout.print(": "); 2310 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 2311 fout.println(); 2312 } 2313 fout.decreaseIndent(); 2314 } 2315 2316 size = mPowerSaveWhitelistAppIds.size(); 2317 if (size > 0) { 2318 fout.println("Power save whitelist app ids:"); 2319 fout.increaseIndent(); 2320 for (int i = 0; i < size; i++) { 2321 fout.print("UID="); 2322 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 2323 fout.print(": "); 2324 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 2325 fout.println(); 2326 } 2327 fout.decreaseIndent(); 2328 } 2329 2330 size = mRestrictBackgroundWhitelistUids.size(); 2331 if (size > 0) { 2332 fout.println("Restrict background whitelist uids:"); 2333 fout.increaseIndent(); 2334 for (int i = 0; i < size; i++) { 2335 fout.print("UID="); 2336 fout.print(mRestrictBackgroundWhitelistUids.keyAt(i)); 2337 fout.println(); 2338 } 2339 fout.decreaseIndent(); 2340 } 2341 2342 size = mDefaultRestrictBackgroundWhitelistUids.size(); 2343 if (size > 0) { 2344 fout.println("Default restrict background whitelist uids:"); 2345 fout.increaseIndent(); 2346 for (int i = 0; i < size; i++) { 2347 fout.print("UID="); 2348 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); 2349 fout.println(); 2350 } 2351 fout.decreaseIndent(); 2352 } 2353 2354 size = mRestrictBackgroundWhitelistRevokedUids.size(); 2355 if (size > 0) { 2356 fout.println("Default restrict background whitelist uids revoked by users:"); 2357 fout.increaseIndent(); 2358 for (int i = 0; i < size; i++) { 2359 fout.print("UID="); 2360 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); 2361 fout.println(); 2362 } 2363 fout.decreaseIndent(); 2364 } 2365 2366 final SparseBooleanArray knownUids = new SparseBooleanArray(); 2367 collectKeys(mUidState, knownUids); 2368 collectKeys(mUidRules, knownUids); 2369 2370 fout.println("Status for all known UIDs:"); 2371 fout.increaseIndent(); 2372 size = knownUids.size(); 2373 for (int i = 0; i < size; i++) { 2374 final int uid = knownUids.keyAt(i); 2375 fout.print("UID="); 2376 fout.print(uid); 2377 2378 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2379 fout.print(" state="); 2380 fout.print(state); 2381 if (state <= ActivityManager.PROCESS_STATE_TOP) { 2382 fout.print(" (fg)"); 2383 } else { 2384 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 2385 ? " (fg svc)" : " (bg)"); 2386 } 2387 2388 final int uidRules = mUidRules.get(uid, RULE_NONE); 2389 fout.print(" rules="); 2390 fout.print(uidRulesToString(uidRules)); 2391 fout.println(); 2392 } 2393 fout.decreaseIndent(); 2394 2395 fout.println("Status for just UIDs with rules:"); 2396 fout.increaseIndent(); 2397 size = mUidRules.size(); 2398 for (int i = 0; i < size; i++) { 2399 final int uid = mUidRules.keyAt(i); 2400 fout.print("UID="); 2401 fout.print(uid); 2402 final int uidRules = mUidRules.get(uid, RULE_NONE); 2403 fout.print(" rules="); 2404 fout.print(uidRulesToString(uidRules)); 2405 fout.println(); 2406 } 2407 fout.decreaseIndent(); 2408 } 2409 } 2410 2411 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ResultReceiver resultReceiver)2412 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2413 String[] args, ResultReceiver resultReceiver) throws RemoteException { 2414 (new NetworkPolicyManagerShellCommand(mContext, this)).exec( 2415 this, in, out, err, args, resultReceiver); 2416 } 2417 2418 @Override isUidForeground(int uid)2419 public boolean isUidForeground(int uid) { 2420 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2421 2422 synchronized (mRulesLock) { 2423 return isUidForegroundLocked(uid); 2424 } 2425 } 2426 isUidForegroundLocked(int uid)2427 private boolean isUidForegroundLocked(int uid) { 2428 return isUidStateForegroundLocked( 2429 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2430 } 2431 isUidForegroundOnRestrictBackgroundLocked(int uid)2432 private boolean isUidForegroundOnRestrictBackgroundLocked(int uid) { 2433 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2434 return isProcStateAllowedWhileOnRestrictBackgroundLocked(procState); 2435 } 2436 isUidForegroundOnRestrictPowerLocked(int uid)2437 private boolean isUidForegroundOnRestrictPowerLocked(int uid) { 2438 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2439 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState); 2440 } 2441 isUidStateForegroundLocked(int state)2442 private boolean isUidStateForegroundLocked(int state) { 2443 // only really in foreground when screen is also on 2444 return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP; 2445 } 2446 2447 /** 2448 * Process state of UID changed; if needed, will trigger 2449 * {@link #updateRulesForDataUsageRestrictionsLocked(int)} and 2450 * {@link #updateRulesForPowerRestrictionsLocked(int)} 2451 */ updateUidStateLocked(int uid, int uidState)2452 private void updateUidStateLocked(int uid, int uidState) { 2453 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2454 if (oldUidState != uidState) { 2455 // state changed, push updated rules 2456 mUidState.put(uid, uidState); 2457 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState); 2458 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 2459 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) { 2460 if (isUidIdle(uid)) { 2461 updateRuleForAppIdleLocked(uid); 2462 } 2463 if (mDeviceIdleMode) { 2464 updateRuleForDeviceIdleLocked(uid); 2465 } 2466 if (mRestrictPower) { 2467 updateRuleForRestrictPowerLocked(uid); 2468 } 2469 updateRulesForPowerRestrictionsLocked(uid); 2470 } 2471 updateNetworkStats(uid, isUidStateForegroundLocked(uidState)); 2472 } 2473 } 2474 removeUidStateLocked(int uid)2475 private void removeUidStateLocked(int uid) { 2476 final int index = mUidState.indexOfKey(uid); 2477 if (index >= 0) { 2478 final int oldUidState = mUidState.valueAt(index); 2479 mUidState.removeAt(index); 2480 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2481 updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, 2482 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2483 if (mDeviceIdleMode) { 2484 updateRuleForDeviceIdleLocked(uid); 2485 } 2486 if (mRestrictPower) { 2487 updateRuleForRestrictPowerLocked(uid); 2488 } 2489 updateRulesForPowerRestrictionsLocked(uid); 2490 updateNetworkStats(uid, false); 2491 } 2492 } 2493 } 2494 2495 // adjust stats accounting based on foreground status updateNetworkStats(int uid, boolean uidForeground)2496 private void updateNetworkStats(int uid, boolean uidForeground) { 2497 try { 2498 mNetworkStats.setUidForeground(uid, uidForeground); 2499 } catch (RemoteException e) { 2500 // ignored; service lives in system_server 2501 } 2502 } 2503 updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState, int newUidState)2504 private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState, 2505 int newUidState) { 2506 final boolean oldForeground = 2507 isProcStateAllowedWhileOnRestrictBackgroundLocked(oldUidState); 2508 final boolean newForeground = 2509 isProcStateAllowedWhileOnRestrictBackgroundLocked(newUidState); 2510 if (oldForeground != newForeground) { 2511 updateRulesForDataUsageRestrictionsLocked(uid); 2512 } 2513 } 2514 updateScreenOn()2515 private void updateScreenOn() { 2516 synchronized (mRulesLock) { 2517 try { 2518 mScreenOn = mPowerManager.isInteractive(); 2519 } catch (RemoteException e) { 2520 // ignored; service lives in system_server 2521 } 2522 updateRulesForScreenLocked(); 2523 } 2524 } 2525 2526 /** 2527 * Update rules that might be changed by {@link #mScreenOn} value. 2528 */ updateRulesForScreenLocked()2529 private void updateRulesForScreenLocked() { 2530 // only update rules for anyone with foreground activities 2531 final int size = mUidState.size(); 2532 for (int i = 0; i < size; i++) { 2533 if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 2534 final int uid = mUidState.keyAt(i); 2535 updateRestrictionRulesForUidLocked(uid); 2536 } 2537 } 2538 } 2539 isProcStateAllowedWhileIdleOrPowerSaveMode(int procState)2540 static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) { 2541 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2542 } 2543 isProcStateAllowedWhileOnRestrictBackgroundLocked(int procState)2544 static boolean isProcStateAllowedWhileOnRestrictBackgroundLocked(int procState) { 2545 return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2546 } 2547 updateRulesForRestrictPowerLocked()2548 void updateRulesForRestrictPowerLocked() { 2549 updateRulesForWhitelistedPowerSaveLocked(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 2550 mUidFirewallPowerSaveRules); 2551 } 2552 updateRuleForRestrictPowerLocked(int uid)2553 void updateRuleForRestrictPowerLocked(int uid) { 2554 updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2555 } 2556 updateRulesForDeviceIdleLocked()2557 void updateRulesForDeviceIdleLocked() { 2558 updateRulesForWhitelistedPowerSaveLocked(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 2559 mUidFirewallDozableRules); 2560 } 2561 updateRuleForDeviceIdleLocked(int uid)2562 void updateRuleForDeviceIdleLocked(int uid) { 2563 updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 2564 } 2565 2566 // NOTE: since both fw_dozable and fw_powersave uses the same map 2567 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain, SparseIntArray rules)2568 private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain, 2569 SparseIntArray rules) { 2570 if (enabled) { 2571 // Sync the whitelists before enabling the chain. We don't care about the rules if 2572 // we are disabling the chain. 2573 final SparseIntArray uidRules = rules; 2574 uidRules.clear(); 2575 final List<UserInfo> users = mUserManager.getUsers(); 2576 for (int ui = users.size() - 1; ui >= 0; ui--) { 2577 UserInfo user = users.get(ui); 2578 for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { 2579 if (mPowerSaveTempWhitelistAppIds.valueAt(i)) { 2580 int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); 2581 int uid = UserHandle.getUid(user.id, appId); 2582 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2583 } 2584 } 2585 for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { 2586 int appId = mPowerSaveWhitelistAppIds.keyAt(i); 2587 int uid = UserHandle.getUid(user.id, appId); 2588 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2589 } 2590 } 2591 for (int i = mUidState.size() - 1; i >= 0; i--) { 2592 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 2593 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2594 } 2595 } 2596 setUidFirewallRules(chain, uidRules); 2597 } 2598 2599 enableFirewallChainLocked(chain, enabled); 2600 } 2601 updateRulesForNonMeteredNetworksLocked()2602 private void updateRulesForNonMeteredNetworksLocked() { 2603 2604 } 2605 isWhitelistedBatterySaverLocked(int uid)2606 private boolean isWhitelistedBatterySaverLocked(int uid) { 2607 final int appId = UserHandle.getAppId(uid); 2608 return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); 2609 } 2610 2611 // NOTE: since both fw_dozable and fw_powersave uses the same map 2612 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain)2613 private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) { 2614 if (enabled) { 2615 if (isWhitelistedBatterySaverLocked(uid) 2616 || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) { 2617 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 2618 } else { 2619 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 2620 } 2621 } 2622 } 2623 updateRulesForAppIdleLocked()2624 void updateRulesForAppIdleLocked() { 2625 final SparseIntArray uidRules = mUidFirewallStandbyRules; 2626 uidRules.clear(); 2627 2628 // Fully update the app idle firewall chain. 2629 final List<UserInfo> users = mUserManager.getUsers(); 2630 for (int ui = users.size() - 1; ui >= 0; ui--) { 2631 UserInfo user = users.get(ui); 2632 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2633 for (int uid : idleUids) { 2634 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2635 // quick check: if this uid doesn't have INTERNET permission, it 2636 // doesn't have network access anyway, so it is a waste to mess 2637 // with it here. 2638 if (hasInternetPermissions(uid)) { 2639 uidRules.put(uid, FIREWALL_RULE_DENY); 2640 } 2641 } 2642 } 2643 } 2644 2645 setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); 2646 } 2647 updateRuleForAppIdleLocked(int uid)2648 void updateRuleForAppIdleLocked(int uid) { 2649 if (!isUidValidForBlacklistRules(uid)) return; 2650 2651 int appId = UserHandle.getAppId(uid); 2652 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) 2653 && !isUidForegroundOnRestrictPowerLocked(uid)) { 2654 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2655 } else { 2656 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2657 } 2658 } 2659 updateRulesForAppIdleParoleLocked()2660 void updateRulesForAppIdleParoleLocked() { 2661 boolean enableChain = !mUsageStats.isAppIdleParoleOn(); 2662 enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); 2663 } 2664 2665 /** 2666 * Update rules that might be changed by {@link #mRestrictBackground}, 2667 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 2668 */ updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged)2669 private void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) { 2670 long start; 2671 if (LOGD) start = System.currentTimeMillis(); 2672 2673 updateRulesForDeviceIdleLocked(); 2674 updateRulesForAppIdleLocked(); 2675 updateRulesForRestrictPowerLocked(); 2676 updateRulesForRestrictBackgroundLocked(); 2677 setRestrictBackgroundLocked(mRestrictBackground); 2678 2679 // If the set of restricted networks may have changed, re-evaluate those. 2680 if (restrictedNetworksChanged) { 2681 normalizePoliciesLocked(); 2682 updateNetworkRulesLocked(); 2683 } 2684 if (LOGD) { 2685 final long delta = System.currentTimeMillis() - start; 2686 Slog.d(TAG, "updateRulesForGlobalChangeLocked(" + restrictedNetworksChanged + ") took " 2687 + delta + "ms"); 2688 } 2689 } 2690 updateRulesForRestrictBackgroundLocked()2691 private void updateRulesForRestrictBackgroundLocked() { 2692 final PackageManager pm = mContext.getPackageManager(); 2693 2694 // update rules for all installed applications 2695 final List<UserInfo> users = mUserManager.getUsers(); 2696 final List<ApplicationInfo> apps = pm.getInstalledApplications( 2697 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS 2698 | PackageManager.MATCH_DIRECT_BOOT_AWARE 2699 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2700 2701 final int usersSize = users.size(); 2702 final int appsSize = apps.size(); 2703 for (int i = 0; i < usersSize; i++) { 2704 final UserInfo user = users.get(i); 2705 for (int j = 0; j < appsSize; j++) { 2706 final ApplicationInfo app = apps.get(j); 2707 final int uid = UserHandle.getUid(user.id, app.uid); 2708 updateRulesForDataUsageRestrictionsLocked(uid); 2709 updateRulesForPowerRestrictionsLocked(uid); 2710 } 2711 } 2712 } 2713 updateRulesForTempWhitelistChangeLocked()2714 private void updateRulesForTempWhitelistChangeLocked() { 2715 final List<UserInfo> users = mUserManager.getUsers(); 2716 for (int i = 0; i < users.size(); i++) { 2717 final UserInfo user = users.get(i); 2718 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { 2719 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); 2720 int uid = UserHandle.getUid(user.id, appId); 2721 // Update external firewall rules. 2722 updateRuleForAppIdleLocked(uid); 2723 updateRuleForDeviceIdleLocked(uid); 2724 updateRuleForRestrictPowerLocked(uid); 2725 // Update internal rules. 2726 updateRulesForPowerRestrictionsLocked(uid); 2727 } 2728 } 2729 } 2730 2731 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 2732 // methods below could be merged into a isUidValidForRules() method. isUidValidForBlacklistRules(int uid)2733 private boolean isUidValidForBlacklistRules(int uid) { 2734 // allow rules on specific system services, and any apps 2735 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 2736 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) { 2737 return true; 2738 } 2739 2740 return false; 2741 } 2742 isUidValidForWhitelistRules(int uid)2743 private boolean isUidValidForWhitelistRules(int uid) { 2744 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 2745 } 2746 isUidIdle(int uid)2747 private boolean isUidIdle(int uid) { 2748 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 2749 final int userId = UserHandle.getUserId(uid); 2750 2751 if (!ArrayUtils.isEmpty(packages)) { 2752 for (String packageName : packages) { 2753 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 2754 return false; 2755 } 2756 } 2757 } 2758 return true; 2759 } 2760 2761 /** 2762 * Checks if an uid has INTERNET permissions. 2763 * <p> 2764 * Useful for the cases where the lack of network access can simplify the rules. 2765 */ hasInternetPermissions(int uid)2766 private boolean hasInternetPermissions(int uid) { 2767 try { 2768 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) 2769 != PackageManager.PERMISSION_GRANTED) { 2770 return false; 2771 } 2772 } catch (RemoteException e) { 2773 } 2774 return true; 2775 } 2776 2777 /** 2778 * Applies network rules to bandwidth and firewall controllers based on uid policy. 2779 * 2780 * <p>There are currently 4 types of restriction rules: 2781 * <ul> 2782 * <li>Doze mode 2783 * <li>App idle mode 2784 * <li>Battery Saver Mode (also referred as power save). 2785 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data'). 2786 * </ul> 2787 * 2788 * <p>This method changes both the external firewall rules and the internal state. 2789 */ updateRestrictionRulesForUidLocked(int uid)2790 private void updateRestrictionRulesForUidLocked(int uid) { 2791 // Methods below only changes the firewall rules for the power-related modes. 2792 updateRuleForDeviceIdleLocked(uid); 2793 updateRuleForAppIdleLocked(uid); 2794 updateRuleForRestrictPowerLocked(uid); 2795 2796 // Update internal state for power-related modes. 2797 updateRulesForPowerRestrictionsLocked(uid); 2798 2799 // Update firewall and internal rules for Data Saver Mode. 2800 updateRulesForDataUsageRestrictionsLocked(uid); 2801 } 2802 2803 /** 2804 * Applies network rules to bandwidth controllers based on process state and user-defined 2805 * restrictions (blacklist / whitelist). 2806 * 2807 * <p> 2808 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 2809 * networks: 2810 * <ul> 2811 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). 2812 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're 2813 * also blacklisted. 2814 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 2815 * no UIDs other those whitelisted will have access. 2816 * <ul> 2817 * 2818 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 2819 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / 2820 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist 2821 * respectively): these methods set the proper internal state (blacklist / whitelist), then call 2822 * this ({@link #updateRulesForDataUsageRestrictionsLocked(int)}) to propagate the rules to 2823 * {@link INetworkManagementService}, but this method should also be called in events (like 2824 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 2825 * following rules should also be applied: 2826 * 2827 * <ul> 2828 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 2829 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 2830 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from 2831 * {@code bw_penalty_box}. 2832 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 2833 * </ul> 2834 * 2835 * <p>For optimization, the rules are only applied on user apps that have internet access 2836 * permission, since there is no need to change the {@code iptables} rule if the app does not 2837 * have permission to use the internet. 2838 * 2839 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID. 2840 * 2841 */ updateRulesForDataUsageRestrictionsLocked(int uid)2842 private void updateRulesForDataUsageRestrictionsLocked(int uid) { 2843 updateRulesForDataUsageRestrictionsLocked(uid, false); 2844 } 2845 2846 /** 2847 * Overloaded version of {@link #updateRulesForDataUsageRestrictionsLocked(int)} called when an 2848 * app is removed - it ignores the UID validity check. 2849 */ updateRulesForDataUsageRestrictionsLocked(int uid, boolean uidDeleted)2850 private void updateRulesForDataUsageRestrictionsLocked(int uid, boolean uidDeleted) { 2851 if (!uidDeleted && !isUidValidForWhitelistRules(uid)) { 2852 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 2853 return; 2854 } 2855 2856 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2857 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2858 final boolean isForeground = isUidForegroundOnRestrictBackgroundLocked(uid); 2859 2860 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 2861 final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid); 2862 final int oldRule = oldUidRules & MASK_METERED_NETWORKS; 2863 int newRule = RULE_NONE; 2864 2865 // First step: define the new rule based on user restrictions and foreground state. 2866 if (isForeground) { 2867 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { 2868 newRule = RULE_TEMPORARY_ALLOW_METERED; 2869 } else if (isWhitelisted) { 2870 newRule = RULE_ALLOW_METERED; 2871 } 2872 } else { 2873 if (isBlacklisted) { 2874 newRule = RULE_REJECT_METERED; 2875 } else if (mRestrictBackground && isWhitelisted) { 2876 newRule = RULE_ALLOW_METERED; 2877 } 2878 } 2879 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS); 2880 2881 if (LOGV) { 2882 Log.v(TAG, "updateRuleForRestrictBackgroundLocked(" + uid + ")" 2883 + ": isForeground=" +isForeground 2884 + ", isBlacklisted=" + isBlacklisted 2885 + ", isWhitelisted=" + isWhitelisted 2886 + ", oldRule=" + uidRulesToString(oldRule) 2887 + ", newRule=" + uidRulesToString(newRule) 2888 + ", newUidRules=" + uidRulesToString(newUidRules) 2889 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 2890 } 2891 2892 if (newUidRules == RULE_NONE) { 2893 mUidRules.delete(uid); 2894 } else { 2895 mUidRules.put(uid, newUidRules); 2896 } 2897 2898 boolean changed = false; 2899 2900 // Second step: apply bw changes based on change of state. 2901 if (newRule != oldRule) { 2902 changed = true; 2903 2904 if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2905 // Temporarily whitelist foreground app, removing from blacklist if necessary 2906 // (since bw_penalty_box prevails over bw_happy_box). 2907 2908 setMeteredNetworkWhitelist(uid, true); 2909 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, 2910 // but ideally it should be just: 2911 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2912 if (isBlacklisted) { 2913 setMeteredNetworkBlacklist(uid, false); 2914 } 2915 } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 2916 // Remove temporary whitelist from app that is not on foreground anymore. 2917 2918 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, 2919 // but ideally they should be just: 2920 // setMeteredNetworkWhitelist(uid, isWhitelisted); 2921 // setMeteredNetworkBlacklist(uid, isBlacklisted); 2922 if (!isWhitelisted) { 2923 setMeteredNetworkWhitelist(uid, false); 2924 } 2925 if (isBlacklisted) { 2926 setMeteredNetworkBlacklist(uid, true); 2927 } 2928 } else if ((newRule & RULE_REJECT_METERED) != 0 2929 || (oldRule & RULE_REJECT_METERED) != 0) { 2930 // Flip state because app was explicitly added or removed to blacklist. 2931 setMeteredNetworkBlacklist(uid, isBlacklisted); 2932 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) { 2933 // Since blacklist prevails over whitelist, we need to handle the special case 2934 // where app is whitelisted and blacklisted at the same time (although such 2935 // scenario should be blocked by the UI), then blacklist is removed. 2936 setMeteredNetworkWhitelist(uid, isWhitelisted); 2937 } 2938 } else if ((newRule & RULE_ALLOW_METERED) != 0 2939 || (oldRule & RULE_ALLOW_METERED) != 0) { 2940 // Flip state because app was explicitly added or removed to whitelist. 2941 setMeteredNetworkWhitelist(uid, isWhitelisted); 2942 } else { 2943 // All scenarios should have been covered above. 2944 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid 2945 + ": foreground=" + isForeground 2946 + ", whitelisted=" + isWhitelisted 2947 + ", blacklisted=" + isBlacklisted 2948 + ", newRule=" + uidRulesToString(newUidRules) 2949 + ", oldRule=" + uidRulesToString(oldUidRules)); 2950 } 2951 2952 // Dispatch changed rule to existing listeners. 2953 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 2954 } 2955 } 2956 2957 /** 2958 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external 2959 * listeners in case of change. 2960 * <p> 2961 * There are 3 power-related rules that affects whether an app has background access on 2962 * non-metered networks, and when the condition applies and the UID is not whitelisted for power 2963 * restriction, it's added to the equivalent firewall chain: 2964 * <ul> 2965 * <li>App is idle: {@code fw_standby} firewall chain. 2966 * <li>Device is idle: {@code fw_dozable} firewall chain. 2967 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain. 2968 * </ul> 2969 * <p> 2970 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on 2971 * these modes, the UID process state (foreground or not), and the UIDwhitelist state. 2972 * <p> 2973 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}. 2974 */ updateRulesForPowerRestrictionsLocked(int uid)2975 private void updateRulesForPowerRestrictionsLocked(int uid) { 2976 if (!isUidValidForBlacklistRules(uid)) { 2977 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); 2978 return; 2979 } 2980 2981 final boolean isIdle = isUidIdle(uid); 2982 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; 2983 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 2984 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 2985 final boolean isForeground = isUidForegroundOnRestrictPowerLocked(uid); 2986 2987 final boolean isWhitelisted = isWhitelistedBatterySaverLocked(uid); 2988 final int oldRule = oldUidRules & MASK_ALL_NETWORKS; 2989 int newRule = RULE_NONE; 2990 2991 // First step: define the new rule based on user restrictions and foreground state. 2992 2993 // NOTE: if statements below could be inlined, but it's easier to understand the logic 2994 // by considering the foreground and non-foreground states. 2995 if (isForeground) { 2996 if (restrictMode) { 2997 newRule = RULE_ALLOW_ALL; 2998 } 2999 } else if (restrictMode) { 3000 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL; 3001 } 3002 3003 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule; 3004 3005 if (LOGV) { 3006 Log.v(TAG, "updateRulesForNonMeteredNetworksLocked(" + uid + ")" 3007 + ", isIdle: " + isIdle 3008 + ", mRestrictPower: " + mRestrictPower 3009 + ", mDeviceIdleMode: " + mDeviceIdleMode 3010 + ", isForeground=" + isForeground 3011 + ", isWhitelisted=" + isWhitelisted 3012 + ", oldRule=" + uidRulesToString(oldRule) 3013 + ", newRule=" + uidRulesToString(newRule) 3014 + ", newUidRules=" + uidRulesToString(newUidRules) 3015 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 3016 } 3017 3018 if (newUidRules == RULE_NONE) { 3019 mUidRules.delete(uid); 3020 } else { 3021 mUidRules.put(uid, newUidRules); 3022 } 3023 3024 // Second step: notify listeners if state changed. 3025 if (newRule != oldRule) { 3026 if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) { 3027 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid); 3028 } else if ((newRule & RULE_REJECT_ALL) != 0) { 3029 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid); 3030 } else { 3031 // All scenarios should have been covered above 3032 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid 3033 + ": foreground=" + isForeground 3034 + ", whitelisted=" + isWhitelisted 3035 + ", newRule=" + uidRulesToString(newUidRules) 3036 + ", oldRule=" + uidRulesToString(oldUidRules)); 3037 } 3038 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 3039 } 3040 } 3041 3042 private class AppIdleStateChangeListener 3043 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 3044 3045 @Override onAppIdleStateChanged(String packageName, int userId, boolean idle)3046 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 3047 try { 3048 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 3049 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 3050 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle); 3051 synchronized (mRulesLock) { 3052 updateRuleForAppIdleLocked(uid); 3053 updateRulesForPowerRestrictionsLocked(uid); 3054 } 3055 } catch (NameNotFoundException nnfe) { 3056 } 3057 } 3058 3059 @Override onParoleStateChanged(boolean isParoleOn)3060 public void onParoleStateChanged(boolean isParoleOn) { 3061 synchronized (mRulesLock) { 3062 updateRulesForAppIdleParoleLocked(); 3063 } 3064 } 3065 } 3066 dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules)3067 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { 3068 if (listener != null) { 3069 try { 3070 listener.onUidRulesChanged(uid, uidRules); 3071 } catch (RemoteException ignored) { 3072 } 3073 } 3074 } 3075 dispatchMeteredIfacesChanged(INetworkPolicyListener listener, String[] meteredIfaces)3076 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, 3077 String[] meteredIfaces) { 3078 if (listener != null) { 3079 try { 3080 listener.onMeteredIfacesChanged(meteredIfaces); 3081 } catch (RemoteException ignored) { 3082 } 3083 } 3084 } 3085 dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, boolean restrictBackground)3086 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, 3087 boolean restrictBackground) { 3088 if (listener != null) { 3089 try { 3090 listener.onRestrictBackgroundChanged(restrictBackground); 3091 } catch (RemoteException ignored) { 3092 } 3093 } 3094 } 3095 dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener, int uid, boolean whitelisted)3096 private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener, 3097 int uid, boolean whitelisted) { 3098 if (listener != null) { 3099 try { 3100 listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted); 3101 } catch (RemoteException ignored) { 3102 } 3103 } 3104 } 3105 dispatchRestrictBackgroundBlacklistChanged(INetworkPolicyListener listener, int uid, boolean blacklisted)3106 private void dispatchRestrictBackgroundBlacklistChanged(INetworkPolicyListener listener, 3107 int uid, boolean blacklisted) { 3108 if (listener != null) { 3109 try { 3110 listener.onRestrictBackgroundBlacklistChanged(uid, blacklisted); 3111 } catch (RemoteException ignored) { 3112 } 3113 } 3114 } 3115 3116 private Handler.Callback mHandlerCallback = new Handler.Callback() { 3117 @Override 3118 public boolean handleMessage(Message msg) { 3119 switch (msg.what) { 3120 case MSG_RULES_CHANGED: { 3121 final int uid = msg.arg1; 3122 final int uidRules = msg.arg2; 3123 dispatchUidRulesChanged(mConnectivityListener, uid, uidRules); 3124 final int length = mListeners.beginBroadcast(); 3125 for (int i = 0; i < length; i++) { 3126 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3127 dispatchUidRulesChanged(listener, uid, uidRules); 3128 } 3129 mListeners.finishBroadcast(); 3130 return true; 3131 } 3132 case MSG_METERED_IFACES_CHANGED: { 3133 final String[] meteredIfaces = (String[]) msg.obj; 3134 dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces); 3135 final int length = mListeners.beginBroadcast(); 3136 for (int i = 0; i < length; i++) { 3137 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3138 dispatchMeteredIfacesChanged(listener, meteredIfaces); 3139 } 3140 mListeners.finishBroadcast(); 3141 return true; 3142 } 3143 case MSG_LIMIT_REACHED: { 3144 final String iface = (String) msg.obj; 3145 3146 maybeRefreshTrustedTime(); 3147 synchronized (mRulesLock) { 3148 if (mMeteredIfaces.contains(iface)) { 3149 try { 3150 // force stats update to make sure we have 3151 // numbers that caused alert to trigger. 3152 mNetworkStats.forceUpdate(); 3153 } catch (RemoteException e) { 3154 // ignored; service lives in system_server 3155 } 3156 3157 updateNetworkEnabledLocked(); 3158 updateNotificationsLocked(); 3159 } 3160 } 3161 return true; 3162 } 3163 case MSG_RESTRICT_BACKGROUND_CHANGED: { 3164 final boolean restrictBackground = msg.arg1 != 0; 3165 dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground); 3166 final int length = mListeners.beginBroadcast(); 3167 for (int i = 0; i < length; i++) { 3168 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3169 dispatchRestrictBackgroundChanged(listener, restrictBackground); 3170 } 3171 mListeners.finishBroadcast(); 3172 final Intent intent = 3173 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3174 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3175 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3176 return true; 3177 } 3178 case MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED: { 3179 // MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED can be called in 2 occasions: 3180 // - when an app is whitelisted 3181 // - when an app is blacklisted 3182 // 3183 // Whether the internal listeners (INetworkPolicyListener implementations) or 3184 // app broadcast receivers are notified depend on the following rules: 3185 // 3186 // - App receivers are only notified when the app status changed (msg.arg2 = 1) 3187 // - Listeners are only notified when app was whitelisted (msg.obj is not null), 3188 // since blacklist notifications are handled through MSG_RULES_CHANGED). 3189 final int uid = msg.arg1; 3190 final boolean changed = msg.arg2 == 1; 3191 final Boolean whitelisted = (Boolean) msg.obj; 3192 3193 // First notify internal listeners... 3194 if (whitelisted != null) { 3195 final boolean whitelistedBool = whitelisted.booleanValue(); 3196 dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid, 3197 whitelistedBool); 3198 final int length = mListeners.beginBroadcast(); 3199 for (int i = 0; i < length; i++) { 3200 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3201 dispatchRestrictBackgroundWhitelistChanged(listener, uid, 3202 whitelistedBool); 3203 } 3204 mListeners.finishBroadcast(); 3205 } 3206 final PackageManager pm = mContext.getPackageManager(); 3207 final String[] packages = pm.getPackagesForUid(uid); 3208 if (changed && packages != null) { 3209 // ...then notify apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 3210 final int userId = UserHandle.getUserId(uid); 3211 for (String packageName : packages) { 3212 final Intent intent = new Intent( 3213 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3214 intent.setPackage(packageName); 3215 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3216 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 3217 } 3218 } 3219 return true; 3220 } 3221 case MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED: { 3222 final int uid = msg.arg1; 3223 final boolean blacklisted = msg.arg2 == 1; 3224 3225 dispatchRestrictBackgroundBlacklistChanged(mConnectivityListener, uid, 3226 blacklisted); 3227 final int length = mListeners.beginBroadcast(); 3228 for (int i = 0; i < length; i++) { 3229 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3230 dispatchRestrictBackgroundBlacklistChanged(listener, uid, 3231 blacklisted); 3232 } 3233 mListeners.finishBroadcast(); 3234 return true; 3235 } 3236 case MSG_ADVISE_PERSIST_THRESHOLD: { 3237 final long lowestRule = (Long) msg.obj; 3238 try { 3239 // make sure stats are recorded frequently enough; we aim 3240 // for 2MB threshold for 2GB/month rules. 3241 final long persistThreshold = lowestRule / 1000; 3242 mNetworkStats.advisePersistThreshold(persistThreshold); 3243 } catch (RemoteException e) { 3244 // ignored; service lives in system_server 3245 } 3246 return true; 3247 } 3248 case MSG_SCREEN_ON_CHANGED: { 3249 updateScreenOn(); 3250 return true; 3251 } 3252 case MSG_UPDATE_INTERFACE_QUOTA: { 3253 removeInterfaceQuota((String) msg.obj); 3254 // int params need to be stitched back into a long 3255 setInterfaceQuota((String) msg.obj, 3256 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); 3257 return true; 3258 } 3259 case MSG_REMOVE_INTERFACE_QUOTA: { 3260 removeInterfaceQuota((String) msg.obj); 3261 return true; 3262 } 3263 default: { 3264 return false; 3265 } 3266 } 3267 } 3268 }; 3269 setInterfaceQuota(String iface, long quotaBytes)3270 private void setInterfaceQuota(String iface, long quotaBytes) { 3271 try { 3272 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 3273 } catch (IllegalStateException e) { 3274 Log.wtf(TAG, "problem setting interface quota", e); 3275 } catch (RemoteException e) { 3276 // ignored; service lives in system_server 3277 } 3278 } 3279 removeInterfaceQuota(String iface)3280 private void removeInterfaceQuota(String iface) { 3281 try { 3282 mNetworkManager.removeInterfaceQuota(iface); 3283 } catch (IllegalStateException e) { 3284 Log.wtf(TAG, "problem removing interface quota", e); 3285 } catch (RemoteException e) { 3286 // ignored; service lives in system_server 3287 } 3288 } 3289 setMeteredNetworkBlacklist(int uid, boolean enable)3290 private void setMeteredNetworkBlacklist(int uid, boolean enable) { 3291 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); 3292 try { 3293 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); 3294 } catch (IllegalStateException e) { 3295 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); 3296 } catch (RemoteException e) { 3297 // ignored; service lives in system_server 3298 } 3299 } 3300 setMeteredNetworkWhitelist(int uid, boolean enable)3301 private void setMeteredNetworkWhitelist(int uid, boolean enable) { 3302 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); 3303 try { 3304 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); 3305 } catch (IllegalStateException e) { 3306 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); 3307 } catch (RemoteException e) { 3308 // ignored; service lives in system_server 3309 } 3310 } 3311 3312 /** 3313 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 3314 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 3315 * specified here. 3316 */ setUidFirewallRules(int chain, SparseIntArray uidRules)3317 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 3318 try { 3319 int size = uidRules.size(); 3320 int[] uids = new int[size]; 3321 int[] rules = new int[size]; 3322 for(int index = size - 1; index >= 0; --index) { 3323 uids[index] = uidRules.keyAt(index); 3324 rules[index] = uidRules.valueAt(index); 3325 } 3326 mNetworkManager.setFirewallUidRules(chain, uids, rules); 3327 } catch (IllegalStateException e) { 3328 Log.wtf(TAG, "problem setting firewall uid rules", e); 3329 } catch (RemoteException e) { 3330 // ignored; service lives in system_server 3331 } 3332 } 3333 3334 /** 3335 * Add or remove a uid to the firewall blacklist for all network ifaces. 3336 */ setUidFirewallRule(int chain, int uid, int rule)3337 private void setUidFirewallRule(int chain, int uid, int rule) { 3338 if (chain == FIREWALL_CHAIN_DOZABLE) { 3339 mUidFirewallDozableRules.put(uid, rule); 3340 } else if (chain == FIREWALL_CHAIN_STANDBY) { 3341 mUidFirewallStandbyRules.put(uid, rule); 3342 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 3343 mUidFirewallPowerSaveRules.put(uid, rule); 3344 } 3345 3346 try { 3347 mNetworkManager.setFirewallUidRule(chain, uid, rule); 3348 } catch (IllegalStateException e) { 3349 Log.wtf(TAG, "problem setting firewall uid rules", e); 3350 } catch (RemoteException e) { 3351 // ignored; service lives in system_server 3352 } 3353 } 3354 3355 /** 3356 * Add or remove a uid to the firewall blacklist for all network ifaces. 3357 */ enableFirewallChainLocked(int chain, boolean enable)3358 private void enableFirewallChainLocked(int chain, boolean enable) { 3359 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 3360 mFirewallChainStates.get(chain) == enable) { 3361 // All is the same, nothing to do. 3362 return; 3363 } 3364 mFirewallChainStates.put(chain, enable); 3365 try { 3366 mNetworkManager.setFirewallChainEnabled(chain, enable); 3367 } catch (IllegalStateException e) { 3368 Log.wtf(TAG, "problem enable firewall chain", e); 3369 } catch (RemoteException e) { 3370 // ignored; service lives in system_server 3371 } 3372 } 3373 getTotalBytes(NetworkTemplate template, long start, long end)3374 private long getTotalBytes(NetworkTemplate template, long start, long end) { 3375 try { 3376 return mNetworkStats.getNetworkTotalBytes(template, start, end); 3377 } catch (RuntimeException e) { 3378 Slog.w(TAG, "problem reading network stats: " + e); 3379 return 0; 3380 } catch (RemoteException e) { 3381 // ignored; service lives in system_server 3382 return 0; 3383 } 3384 } 3385 isBandwidthControlEnabled()3386 private boolean isBandwidthControlEnabled() { 3387 final long token = Binder.clearCallingIdentity(); 3388 try { 3389 return mNetworkManager.isBandwidthControlEnabled(); 3390 } catch (RemoteException e) { 3391 // ignored; service lives in system_server 3392 return false; 3393 } finally { 3394 Binder.restoreCallingIdentity(token); 3395 } 3396 } 3397 3398 /** 3399 * Try refreshing {@link #mTime} when stale. 3400 */ maybeRefreshTrustedTime()3401 void maybeRefreshTrustedTime() { 3402 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3403 mTime.forceRefresh(); 3404 } 3405 } 3406 currentTimeMillis()3407 private long currentTimeMillis() { 3408 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3409 } 3410 buildAllowBackgroundDataIntent()3411 private static Intent buildAllowBackgroundDataIntent() { 3412 return new Intent(ACTION_ALLOW_BACKGROUND); 3413 } 3414 buildSnoozeWarningIntent(NetworkTemplate template)3415 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 3416 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 3417 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3418 return intent; 3419 } 3420 buildNetworkOverLimitIntent(NetworkTemplate template)3421 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 3422 final Intent intent = new Intent(); 3423 intent.setComponent(new ComponentName( 3424 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 3425 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3426 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3427 return intent; 3428 } 3429 buildViewDataUsageIntent(NetworkTemplate template)3430 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 3431 final Intent intent = new Intent(); 3432 intent.setComponent(new ComponentName( 3433 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 3434 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3435 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3436 return intent; 3437 } 3438 3439 @VisibleForTesting addIdleHandler(IdleHandler handler)3440 public void addIdleHandler(IdleHandler handler) { 3441 mHandler.getLooper().getQueue().addIdleHandler(handler); 3442 } 3443 collectKeys(SparseIntArray source, SparseBooleanArray target)3444 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 3445 final int size = source.size(); 3446 for (int i = 0; i < size; i++) { 3447 target.put(source.keyAt(i), true); 3448 } 3449 } 3450 3451 @Override factoryReset(String subscriber)3452 public void factoryReset(String subscriber) { 3453 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 3454 3455 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3456 return; 3457 } 3458 3459 // Turn mobile data limit off 3460 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 3461 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 3462 for (NetworkPolicy policy : policies) { 3463 if (policy.template.equals(template)) { 3464 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 3465 policy.inferred = false; 3466 policy.clearSnooze(); 3467 } 3468 } 3469 setNetworkPolicies(policies); 3470 3471 // Turn restrict background data off 3472 setRestrictBackground(false); 3473 3474 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 3475 // Remove app's "restrict background data" flag 3476 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 3477 setUidPolicy(uid, POLICY_NONE); 3478 } 3479 } 3480 } 3481 3482 private class MyPackageMonitor extends PackageMonitor { 3483 3484 @Override onPackageRemoved(String packageName, int uid)3485 public void onPackageRemoved(String packageName, int uid) { 3486 if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid); 3487 synchronized (mRulesLock) { 3488 removeRestrictBackgroundWhitelistedUidLocked(uid, true, true); 3489 updateRestrictionRulesForUidLocked(uid); 3490 } 3491 } 3492 } 3493 3494 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal { 3495 3496 @Override resetUserState(int userId)3497 public void resetUserState(int userId) { 3498 synchronized (mRulesLock) { 3499 boolean changed = removeUserStateLocked(userId, false); 3500 changed = addDefaultRestrictBackgroundWhitelistUidsLocked(userId) || changed; 3501 if (changed) { 3502 writePolicyLocked(); 3503 } 3504 } 3505 } 3506 } 3507 } 3508