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