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