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.CONNECTIVITY_USE_RESTRICTED_NETWORKS; 22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY; 23 import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS; 24 import static android.Manifest.permission.NETWORK_SETTINGS; 25 import static android.Manifest.permission.NETWORK_STACK; 26 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; 27 import static android.Manifest.permission.READ_PHONE_STATE; 28 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 29 import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; 30 import static android.app.ActivityManager.isProcStateConsideredInteraction; 31 import static android.app.ActivityManager.procStateToString; 32 import static android.app.PendingIntent.FLAG_IMMUTABLE; 33 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; 34 import static android.content.Intent.ACTION_PACKAGE_ADDED; 35 import static android.content.Intent.ACTION_UID_REMOVED; 36 import static android.content.Intent.ACTION_USER_ADDED; 37 import static android.content.Intent.ACTION_USER_REMOVED; 38 import static android.content.Intent.EXTRA_UID; 39 import static android.content.pm.PackageManager.MATCH_ANY_USER; 40 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 42 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 43 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 44 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 45 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED; 46 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 47 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 48 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 49 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; 50 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 51 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; 52 import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY; 53 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 54 import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE; 55 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 57 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 58 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 59 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 60 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 61 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 62 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 63 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; 64 import static android.net.ConnectivityManager.TYPE_MOBILE; 65 import static android.net.INetd.FIREWALL_RULE_ALLOW; 66 import static android.net.INetd.FIREWALL_RULE_DENY; 67 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 68 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 69 import static android.net.NetworkPolicy.LIMIT_DISABLED; 70 import static android.net.NetworkPolicy.SNOOZE_NEVER; 71 import static android.net.NetworkPolicy.WARNING_DISABLED; 72 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND; 73 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK; 74 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM; 75 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED; 76 import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; 77 import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST; 78 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; 79 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST; 80 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST; 81 import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; 82 import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; 83 import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; 84 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 85 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 86 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; 87 import static android.net.NetworkPolicyManager.POLICY_NONE; 88 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 89 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 90 import static android.net.NetworkPolicyManager.RULE_NONE; 91 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 92 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 93 import static android.net.NetworkPolicyManager.RULE_REJECT_RESTRICTED_MODE; 94 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 95 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; 96 import static android.net.NetworkPolicyManager.allowedReasonsToString; 97 import static android.net.NetworkPolicyManager.blockedReasonsToString; 98 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 99 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileInLowPowerStandby; 100 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 101 import static android.net.NetworkPolicyManager.resolveNetworkId; 102 import static android.net.NetworkPolicyManager.uidPoliciesToString; 103 import static android.net.NetworkPolicyManager.uidRulesToString; 104 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; 105 import static android.net.NetworkStats.METERED_ALL; 106 import static android.net.NetworkStats.METERED_YES; 107 import static android.net.NetworkTemplate.MATCH_CARRIER; 108 import static android.net.NetworkTemplate.MATCH_MOBILE; 109 import static android.net.NetworkTemplate.MATCH_WIFI; 110 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; 111 import static android.os.Trace.TRACE_TAG_NETWORK; 112 import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; 113 import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED; 114 import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS; 115 import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH; 116 import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED; 117 import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED; 118 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; 119 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; 120 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; 121 import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL; 122 import static android.telephony.CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL; 123 import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL; 124 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 125 126 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; 127 import static com.android.internal.util.ArrayUtils.appendInt; 128 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 129 import static com.android.internal.util.XmlUtils.readIntAttribute; 130 import static com.android.internal.util.XmlUtils.readLongAttribute; 131 import static com.android.internal.util.XmlUtils.readStringAttribute; 132 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 133 import static com.android.internal.util.XmlUtils.writeIntAttribute; 134 import static com.android.internal.util.XmlUtils.writeLongAttribute; 135 import static com.android.internal.util.XmlUtils.writeStringAttribute; 136 import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; 137 138 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 139 import static org.xmlpull.v1.XmlPullParser.END_TAG; 140 import static org.xmlpull.v1.XmlPullParser.START_TAG; 141 142 import android.Manifest; 143 import android.annotation.IntDef; 144 import android.annotation.NonNull; 145 import android.annotation.Nullable; 146 import android.app.ActivityManager; 147 import android.app.ActivityManager.ProcessCapability; 148 import android.app.ActivityManagerInternal; 149 import android.app.AppGlobals; 150 import android.app.AppOpsManager; 151 import android.app.IActivityManager; 152 import android.app.IUidObserver; 153 import android.app.Notification; 154 import android.app.NotificationManager; 155 import android.app.PendingIntent; 156 import android.app.usage.NetworkStats; 157 import android.app.usage.NetworkStatsManager; 158 import android.app.usage.UsageStatsManagerInternal; 159 import android.content.BroadcastReceiver; 160 import android.content.ComponentName; 161 import android.content.ContentResolver; 162 import android.content.Context; 163 import android.content.Intent; 164 import android.content.IntentFilter; 165 import android.content.pm.ApplicationInfo; 166 import android.content.pm.IPackageManager; 167 import android.content.pm.PackageManager; 168 import android.content.pm.PackageManager.NameNotFoundException; 169 import android.content.pm.PackageManagerInternal; 170 import android.content.pm.UserInfo; 171 import android.content.res.Resources; 172 import android.database.ContentObserver; 173 import android.net.ConnectivityManager; 174 import android.net.ConnectivityManager.NetworkCallback; 175 import android.net.INetworkManagementEventObserver; 176 import android.net.INetworkPolicyListener; 177 import android.net.INetworkPolicyManager; 178 import android.net.LinkProperties; 179 import android.net.Network; 180 import android.net.NetworkCapabilities; 181 import android.net.NetworkIdentity; 182 import android.net.NetworkPolicy; 183 import android.net.NetworkPolicyManager; 184 import android.net.NetworkPolicyManager.UidState; 185 import android.net.NetworkRequest; 186 import android.net.NetworkStack; 187 import android.net.NetworkStateSnapshot; 188 import android.net.NetworkTemplate; 189 import android.net.wifi.WifiConfiguration; 190 import android.net.wifi.WifiManager; 191 import android.os.BestClock; 192 import android.os.Binder; 193 import android.os.Environment; 194 import android.os.Handler; 195 import android.os.HandlerExecutor; 196 import android.os.HandlerThread; 197 import android.os.INetworkManagementService; 198 import android.os.Message; 199 import android.os.MessageQueue.IdleHandler; 200 import android.os.ParcelFileDescriptor; 201 import android.os.PersistableBundle; 202 import android.os.PowerExemptionManager.ReasonCode; 203 import android.os.PowerManager; 204 import android.os.PowerManager.ServiceType; 205 import android.os.PowerManagerInternal; 206 import android.os.PowerSaveState; 207 import android.os.PowerWhitelistManager; 208 import android.os.Process; 209 import android.os.RemoteCallbackList; 210 import android.os.RemoteException; 211 import android.os.SystemClock; 212 import android.os.SystemProperties; 213 import android.os.Trace; 214 import android.os.UserHandle; 215 import android.os.UserManager; 216 import android.provider.Settings; 217 import android.provider.Settings.Global; 218 import android.telephony.CarrierConfigManager; 219 import android.telephony.SubscriptionInfo; 220 import android.telephony.SubscriptionManager; 221 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 222 import android.telephony.SubscriptionPlan; 223 import android.telephony.TelephonyManager; 224 import android.text.TextUtils; 225 import android.text.format.DateUtils; 226 import android.text.format.Formatter; 227 import android.util.ArrayMap; 228 import android.util.ArraySet; 229 import android.util.AtomicFile; 230 import android.util.DataUnit; 231 import android.util.IntArray; 232 import android.util.Log; 233 import android.util.Pair; 234 import android.util.Range; 235 import android.util.RecurrenceRule; 236 import android.util.Slog; 237 import android.util.SparseArray; 238 import android.util.SparseBooleanArray; 239 import android.util.SparseIntArray; 240 import android.util.SparseLongArray; 241 import android.util.SparseSetArray; 242 import android.util.TypedXmlPullParser; 243 import android.util.TypedXmlSerializer; 244 import android.util.Xml; 245 246 import com.android.internal.R; 247 import com.android.internal.annotations.GuardedBy; 248 import com.android.internal.annotations.VisibleForTesting; 249 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 250 import com.android.internal.notification.SystemNotificationChannels; 251 import com.android.internal.os.SomeArgs; 252 import com.android.internal.util.ArrayUtils; 253 import com.android.internal.util.CollectionUtils; 254 import com.android.internal.util.ConcurrentUtils; 255 import com.android.internal.util.DumpUtils; 256 import com.android.internal.util.IndentingPrintWriter; 257 import com.android.internal.util.StatLogger; 258 import com.android.net.module.util.NetworkIdentityUtils; 259 import com.android.net.module.util.NetworkStatsUtils; 260 import com.android.net.module.util.PermissionUtils; 261 import com.android.server.EventLogTags; 262 import com.android.server.LocalServices; 263 import com.android.server.ServiceThread; 264 import com.android.server.SystemConfig; 265 import com.android.server.connectivity.MultipathPolicyTracker; 266 import com.android.server.usage.AppStandbyInternal; 267 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; 268 269 import dalvik.annotation.optimization.NeverCompile; 270 271 import libcore.io.IoUtils; 272 273 import java.io.File; 274 import java.io.FileDescriptor; 275 import java.io.FileInputStream; 276 import java.io.FileNotFoundException; 277 import java.io.FileOutputStream; 278 import java.io.IOException; 279 import java.io.PrintWriter; 280 import java.lang.annotation.Retention; 281 import java.lang.annotation.RetentionPolicy; 282 import java.time.Clock; 283 import java.time.Instant; 284 import java.time.ZoneId; 285 import java.time.ZoneOffset; 286 import java.time.ZonedDateTime; 287 import java.time.temporal.ChronoUnit; 288 import java.util.ArrayList; 289 import java.util.Arrays; 290 import java.util.Calendar; 291 import java.util.List; 292 import java.util.Objects; 293 import java.util.Set; 294 import java.util.concurrent.CountDownLatch; 295 import java.util.concurrent.Executor; 296 import java.util.concurrent.TimeUnit; 297 import java.util.function.IntConsumer; 298 299 /** 300 * Service that maintains low-level network policy rules, using 301 * {@link NetworkStatsService} statistics to drive those rules. 302 * <p> 303 * Derives active rules by combining a given policy with other system status, 304 * and delivers to listeners, such as {@link ConnectivityManager}, for 305 * enforcement. 306 * 307 * <p> 308 * This class uses 2 locks to synchronize state: 309 * <ul> 310 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall 311 * rules). 312 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such 313 * as network policies). 314 * </ul> 315 * 316 * <p> 317 * As such, methods that require synchronization have the following prefixes: 318 * <ul> 319 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}). 320 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}). 321 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock} 322 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc.. 323 * </ul> 324 */ 325 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 326 static final String TAG = NetworkPolicyLogger.TAG; 327 private static final boolean LOGD = NetworkPolicyLogger.LOGD; 328 private static final boolean LOGV = NetworkPolicyLogger.LOGV; 329 330 /** 331 * No opportunistic quota could be calculated from user data plan or data settings. 332 */ 333 public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1; 334 335 private static final int VERSION_INIT = 1; 336 private static final int VERSION_ADDED_SNOOZE = 2; 337 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 338 private static final int VERSION_ADDED_METERED = 4; 339 private static final int VERSION_SPLIT_SNOOZE = 5; 340 private static final int VERSION_ADDED_TIMEZONE = 6; 341 private static final int VERSION_ADDED_INFERRED = 7; 342 private static final int VERSION_SWITCH_APP_ID = 8; 343 private static final int VERSION_ADDED_NETWORK_ID = 9; 344 private static final int VERSION_SWITCH_UID = 10; 345 private static final int VERSION_ADDED_CYCLE = 11; 346 private static final int VERSION_ADDED_NETWORK_TYPES = 12; 347 private static final int VERSION_SUPPORTED_CARRIER_USAGE = 13; 348 private static final int VERSION_REMOVED_SUBSCRIPTION_PLANS = 14; 349 private static final int VERSION_LATEST = VERSION_REMOVED_SUBSCRIPTION_PLANS; 350 351 @VisibleForTesting 352 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING; 353 @VisibleForTesting 354 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT; 355 @VisibleForTesting 356 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED; 357 @VisibleForTesting 358 public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID; 359 360 private static final String TAG_POLICY_LIST = "policy-list"; 361 private static final String TAG_NETWORK_POLICY = "network-policy"; 362 private static final String TAG_UID_POLICY = "uid-policy"; 363 private static final String TAG_APP_POLICY = "app-policy"; 364 private static final String TAG_WHITELIST = "whitelist"; 365 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; 366 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background"; 367 private static final String TAG_XML_UTILS_INT_ARRAY = "int-array"; 368 369 private static final String ATTR_VERSION = "version"; 370 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 371 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 372 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 373 private static final String ATTR_SUBSCRIBER_ID_MATCH_RULE = "subscriberIdMatchRule"; 374 private static final String ATTR_NETWORK_ID = "networkId"; 375 private static final String ATTR_TEMPLATE_METERED = "templateMetered"; 376 @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay"; 377 @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 378 private static final String ATTR_CYCLE_START = "cycleStart"; 379 private static final String ATTR_CYCLE_END = "cycleEnd"; 380 private static final String ATTR_CYCLE_PERIOD = "cyclePeriod"; 381 private static final String ATTR_WARNING_BYTES = "warningBytes"; 382 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 383 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 384 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 385 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 386 private static final String ATTR_METERED = "metered"; 387 private static final String ATTR_INFERRED = "inferred"; 388 private static final String ATTR_UID = "uid"; 389 private static final String ATTR_APP_ID = "appId"; 390 private static final String ATTR_POLICY = "policy"; 391 private static final String ATTR_SUB_ID = "subId"; 392 private static final String ATTR_TITLE = "title"; 393 private static final String ATTR_SUMMARY = "summary"; 394 private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior"; 395 private static final String ATTR_USAGE_BYTES = "usageBytes"; 396 private static final String ATTR_USAGE_TIME = "usageTime"; 397 private static final String ATTR_OWNER_PACKAGE = "ownerPackage"; 398 private static final String ATTR_NETWORK_TYPES = "networkTypes"; 399 private static final String ATTR_XML_UTILS_NAME = "name"; 400 401 private static final String ACTION_SNOOZE_WARNING = 402 "com.android.server.net.action.SNOOZE_WARNING"; 403 private static final String ACTION_SNOOZE_RAPID = 404 "com.android.server.net.action.SNOOZE_RAPID"; 405 406 /** 407 * Indicates the maximum wait time for admin data to be available. 408 */ 409 private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000; 410 411 private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20); 412 private static final float QUOTA_LIMITED_DEFAULT = 0.1f; 413 private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f; 414 private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f; 415 416 private static final int MSG_RULES_CHANGED = 1; 417 private static final int MSG_METERED_IFACES_CHANGED = 2; 418 private static final int MSG_LIMIT_REACHED = 5; 419 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 420 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 421 private static final int MSG_UPDATE_INTERFACE_QUOTAS = 10; 422 private static final int MSG_REMOVE_INTERFACE_QUOTAS = 11; 423 private static final int MSG_POLICIES_CHANGED = 13; 424 private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15; 425 private static final int MSG_SUBSCRIPTION_OVERRIDE = 16; 426 private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17; 427 private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18; 428 private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19; 429 private static final int MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED = 20; 430 431 // TODO: Add similar docs for other messages. 432 /** 433 * Message to indicate that reasons for why an uid is blocked changed. 434 * arg1 = uid 435 * arg2 = newBlockedReasons 436 * obj = oldBlockedReasons 437 */ 438 private static final int MSG_UID_BLOCKED_REASON_CHANGED = 21; 439 440 /** 441 * Message to indicate that subscription plans expired and should be cleared. 442 * arg1 = subId 443 * arg2 = setSubscriptionPlans call ID 444 * obj = callingPackage 445 */ 446 private static final int MSG_CLEAR_SUBSCRIPTION_PLANS = 22; 447 448 /** 449 * Message to indicate that reasons for why some uids are blocked changed. 450 * obj = SparseArray<SomeArgs> where key = uid and value = SomeArgs object with 451 * value.argi1 = oldEffectiveBlockedReasons, 452 * value.argi2 = newEffectiveBlockedReasons, 453 * value.argi3 = uidRules 454 */ 455 private static final int MSG_UIDS_BLOCKED_REASONS_CHANGED = 23; 456 457 private static final int UID_MSG_STATE_CHANGED = 100; 458 private static final int UID_MSG_GONE = 101; 459 460 private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner"; 461 462 private final Context mContext; 463 private final IActivityManager mActivityManager; 464 private NetworkStatsManager mNetworkStats; 465 private final INetworkManagementService mNetworkManager; 466 private UsageStatsManagerInternal mUsageStats; 467 private AppStandbyInternal mAppStandby; 468 private final Clock mClock; 469 private final UserManager mUserManager; 470 private final CarrierConfigManager mCarrierConfigManager; 471 private final MultipathPolicyTracker mMultipathPolicyTracker; 472 473 private ConnectivityManager mConnManager; 474 private PowerManagerInternal mPowerManagerInternal; 475 private PowerWhitelistManager mPowerWhitelistManager; 476 @NonNull 477 private final Dependencies mDeps; 478 479 /** Current cached value of the current Battery Saver mode's setting for restrict background. */ 480 @GuardedBy("mUidRulesFirstLock") 481 private boolean mRestrictBackgroundLowPowerMode; 482 483 // Store the status of restrict background before turning on battery saver. 484 // Used to restore mRestrictBackground when battery saver is turned off. 485 private boolean mRestrictBackgroundBeforeBsm; 486 487 // Denotes the status of restrict background read from disk. 488 private boolean mLoadedRestrictBackground; 489 490 // See main javadoc for instructions on how to use these locks. 491 final Object mUidRulesFirstLock = new Object(); 492 final Object mNetworkPoliciesSecondLock = new Object(); 493 494 @GuardedBy(anyOf = {"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) 495 volatile boolean mSystemReady; 496 497 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground; 498 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower; 499 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode; 500 // Store whether user flipped restrict background in battery saver mode 501 @GuardedBy("mUidRulesFirstLock") 502 volatile boolean mRestrictBackgroundChangedInBsm; 503 @GuardedBy("mUidRulesFirstLock") 504 volatile boolean mRestrictedNetworkingMode; 505 @GuardedBy("mUidRulesFirstLock") 506 volatile boolean mLowPowerStandbyActive; 507 508 private final boolean mSuppressDefaultPolicy; 509 510 private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1); 511 512 private volatile boolean mNetworkManagerReady; 513 514 /** Defined network policies. */ 515 @GuardedBy("mNetworkPoliciesSecondLock") 516 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); 517 518 /** Map from subId to subscription plans. */ 519 @GuardedBy("mNetworkPoliciesSecondLock") 520 final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>(); 521 /** Map from subId to package name that owns subscription plans. */ 522 @GuardedBy("mNetworkPoliciesSecondLock") 523 final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>(); 524 /** Map from subId to the ID of the clear plans request. */ 525 @GuardedBy("mNetworkPoliciesSecondLock") 526 final SparseIntArray mSetSubscriptionPlansIds = new SparseIntArray(); 527 /** Atomic integer to generate a new ID for each clear plans request. */ 528 @GuardedBy("mNetworkPoliciesSecondLock") 529 int mSetSubscriptionPlansIdCounter = 0; 530 531 /** Map from subId to daily opportunistic quota. */ 532 @GuardedBy("mNetworkPoliciesSecondLock") 533 final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray(); 534 535 /** Defined UID policies. */ 536 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray(); 537 538 @GuardedBy("mUidRulesFirstLock") 539 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 540 @GuardedBy("mUidRulesFirstLock") 541 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 542 @GuardedBy("mUidRulesFirstLock") 543 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 544 @GuardedBy("mUidRulesFirstLock") 545 final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray(); 546 @GuardedBy("mUidRulesFirstLock") 547 final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray(); 548 549 /** Set of states for the child firewall chains. True if the chain is active. */ 550 @GuardedBy("mUidRulesFirstLock") 551 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 552 553 // "Power save mode" is the concept used in the DeviceIdleController that includes various 554 // features including Doze and Battery Saver. It include Battery Saver, but "power save mode" 555 // and "battery saver" are not equivalent. 556 557 /** 558 * UIDs that have been allowlisted to always be able to have network access 559 * in power save mode, except device idle (doze) still applies. 560 * TODO: An int array might be sufficient 561 */ 562 @GuardedBy("mUidRulesFirstLock") 563 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 564 565 /** 566 * UIDs that have been allowlisted to always be able to have network access 567 * in power save mode. 568 * TODO: An int array might be sufficient 569 */ 570 @GuardedBy("mUidRulesFirstLock") 571 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); 572 573 @GuardedBy("mUidRulesFirstLock") 574 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); 575 576 @GuardedBy("mUidRulesFirstLock") 577 private final SparseBooleanArray mLowPowerStandbyAllowlistUids = new SparseBooleanArray(); 578 579 /** 580 * UIDs that have been allowlisted temporarily to be able to have network access despite being 581 * idle. Other power saving restrictions still apply. 582 */ 583 @GuardedBy("mUidRulesFirstLock") 584 private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray(); 585 586 /** 587 * UIDs that have been initially allowlisted by system to avoid restricted background. 588 */ 589 @GuardedBy("mUidRulesFirstLock") 590 private final SparseBooleanArray mDefaultRestrictBackgroundAllowlistUids = 591 new SparseBooleanArray(); 592 593 /** 594 * UIDs that have been initially allowlisted by system to avoid restricted background, 595 * but later revoked by user. 596 */ 597 @GuardedBy("mUidRulesFirstLock") 598 private final SparseBooleanArray mRestrictBackgroundAllowlistRevokedUids = 599 new SparseBooleanArray(); 600 601 final Object mMeteredIfacesLock = new Object(); 602 /** Set of ifaces that are metered. */ 603 @GuardedBy("mMeteredIfacesLock") 604 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 605 /** Set of over-limit templates that have been notified. */ 606 @GuardedBy("mNetworkPoliciesSecondLock") 607 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>(); 608 609 /** Set of currently active {@link Notification} tags. */ 610 @GuardedBy("mNetworkPoliciesSecondLock") 611 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>(); 612 613 /** Foreground at UID granularity. */ 614 @GuardedBy("mUidRulesFirstLock") 615 private final SparseArray<UidState> mUidState = new SparseArray<>(); 616 617 @GuardedBy("mUidBlockedState") 618 private final SparseArray<UidBlockedState> mUidBlockedState = new SparseArray<>(); 619 620 /** Objects used temporarily while computing the new blocked state for each uid. */ 621 @GuardedBy("mUidRulesFirstLock") 622 private final SparseArray<UidBlockedState> mTmpUidBlockedState = new SparseArray<>(); 623 624 /** Map from network ID to last observed meteredness state */ 625 @GuardedBy("mNetworkPoliciesSecondLock") 626 private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray(); 627 /** Map from network ID to last observed roaming state */ 628 @GuardedBy("mNetworkPoliciesSecondLock") 629 private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray(); 630 /** Map from network ID to the last ifaces on it */ 631 @GuardedBy("mNetworkPoliciesSecondLock") 632 private SparseSetArray<String> mNetworkToIfaces = new SparseSetArray<>(); 633 634 /** Map from netId to subId as of last update */ 635 @GuardedBy("mNetworkPoliciesSecondLock") 636 private final SparseIntArray mNetIdToSubId = new SparseIntArray(); 637 638 /** Map from subId to subscriberId as of last update */ 639 @GuardedBy("mNetworkPoliciesSecondLock") 640 private final SparseArray<String> mSubIdToSubscriberId = new SparseArray<>(); 641 /** Set of all merged subscriberId as of last update */ 642 @GuardedBy("mNetworkPoliciesSecondLock") 643 private List<String[]> mMergedSubscriberIds = new ArrayList<>(); 644 /** Map from subId to carrierConfig as of last update */ 645 @GuardedBy("mNetworkPoliciesSecondLock") 646 private final SparseArray<PersistableBundle> mSubIdToCarrierConfig = 647 new SparseArray<PersistableBundle>(); 648 649 /** 650 * Indicates the uids restricted by admin from accessing metered data. It's a mapping from 651 * userId to restricted uids which belong to that user. 652 */ 653 @GuardedBy("mUidRulesFirstLock") 654 private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>(); 655 656 private final RemoteCallbackList<INetworkPolicyListener> 657 mListeners = new RemoteCallbackList<>(); 658 659 final Handler mHandler; 660 @VisibleForTesting 661 final Handler mUidEventHandler; 662 663 private final ServiceThread mUidEventThread; 664 665 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) 666 private final AtomicFile mPolicyFile; 667 668 private final AppOpsManager mAppOps; 669 670 private final IPackageManager mIPm; 671 672 private ActivityManagerInternal mActivityManagerInternal; 673 674 private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger(); 675 676 /** List of apps indexed by uid and whether they have the internet permission */ 677 @GuardedBy("mUidRulesFirstLock") 678 private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray(); 679 680 /** 681 * Map of uid -> UidStateCallbackInfo objects holding the data received from 682 * {@link IUidObserver#onUidStateChanged(int, int, long, int)} callbacks. In order to avoid 683 * creating a new object for every callback received, we hold onto the object created for each 684 * uid and reuse it. 685 * 686 * Note that the lock used for accessing this object should not be used for anything else and we 687 * should not be acquiring new locks or doing any heavy work while this lock is held since this 688 * will be used in the callback from ActivityManagerService. 689 */ 690 @GuardedBy("mUidStateCallbackInfos") 691 private final SparseArray<UidStateCallbackInfo> mUidStateCallbackInfos = 692 new SparseArray<>(); 693 694 private RestrictedModeObserver mRestrictedModeObserver; 695 696 // TODO: keep allowlist of system-critical services that should never have 697 // rules enforced, such as system, phone, and radio UIDs. 698 699 // TODO: migrate notifications to SystemUI 700 701 702 interface Stats { 703 int UPDATE_NETWORK_ENABLED = 0; 704 int IS_UID_NETWORKING_BLOCKED = 1; 705 706 int COUNT = IS_UID_NETWORKING_BLOCKED + 1; 707 } 708 709 private static class RestrictedModeObserver extends ContentObserver { 710 private final Context mContext; 711 private final RestrictedModeListener mListener; 712 RestrictedModeObserver(Context ctx, RestrictedModeListener listener)713 RestrictedModeObserver(Context ctx, RestrictedModeListener listener) { 714 super(null); 715 mContext = ctx; 716 mListener = listener; 717 mContext.getContentResolver().registerContentObserver( 718 Settings.Global.getUriFor(Settings.Global.RESTRICTED_NETWORKING_MODE), false, 719 this); 720 } 721 isRestrictedModeEnabled()722 public boolean isRestrictedModeEnabled() { 723 return Settings.Global.getInt(mContext.getContentResolver(), 724 Settings.Global.RESTRICTED_NETWORKING_MODE, 0) != 0; 725 } 726 727 @Override onChange(boolean selfChange)728 public void onChange(boolean selfChange) { 729 mListener.onChange(isRestrictedModeEnabled()); 730 } 731 732 public interface RestrictedModeListener { onChange(boolean enabled)733 void onChange(boolean enabled); 734 } 735 } 736 737 public final StatLogger mStatLogger = new StatLogger(new String[]{ 738 "updateNetworkEnabledNL()", 739 "isUidNetworkingBlocked()", 740 }); 741 NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkManagementService networkManagement)742 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 743 INetworkManagementService networkManagement) { 744 this(context, activityManager, networkManagement, AppGlobals.getPackageManager(), 745 getDefaultClock(), getDefaultSystemDir(), false, new Dependencies(context)); 746 } 747 getDefaultSystemDir()748 private static @NonNull File getDefaultSystemDir() { 749 return new File(Environment.getDataDirectory(), "system"); 750 } 751 getDefaultClock()752 private static @NonNull Clock getDefaultClock() { 753 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(), 754 Clock.systemUTC()); 755 } 756 757 static class Dependencies { 758 final Context mContext; 759 final NetworkStatsManager mNetworkStatsManager; Dependencies(Context context)760 Dependencies(Context context) { 761 mContext = context; 762 mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class); 763 // Query stats from NetworkStatsService will trigger a poll by default. 764 // But since NPMS listens stats updated event, and will query stats 765 // after the event. A polling -> updated -> query -> polling loop will be introduced 766 // if polls on open. Hence, while NPMS manages it's poll requests explicitly, set 767 // flag to false to prevent a polling loop. 768 mNetworkStatsManager.setPollOnOpen(false); 769 } 770 getNetworkTotalBytes(NetworkTemplate template, long start, long end)771 long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { 772 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes"); 773 try { 774 final NetworkStats.Bucket ret = mNetworkStatsManager 775 .querySummaryForDevice(template, start, end); 776 return ret.getRxBytes() + ret.getTxBytes(); 777 } catch (RuntimeException e) { 778 Slog.w(TAG, "Failed to read network stats: " + e); 779 return 0; 780 } finally { 781 Trace.traceEnd(TRACE_TAG_NETWORK); 782 } 783 } 784 785 @NonNull getNetworkUidBytes( @onNull NetworkTemplate template, long start, long end)786 List<NetworkStats.Bucket> getNetworkUidBytes( 787 @NonNull NetworkTemplate template, long start, long end) { 788 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes"); 789 final List<NetworkStats.Bucket> buckets = new ArrayList<>(); 790 try { 791 final NetworkStats stats = mNetworkStatsManager.querySummary(template, start, end); 792 while (stats.hasNextBucket()) { 793 final NetworkStats.Bucket bucket = new NetworkStats.Bucket(); 794 stats.getNextBucket(bucket); 795 buckets.add(bucket); 796 } 797 } catch (RuntimeException e) { 798 Slog.w(TAG, "Failed to read network stats: " + e); 799 } finally { 800 Trace.traceEnd(TRACE_TAG_NETWORK); 801 } 802 return buckets; 803 } 804 } 805 806 @VisibleForTesting NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkManagementService networkManagement, IPackageManager pm, Clock clock, File systemDir, boolean suppressDefaultPolicy, Dependencies deps)807 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 808 INetworkManagementService networkManagement, IPackageManager pm, Clock clock, 809 File systemDir, boolean suppressDefaultPolicy, Dependencies deps) { 810 mContext = Objects.requireNonNull(context, "missing context"); 811 mActivityManager = Objects.requireNonNull(activityManager, "missing activityManager"); 812 mNetworkManager = Objects.requireNonNull(networkManagement, "missing networkManagement"); 813 mPowerWhitelistManager = mContext.getSystemService(PowerWhitelistManager.class); 814 mClock = Objects.requireNonNull(clock, "missing Clock"); 815 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 816 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); 817 mIPm = pm; 818 819 HandlerThread thread = new HandlerThread(TAG); 820 thread.start(); 821 mHandler = new Handler(thread.getLooper(), mHandlerCallback); 822 823 // We create another thread for the UID events, which are more time-critical. 824 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND, 825 /*allowIo=*/ false); 826 mUidEventThread.start(); 827 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback); 828 829 mSuppressDefaultPolicy = suppressDefaultPolicy; 830 mDeps = Objects.requireNonNull(deps, "missing Dependencies"); 831 832 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy"); 833 834 mAppOps = context.getSystemService(AppOpsManager.class); 835 mNetworkStats = context.getSystemService(NetworkStatsManager.class); 836 mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler); 837 // Expose private service for system components to use. 838 LocalServices.addService(NetworkPolicyManagerInternal.class, 839 new NetworkPolicyManagerInternalImpl()); 840 } 841 bindConnectivityManager()842 public void bindConnectivityManager() { 843 mConnManager = Objects.requireNonNull(mContext.getSystemService(ConnectivityManager.class), 844 "missing ConnectivityManager"); 845 } 846 847 @GuardedBy("mUidRulesFirstLock") updatePowerSaveWhitelistUL()848 private void updatePowerSaveWhitelistUL() { 849 int[] whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ false); 850 mPowerSaveWhitelistExceptIdleAppIds.clear(); 851 for (int uid : whitelist) { 852 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); 853 } 854 855 whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ true); 856 mPowerSaveWhitelistAppIds.clear(); 857 for (int uid : whitelist) { 858 mPowerSaveWhitelistAppIds.put(uid, true); 859 } 860 } 861 862 /** 863 * Allows pre-defined apps for restrict background, but only if the user didn't already 864 * revoked them. 865 * 866 * @return whether any uid has been added to allowlist. 867 */ 868 @GuardedBy("mUidRulesFirstLock") addDefaultRestrictBackgroundAllowlistUidsUL()869 boolean addDefaultRestrictBackgroundAllowlistUidsUL() { 870 final List<UserInfo> users = mUserManager.getUsers(); 871 final int numberUsers = users.size(); 872 873 boolean changed = false; 874 for (int i = 0; i < numberUsers; i++) { 875 final UserInfo user = users.get(i); 876 changed = addDefaultRestrictBackgroundAllowlistUidsUL(user.id) || changed; 877 } 878 return changed; 879 } 880 881 @GuardedBy("mUidRulesFirstLock") addDefaultRestrictBackgroundAllowlistUidsUL(int userId)882 private boolean addDefaultRestrictBackgroundAllowlistUidsUL(int userId) { 883 final SystemConfig sysConfig = SystemConfig.getInstance(); 884 final PackageManager pm = mContext.getPackageManager(); 885 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave(); 886 boolean changed = false; 887 for (int i = 0; i < allowDataUsage.size(); i++) { 888 final String pkg = allowDataUsage.valueAt(i); 889 if (LOGD) 890 Slog.d(TAG, "checking restricted background exemption for package " + pkg 891 + " and user " + userId); 892 final ApplicationInfo app; 893 try { 894 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId); 895 } catch (PackageManager.NameNotFoundException e) { 896 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg); 897 // Ignore it - some apps on allow-in-data-usage-save are optional. 898 continue; 899 } 900 if (!app.isPrivilegedApp()) { 901 Slog.e(TAG, "addDefaultRestrictBackgroundAllowlistUidsUL(): " 902 + "skipping non-privileged app " + pkg); 903 continue; 904 } 905 final int uid = UserHandle.getUid(userId, app.uid); 906 mDefaultRestrictBackgroundAllowlistUids.append(uid, true); 907 if (LOGD) 908 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted " 909 + "background allowlist. Revoked status: " 910 + mRestrictBackgroundAllowlistRevokedUids.get(uid)); 911 if (!mRestrictBackgroundAllowlistRevokedUids.get(uid)) { 912 if (LOGD) 913 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user " 914 + userId + ") to restrict background allowlist"); 915 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false); 916 changed = true; 917 } 918 } 919 return changed; 920 } 921 initService(CountDownLatch initCompleteSignal)922 private void initService(CountDownLatch initCompleteSignal) { 923 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady"); 924 final int oldPriority = Process.getThreadPriority(Process.myTid()); 925 try { 926 // Boost thread's priority during system server init 927 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 928 if (!isBandwidthControlEnabled()) { 929 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 930 return; 931 } 932 933 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); 934 mAppStandby = LocalServices.getService(AppStandbyInternal.class); 935 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 936 937 synchronized (mUidRulesFirstLock) { 938 synchronized (mNetworkPoliciesSecondLock) { 939 updatePowerSaveWhitelistUL(); 940 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 941 mPowerManagerInternal.registerLowPowerModeObserver( 942 new PowerManagerInternal.LowPowerModeListener() { 943 @Override 944 public int getServiceType() { 945 return ServiceType.NETWORK_FIREWALL; 946 } 947 948 @Override 949 public void onLowPowerModeChanged(PowerSaveState result) { 950 final boolean enabled = result.batterySaverEnabled; 951 if (LOGD) { 952 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")"); 953 } 954 synchronized (mUidRulesFirstLock) { 955 if (mRestrictPower != enabled) { 956 mRestrictPower = enabled; 957 updateRulesForRestrictPowerUL(); 958 } 959 } 960 } 961 }); 962 mRestrictPower = mPowerManagerInternal.getLowPowerState( 963 ServiceType.NETWORK_FIREWALL).batterySaverEnabled; 964 965 mRestrictedModeObserver = new RestrictedModeObserver(mContext, 966 enabled -> { 967 synchronized (mUidRulesFirstLock) { 968 mRestrictedNetworkingMode = enabled; 969 updateRestrictedModeAllowlistUL(); 970 } 971 }); 972 mRestrictedNetworkingMode = mRestrictedModeObserver.isRestrictedModeEnabled(); 973 974 mSystemReady = true; 975 976 waitForAdminData(); 977 978 // read policy from disk 979 readPolicyAL(); 980 981 // Update the restrictBackground if battery saver is turned on 982 mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground; 983 mRestrictBackgroundLowPowerMode = mPowerManagerInternal 984 .getLowPowerState(ServiceType.DATA_SAVER).batterySaverEnabled; 985 if (mRestrictBackgroundLowPowerMode && !mLoadedRestrictBackground) { 986 mLoadedRestrictBackground = true; 987 } 988 mPowerManagerInternal.registerLowPowerModeObserver( 989 new PowerManagerInternal.LowPowerModeListener() { 990 @Override 991 public int getServiceType() { 992 return ServiceType.DATA_SAVER; 993 } 994 995 @Override 996 public void onLowPowerModeChanged(PowerSaveState result) { 997 synchronized (mUidRulesFirstLock) { 998 updateRestrictBackgroundByLowPowerModeUL(result); 999 } 1000 } 1001 }); 1002 1003 if (addDefaultRestrictBackgroundAllowlistUidsUL()) { 1004 writePolicyAL(); 1005 } 1006 1007 setRestrictBackgroundUL(mLoadedRestrictBackground, "init_service"); 1008 updateRulesForGlobalChangeAL(false); 1009 updateNotificationsNL(); 1010 } 1011 } 1012 1013 try { 1014 final int changes = ActivityManager.UID_OBSERVER_PROCSTATE 1015 | ActivityManager.UID_OBSERVER_GONE 1016 | ActivityManager.UID_OBSERVER_CAPABILITY; 1017 mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes, 1018 NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android"); 1019 mNetworkManager.registerObserver(mAlertObserver); 1020 } catch (RemoteException e) { 1021 // ignored; both services live in system_server 1022 } 1023 1024 // listen for changes to power save allowlist 1025 final IntentFilter whitelistFilter = new IntentFilter( 1026 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 1027 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); 1028 1029 // watch for network interfaces to be claimed 1030 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 1031 mContext.registerReceiver(mConnReceiver, connFilter, NETWORK_STACK, mHandler); 1032 1033 // listen for package changes to update policy 1034 final IntentFilter packageFilter = new IntentFilter(); 1035 packageFilter.addAction(ACTION_PACKAGE_ADDED); 1036 packageFilter.addDataScheme("package"); 1037 mContext.registerReceiverForAllUsers(mPackageReceiver, packageFilter, null, mHandler); 1038 1039 // listen for UID changes to update policy 1040 mContext.registerReceiverForAllUsers( 1041 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 1042 1043 // listen for user changes to update policy 1044 final IntentFilter userFilter = new IntentFilter(); 1045 userFilter.addAction(ACTION_USER_ADDED); 1046 userFilter.addAction(ACTION_USER_REMOVED); 1047 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 1048 1049 // listen for stats updated callbacks for interested network types. 1050 final Executor executor = new HandlerExecutor(mHandler); 1051 mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(), 1052 0 /* thresholdBytes */, executor, mStatsCallback); 1053 mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(), 1054 0 /* thresholdBytes */, executor, mStatsCallback); 1055 1056 // Listen for snooze from notifications 1057 mContext.registerReceiver(mSnoozeReceiver, 1058 new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler); 1059 mContext.registerReceiver(mSnoozeReceiver, 1060 new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler); 1061 1062 // listen for configured wifi networks to be loaded 1063 final IntentFilter wifiFilter = 1064 new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); 1065 mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler); 1066 1067 // listen for carrier config changes to update data cycle information 1068 final IntentFilter carrierConfigFilter = new IntentFilter( 1069 ACTION_CARRIER_CONFIG_CHANGED); 1070 mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler); 1071 1072 // listen for meteredness changes 1073 mConnManager.registerNetworkCallback( 1074 new NetworkRequest.Builder().build(), mNetworkCallback); 1075 1076 mAppStandby.addListener(new NetPolicyAppIdleStateChangeListener()); 1077 synchronized (mUidRulesFirstLock) { 1078 updateRulesForAppIdleParoleUL(); 1079 } 1080 1081 // Listen for subscriber changes 1082 mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener( 1083 new HandlerExecutor(mHandler), 1084 new OnSubscriptionsChangedListener() { 1085 @Override 1086 public void onSubscriptionsChanged() { 1087 updateNetworksInternal(); 1088 } 1089 }); 1090 1091 // tell systemReady() that the service has been initialized 1092 initCompleteSignal.countDown(); 1093 } finally { 1094 // Restore the default priority after init is done 1095 Process.setThreadPriority(oldPriority); 1096 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1097 } 1098 } 1099 networkScoreAndNetworkManagementServiceReady()1100 public CountDownLatch networkScoreAndNetworkManagementServiceReady() { 1101 mNetworkManagerReady = true; 1102 final CountDownLatch initCompleteSignal = new CountDownLatch(1); 1103 mHandler.post(() -> initService(initCompleteSignal)); 1104 return initCompleteSignal; 1105 } 1106 systemReady(CountDownLatch initCompleteSignal)1107 public void systemReady(CountDownLatch initCompleteSignal) { 1108 // wait for initService to complete 1109 try { 1110 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) { 1111 throw new IllegalStateException("Service " + TAG +" init timeout"); 1112 } 1113 mMultipathPolicyTracker.start(); 1114 } catch (InterruptedException e) { 1115 Thread.currentThread().interrupt(); 1116 throw new IllegalStateException("Service " + TAG + " init interrupted", e); 1117 } 1118 } 1119 1120 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 1121 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, 1122 @ProcessCapability int capability) { 1123 synchronized (mUidStateCallbackInfos) { 1124 UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid); 1125 if (callbackInfo == null) { 1126 callbackInfo = new UidStateCallbackInfo(); 1127 mUidStateCallbackInfos.put(uid, callbackInfo); 1128 } 1129 if (callbackInfo.procStateSeq == -1 || procStateSeq > callbackInfo.procStateSeq) { 1130 callbackInfo.update(uid, procState, procStateSeq, capability); 1131 } 1132 if (!callbackInfo.isPending) { 1133 mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo) 1134 .sendToTarget(); 1135 } 1136 } 1137 } 1138 1139 @Override public void onUidGone(int uid, boolean disabled) { 1140 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget(); 1141 } 1142 1143 @Override public void onUidActive(int uid) { 1144 } 1145 1146 @Override public void onUidIdle(int uid, boolean disabled) { 1147 } 1148 1149 @Override public void onUidCachedChanged(int uid, boolean cached) { 1150 } 1151 1152 @Override public void onUidProcAdjChanged(int uid) { 1153 } 1154 }; 1155 1156 private static final class UidStateCallbackInfo { 1157 public int uid; 1158 public int procState = ActivityManager.PROCESS_STATE_NONEXISTENT; 1159 public long procStateSeq = -1; 1160 @ProcessCapability 1161 public int capability; 1162 public boolean isPending; 1163 update(int uid, int procState, long procStateSeq, int capability)1164 public void update(int uid, int procState, long procStateSeq, int capability) { 1165 this.uid = uid; 1166 this.procState = procState; 1167 this.procStateSeq = procStateSeq; 1168 this.capability = capability; 1169 } 1170 } 1171 1172 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { 1173 @Override 1174 public void onReceive(Context context, Intent intent) { 1175 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected 1176 synchronized (mUidRulesFirstLock) { 1177 updatePowerSaveWhitelistUL(); 1178 updateRulesForRestrictPowerUL(); 1179 updateRulesForAppIdleUL(); 1180 } 1181 } 1182 }; 1183 1184 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 1185 @Override 1186 public void onReceive(Context context, Intent intent) { 1187 // on background handler thread, and PACKAGE_ADDED is protected 1188 1189 final String action = intent.getAction(); 1190 final int uid = intent.getIntExtra(EXTRA_UID, -1); 1191 if (uid == -1) return; 1192 1193 if (ACTION_PACKAGE_ADDED.equals(action)) { 1194 // update rules for UID, since it might be subject to 1195 // global background data policy 1196 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 1197 // Clear the cache for the app 1198 synchronized (mUidRulesFirstLock) { 1199 mInternetPermissionMap.delete(uid); 1200 updateRestrictionRulesForUidUL(uid); 1201 } 1202 } 1203 } 1204 }; 1205 1206 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 1207 @Override 1208 public void onReceive(Context context, Intent intent) { 1209 // on background handler thread, and UID_REMOVED is protected 1210 1211 final int uid = intent.getIntExtra(EXTRA_UID, -1); 1212 if (uid == -1) return; 1213 1214 // remove any policy and update rules to clean up 1215 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 1216 synchronized (mUidRulesFirstLock) { 1217 onUidDeletedUL(uid); 1218 synchronized (mNetworkPoliciesSecondLock) { 1219 writePolicyAL(); 1220 } 1221 } 1222 } 1223 }; 1224 1225 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 1226 @Override 1227 public void onReceive(Context context, Intent intent) { 1228 // on background handler thread, and USER_ADDED and USER_REMOVED 1229 // broadcasts are protected 1230 1231 final String action = intent.getAction(); 1232 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 1233 if (userId == -1) return; 1234 1235 switch (action) { 1236 case ACTION_USER_REMOVED: 1237 case ACTION_USER_ADDED: 1238 synchronized (mUidRulesFirstLock) { 1239 // Remove any persistable state for the given user; both cleaning up after a 1240 // USER_REMOVED, and one last check during USER_ADDED 1241 removeUserStateUL(userId, true, false); 1242 // Removing outside removeUserStateUL since that can also be called when 1243 // user resets app preferences. 1244 mMeteredRestrictedUids.remove(userId); 1245 if (action == ACTION_USER_ADDED) { 1246 // Add apps that are allowed by default. 1247 addDefaultRestrictBackgroundAllowlistUidsUL(userId); 1248 } 1249 // Update global restrict for that user 1250 synchronized (mNetworkPoliciesSecondLock) { 1251 updateRulesForGlobalChangeAL(true); 1252 } 1253 } 1254 break; 1255 } 1256 } 1257 }; 1258 1259 /** 1260 * Listener that watches for {@link NetworkStatsManager} updates, which 1261 * NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}. 1262 */ 1263 private final StatsCallback mStatsCallback = new StatsCallback(); 1264 private class StatsCallback extends NetworkStatsManager.UsageCallback { 1265 private boolean mIsAnyCallbackReceived = false; 1266 1267 @Override onThresholdReached(int networkType, String subscriberId)1268 public void onThresholdReached(int networkType, String subscriberId) { 1269 mIsAnyCallbackReceived = true; 1270 1271 synchronized (mNetworkPoliciesSecondLock) { 1272 updateNetworkRulesNL(); 1273 updateNetworkEnabledNL(); 1274 updateNotificationsNL(); 1275 } 1276 } 1277 1278 /** 1279 * Return whether any callback is received. 1280 * Used to determine if NetworkStatsService is ready. 1281 */ isAnyCallbackReceived()1282 public boolean isAnyCallbackReceived() { 1283 // Warning : threading for this member is broken. It should only be read 1284 // and written on the handler thread ; furthermore, the constructor 1285 // is called on a different thread, so this stops working if the default 1286 // value is not false or if this member ever goes back to false after 1287 // being set to true. 1288 // TODO : fix threading for this member. 1289 return mIsAnyCallbackReceived; 1290 } 1291 }; 1292 1293 /** 1294 * Receiver that watches for {@link Notification} control of 1295 * {@link NetworkPolicy#lastWarningSnooze}. 1296 */ 1297 final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() { 1298 @Override 1299 public void onReceive(Context context, Intent intent) { 1300 // on background handler thread, and verified MANAGE_NETWORK_POLICY 1301 // permission above. 1302 1303 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 1304 if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) { 1305 performSnooze(template, TYPE_WARNING); 1306 } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) { 1307 performSnooze(template, TYPE_RAPID); 1308 } 1309 } 1310 }; 1311 1312 /** 1313 * Receiver that watches for {@link WifiConfiguration} to be loaded so that 1314 * we can perform upgrade logic. After initial upgrade logic, it updates 1315 * {@link #mMeteredIfaces} based on configuration changes. 1316 */ 1317 final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() { 1318 @Override 1319 public void onReceive(Context context, Intent intent) { 1320 upgradeWifiMeteredOverride(); 1321 // Only need to perform upgrade logic once 1322 mContext.unregisterReceiver(this); 1323 } 1324 }; 1325 updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue, Network network)1326 private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue, 1327 Network network) { 1328 final boolean lastValue = lastValues.get(network.getNetId(), false); 1329 final boolean changed = (lastValue != newValue) 1330 || lastValues.indexOfKey(network.getNetId()) < 0; 1331 if (changed) { 1332 lastValues.put(network.getNetId(), newValue); 1333 } 1334 return changed; 1335 } 1336 1337 @GuardedBy("mNetworkPoliciesSecondLock") 1338 private boolean updateNetworkToIfacesNL(int netId, @NonNull ArraySet<String> newIfaces) { 1339 // TODO: Add a facility SparseSetArray.contains(key) to return whether the key exists. 1340 final ArraySet<String> lastIfaces = mNetworkToIfaces.get(netId); 1341 final boolean changed = lastIfaces == null ? true : !lastIfaces.equals(newIfaces); 1342 1343 if (changed) { 1344 // Changed on the same network should remove last ifaces and add new ifaces. 1345 // TODO: Add a facility SparseSetArray.put(key, value) for replacing the 1346 // value for a given key. 1347 mNetworkToIfaces.remove(netId); 1348 for (String iface : newIfaces) { 1349 mNetworkToIfaces.add(netId, iface); 1350 } 1351 } 1352 return changed; 1353 } 1354 1355 private final NetworkCallback mNetworkCallback = new NetworkCallback() { 1356 @Override 1357 public void onCapabilitiesChanged(@NonNull Network network, 1358 @NonNull NetworkCapabilities networkCapabilities) { 1359 1360 synchronized (mNetworkPoliciesSecondLock) { 1361 final boolean newMetered = !networkCapabilities 1362 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1363 final boolean meteredChanged = updateCapabilityChange( 1364 mNetworkMetered, newMetered, network); 1365 1366 final boolean newRoaming = !networkCapabilities 1367 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 1368 final boolean roamingChanged = updateCapabilityChange( 1369 mNetworkRoaming, newRoaming, network); 1370 1371 if (meteredChanged || roamingChanged) { 1372 mLogger.meterednessChanged(network.getNetId(), newMetered); 1373 updateNetworkRulesNL(); 1374 } 1375 } 1376 } 1377 1378 @Override 1379 public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties lp) { 1380 synchronized (mNetworkPoliciesSecondLock) { 1381 final ArraySet<String> newIfaces = new ArraySet<>(lp.getAllInterfaceNames()); 1382 final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(), 1383 newIfaces); 1384 if (ifacesChanged) { 1385 updateNetworkRulesNL(); 1386 } 1387 } 1388 } 1389 1390 @Override 1391 public void onLost(@NonNull Network network) { 1392 synchronized (mNetworkPoliciesSecondLock) { 1393 mNetworkToIfaces.remove(network.getNetId()); 1394 } 1395 } 1396 }; 1397 1398 /** 1399 * Observer that watches for {@link INetworkManagementService} alerts. 1400 */ 1401 final private INetworkManagementEventObserver mAlertObserver 1402 = new BaseNetworkObserver() { 1403 @Override 1404 public void limitReached(String limitName, String iface) { 1405 // only someone like NMS should be calling us 1406 NetworkStack.checkNetworkStackPermission(mContext); 1407 1408 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 1409 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 1410 } 1411 } 1412 }; 1413 1414 /** 1415 * Check {@link NetworkPolicy} against current {@link NetworkStatsManager} 1416 * to show visible notifications as needed. 1417 */ 1418 @GuardedBy("mNetworkPoliciesSecondLock") 1419 void updateNotificationsNL() { 1420 if (LOGV) Slog.v(TAG, "updateNotificationsNL()"); 1421 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNotificationsNL"); 1422 1423 // keep track of previously active notifications 1424 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs); 1425 mActiveNotifs.clear(); 1426 1427 // TODO: when switching to kernel notifications, compute next future 1428 // cycle boundary to recompute notifications. 1429 1430 // examine stats for each active policy 1431 final long now = mClock.millis(); 1432 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1433 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1434 final int subId = findRelevantSubIdNL(policy.template); 1435 1436 // ignore policies that aren't relevant to user 1437 if (subId == INVALID_SUBSCRIPTION_ID) continue; 1438 if (!policy.hasCycle()) continue; 1439 1440 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager 1441 .cycleIterator(policy).next(); 1442 final long cycleStart = cycle.first.toInstant().toEpochMilli(); 1443 final long cycleEnd = cycle.second.toInstant().toEpochMilli(); 1444 final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd); 1445 1446 // Carrier might want to manage notifications themselves 1447 final PersistableBundle config = mSubIdToCarrierConfig.get(subId); 1448 if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) { 1449 if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false"); 1450 // Don't show notifications until we confirm that the loaded config is from an 1451 // identified carrier, which may want to manage their own notifications. This method 1452 // should be called every time the carrier config changes anyways, and there's no 1453 // reason to alert if there isn't a carrier. 1454 continue; 1455 } 1456 1457 final boolean notifyWarning = getBooleanDefeatingNullable(config, 1458 KEY_DATA_WARNING_NOTIFICATION_BOOL, true); 1459 final boolean notifyLimit = getBooleanDefeatingNullable(config, 1460 KEY_DATA_LIMIT_NOTIFICATION_BOOL, true); 1461 final boolean notifyRapid = getBooleanDefeatingNullable(config, 1462 KEY_DATA_RAPID_NOTIFICATION_BOOL, true); 1463 1464 // Notify when data usage is over warning 1465 if (notifyWarning) { 1466 if (policy.isOverWarning(totalBytes) && !policy.isOverLimit(totalBytes)) { 1467 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart; 1468 if (!snoozedThisCycle) { 1469 enqueueNotification(policy, TYPE_WARNING, totalBytes, null); 1470 } 1471 } 1472 } 1473 1474 // Notify when data usage is over limit 1475 if (notifyLimit) { 1476 if (policy.isOverLimit(totalBytes)) { 1477 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart; 1478 if (snoozedThisCycle) { 1479 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null); 1480 } else { 1481 enqueueNotification(policy, TYPE_LIMIT, totalBytes, null); 1482 notifyOverLimitNL(policy.template); 1483 } 1484 } else { 1485 notifyUnderLimitNL(policy.template); 1486 } 1487 } 1488 1489 // Warn if average usage over last 4 days is on track to blow pretty 1490 // far past the plan limits. 1491 if (notifyRapid && policy.limitBytes != LIMIT_DISABLED) { 1492 final long recentDuration = TimeUnit.DAYS.toMillis(4); 1493 final long recentStart = now - recentDuration; 1494 final long recentEnd = now; 1495 final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd); 1496 1497 final long cycleDuration = cycleEnd - cycleStart; 1498 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration; 1499 final long alertBytes = (policy.limitBytes * 3) / 2; 1500 1501 if (LOGD) { 1502 Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected " 1503 + projectedBytes + " alert " + alertBytes); 1504 } 1505 1506 final boolean snoozedRecently = policy.lastRapidSnooze >= now 1507 - DateUtils.DAY_IN_MILLIS; 1508 if (projectedBytes > alertBytes && !snoozedRecently) { 1509 enqueueNotification(policy, TYPE_RAPID, 0, 1510 findRapidBlame(policy.template, recentStart, recentEnd)); 1511 } 1512 } 1513 } 1514 1515 // cancel stale notifications that we didn't renew above 1516 for (int i = beforeNotifs.size()-1; i >= 0; i--) { 1517 final NotificationId notificationId = beforeNotifs.valueAt(i); 1518 if (!mActiveNotifs.contains(notificationId)) { 1519 cancelNotification(notificationId); 1520 } 1521 } 1522 1523 Trace.traceEnd(TRACE_TAG_NETWORK); 1524 } 1525 1526 /** 1527 * Attempt to find a specific app to blame for rapid data usage during the 1528 * given time period. 1529 */ findRapidBlame(NetworkTemplate template, long start, long end)1530 private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template, 1531 long start, long end) { 1532 long totalBytes = 0; 1533 long maxBytes = 0; 1534 int maxUid = 0; 1535 1536 // Skip if not ready. NetworkStatsService will block public API calls until it is 1537 // ready. To prevent NPMS be blocked on that, skip and fail fast instead. 1538 if (!mStatsCallback.isAnyCallbackReceived()) return null; 1539 1540 final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end); 1541 for (final NetworkStats.Bucket entry : stats) { 1542 final long bytes = entry.getRxBytes() + entry.getTxBytes(); 1543 totalBytes += bytes; 1544 if (bytes > maxBytes) { 1545 maxBytes = bytes; 1546 maxUid = entry.getUid(); 1547 } 1548 } 1549 1550 // Only point blame if the majority of usage was done by a single app. 1551 // TODO: support shared UIDs 1552 if (maxBytes > 0 && maxBytes > totalBytes / 2) { 1553 final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid); 1554 if (packageNames != null && packageNames.length == 1) { 1555 try { 1556 return mContext.getPackageManager().getApplicationInfo(packageNames[0], 1557 MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE 1558 | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES); 1559 } catch (NameNotFoundException ignored) { 1560 } 1561 } 1562 } 1563 1564 return null; 1565 } 1566 1567 /** 1568 * Test if given {@link NetworkTemplate} is relevant to user based on 1569 * current device state, such as when 1570 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 1571 * data connection status. 1572 * 1573 * @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no 1574 * matching subId found. 1575 */ 1576 @GuardedBy("mNetworkPoliciesSecondLock") findRelevantSubIdNL(NetworkTemplate template)1577 private int findRelevantSubIdNL(NetworkTemplate template) { 1578 // Carrier template is relevant when any active subscriber matches 1579 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { 1580 final int subId = mSubIdToSubscriberId.keyAt(i); 1581 final String subscriberId = mSubIdToSubscriberId.valueAt(i); 1582 final NetworkIdentity probeIdent = new NetworkIdentity.Builder() 1583 .setType(TYPE_MOBILE) 1584 .setSubscriberId(subscriberId) 1585 .setMetered(true) 1586 .setDefaultNetwork(true) 1587 .setSubId(subId).build(); 1588 if (template.matches(probeIdent)) { 1589 return subId; 1590 } 1591 } 1592 return INVALID_SUBSCRIPTION_ID; 1593 } 1594 1595 /** 1596 * Notify that given {@link NetworkTemplate} is over 1597 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 1598 */ 1599 @GuardedBy("mNetworkPoliciesSecondLock") notifyOverLimitNL(NetworkTemplate template)1600 private void notifyOverLimitNL(NetworkTemplate template) { 1601 if (!mOverLimitNotified.contains(template)) { 1602 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template)); 1603 mOverLimitNotified.add(template); 1604 } 1605 } 1606 1607 @GuardedBy("mNetworkPoliciesSecondLock") notifyUnderLimitNL(NetworkTemplate template)1608 private void notifyUnderLimitNL(NetworkTemplate template) { 1609 mOverLimitNotified.remove(template); 1610 } 1611 1612 /** 1613 * Show notification for combined {@link NetworkPolicy} and specific type, 1614 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 1615 */ enqueueNotification(NetworkPolicy policy, int type, long totalBytes, ApplicationInfo rapidBlame)1616 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes, 1617 ApplicationInfo rapidBlame) { 1618 final NotificationId notificationId = new NotificationId(policy, type); 1619 final Notification.Builder builder = 1620 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS); 1621 builder.setOnlyAlertOnce(true); 1622 builder.setWhen(0L); 1623 builder.setColor(mContext.getColor( 1624 com.android.internal.R.color.system_notification_accent_color)); 1625 1626 final Resources res = mContext.getResources(); 1627 final CharSequence title; 1628 final CharSequence body; 1629 switch (type) { 1630 case TYPE_WARNING: { 1631 title = res.getText(R.string.data_usage_warning_title); 1632 body = res.getString(R.string.data_usage_warning_body, 1633 Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS)); 1634 1635 builder.setSmallIcon(R.drawable.stat_notify_error); 1636 1637 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template, 1638 mContext.getPackageName()); 1639 builder.setDeleteIntent(PendingIntent.getBroadcast( 1640 mContext, 0, snoozeIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1641 1642 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template); 1643 // TODO: Resolve to single code path. 1644 if (UserManager.isHeadlessSystemUserMode()) { 1645 builder.setContentIntent(PendingIntent.getActivityAsUser( 1646 mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, 1647 /* options= */ null, UserHandle.CURRENT)); 1648 } else { 1649 builder.setContentIntent(PendingIntent.getActivity( 1650 mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1651 } 1652 break; 1653 } 1654 case TYPE_LIMIT: { 1655 switch (policy.template.getMatchRule()) { 1656 case MATCH_CARRIER: 1657 case MATCH_MOBILE: 1658 title = res.getText(R.string.data_usage_mobile_limit_title); 1659 break; 1660 case MATCH_WIFI: 1661 title = res.getText(R.string.data_usage_wifi_limit_title); 1662 break; 1663 default: 1664 return; 1665 } 1666 body = res.getText(R.string.data_usage_limit_body); 1667 1668 builder.setOngoing(true); 1669 builder.setSmallIcon(R.drawable.stat_notify_disabled_data); 1670 1671 final Intent intent = buildNetworkOverLimitIntent(res, policy.template); 1672 // TODO: Resolve to single code path. 1673 if (UserManager.isHeadlessSystemUserMode()) { 1674 builder.setContentIntent(PendingIntent.getActivityAsUser( 1675 mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, 1676 /* options= */ null, UserHandle.CURRENT)); 1677 } else { 1678 builder.setContentIntent(PendingIntent.getActivity( 1679 mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1680 } 1681 break; 1682 } 1683 case TYPE_LIMIT_SNOOZED: { 1684 switch (policy.template.getMatchRule()) { 1685 case MATCH_CARRIER: 1686 case MATCH_MOBILE: 1687 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 1688 break; 1689 case MATCH_WIFI: 1690 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 1691 break; 1692 default: 1693 return; 1694 } 1695 final long overBytes = totalBytes - policy.limitBytes; 1696 body = res.getString(R.string.data_usage_limit_snoozed_body, 1697 Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS)); 1698 1699 builder.setOngoing(true); 1700 builder.setSmallIcon(R.drawable.stat_notify_error); 1701 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS); 1702 1703 final Intent intent = buildViewDataUsageIntent(res, policy.template); 1704 // TODO: Resolve to single code path. 1705 if (UserManager.isHeadlessSystemUserMode()) { 1706 builder.setContentIntent(PendingIntent.getActivityAsUser( 1707 mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, 1708 /* options= */ null, UserHandle.CURRENT)); 1709 } else { 1710 builder.setContentIntent(PendingIntent.getActivity( 1711 mContext, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1712 } 1713 break; 1714 } 1715 case TYPE_RAPID: { 1716 title = res.getText(R.string.data_usage_rapid_title); 1717 if (rapidBlame != null) { 1718 body = res.getString(R.string.data_usage_rapid_app_body, 1719 rapidBlame.loadLabel(mContext.getPackageManager())); 1720 } else { 1721 body = res.getString(R.string.data_usage_rapid_body); 1722 } 1723 1724 builder.setSmallIcon(R.drawable.stat_notify_error); 1725 1726 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template, 1727 mContext.getPackageName()); 1728 builder.setDeleteIntent(PendingIntent.getBroadcast( 1729 mContext, 0, snoozeIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1730 1731 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template); 1732 // TODO: Resolve to single code path. 1733 if (UserManager.isHeadlessSystemUserMode()) { 1734 builder.setContentIntent(PendingIntent.getActivityAsUser( 1735 mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, 1736 /* options= */ null, UserHandle.CURRENT)); 1737 } else { 1738 builder.setContentIntent(PendingIntent.getActivity( 1739 mContext, 0, viewIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); 1740 } 1741 break; 1742 } 1743 default: { 1744 return; 1745 } 1746 } 1747 1748 builder.setTicker(title); 1749 builder.setContentTitle(title); 1750 builder.setContentText(body); 1751 builder.setStyle(new Notification.BigTextStyle().bigText(body)); 1752 1753 mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(), 1754 notificationId.getId(), builder.build(), UserHandle.ALL); 1755 mActiveNotifs.add(notificationId); 1756 } 1757 cancelNotification(NotificationId notificationId)1758 private void cancelNotification(NotificationId notificationId) { 1759 mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(), 1760 notificationId.getId()); 1761 } 1762 1763 /** 1764 * Receiver that watches for {@link IConnectivityManager} to claim network 1765 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 1766 */ 1767 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 1768 @Override 1769 public void onReceive(Context context, Intent intent) { 1770 // on background handler thread, and verified NETWORK_STACK 1771 // permission above. 1772 updateNetworksInternal(); 1773 } 1774 }; 1775 updateNetworksInternal()1776 private void updateNetworksInternal() { 1777 // Get all of our cross-process communication with telephony out of 1778 // the way before we acquire internal locks. 1779 updateSubscriptions(); 1780 1781 synchronized (mUidRulesFirstLock) { 1782 synchronized (mNetworkPoliciesSecondLock) { 1783 ensureActiveCarrierPolicyAL(); 1784 normalizePoliciesNL(); 1785 updateNetworkEnabledNL(); 1786 updateNetworkRulesNL(); 1787 updateNotificationsNL(); 1788 } 1789 } 1790 } 1791 1792 @VisibleForTesting updateNetworks()1793 void updateNetworks() throws InterruptedException { 1794 updateNetworksInternal(); 1795 final CountDownLatch latch = new CountDownLatch(1); 1796 mHandler.post(() -> { 1797 latch.countDown(); 1798 }); 1799 latch.await(5, TimeUnit.SECONDS); 1800 } 1801 1802 @VisibleForTesting getHandlerForTesting()1803 Handler getHandlerForTesting() { 1804 return mHandler; 1805 } 1806 1807 /** 1808 * Update carrier policies with data cycle information from {@link CarrierConfigManager} 1809 * if necessary. 1810 * 1811 * @param subId that has its associated NetworkPolicy updated if necessary 1812 * @return if any policies were updated 1813 */ 1814 @GuardedBy("mNetworkPoliciesSecondLock") maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId)1815 private boolean maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId) { 1816 if (LOGV) Slog.v(TAG, "maybeUpdateCarrierPolicyCycleAL()"); 1817 1818 // find and update the carrier NetworkPolicy for this subscriber id 1819 boolean policyUpdated = false; 1820 final NetworkIdentity probeIdent = new NetworkIdentity.Builder() 1821 .setType(TYPE_MOBILE) 1822 .setSubscriberId(subscriberId) 1823 .setMetered(true) 1824 .setDefaultNetwork(true) 1825 .setSubId(subId).build(); 1826 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1827 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1828 if (template.matches(probeIdent)) { 1829 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1830 policyUpdated |= updateDefaultCarrierPolicyAL(subId, policy); 1831 } 1832 } 1833 return policyUpdated; 1834 } 1835 1836 /** 1837 * Returns the cycle day that should be used for a carrier NetworkPolicy. 1838 * 1839 * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable 1840 * to do so, it returns the fallback value. 1841 * 1842 * @param config The CarrierConfig to read the value from. 1843 * @param fallbackCycleDay to return if the CarrierConfig can't be read. 1844 * @return cycleDay to use in the carrier NetworkPolicy. 1845 */ 1846 @VisibleForTesting getCycleDayFromCarrierConfig(@ullable PersistableBundle config, int fallbackCycleDay)1847 int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config, 1848 int fallbackCycleDay) { 1849 if (config == null) { 1850 return fallbackCycleDay; 1851 } 1852 int cycleDay = 1853 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT); 1854 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1855 return fallbackCycleDay; 1856 } 1857 // validate cycleDay value 1858 final Calendar cal = Calendar.getInstance(); 1859 if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) || 1860 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) { 1861 Slog.e(TAG, "Invalid date in " 1862 + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay); 1863 return fallbackCycleDay; 1864 } 1865 return cycleDay; 1866 } 1867 1868 /** 1869 * Returns the warning bytes that should be used for a carrier NetworkPolicy. 1870 * 1871 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable 1872 * to do so, it returns the fallback value. 1873 * 1874 * @param config The CarrierConfig to read the value from. 1875 * @param fallbackWarningBytes to return if the CarrierConfig can't be read. 1876 * @return warningBytes to use in the carrier NetworkPolicy. 1877 */ 1878 @VisibleForTesting getWarningBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackWarningBytes)1879 long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config, 1880 long fallbackWarningBytes) { 1881 if (config == null) { 1882 return fallbackWarningBytes; 1883 } 1884 long warningBytes = 1885 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG); 1886 1887 if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) { 1888 return WARNING_DISABLED; 1889 } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1890 return getPlatformDefaultWarningBytes(); 1891 } else if (warningBytes < 0) { 1892 Slog.e(TAG, "Invalid value in " 1893 + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a " 1894 + "non-negative value but got: " + warningBytes); 1895 return fallbackWarningBytes; 1896 } 1897 1898 return warningBytes; 1899 } 1900 1901 /** 1902 * Returns the limit bytes that should be used for a carrier NetworkPolicy. 1903 * 1904 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable 1905 * to do so, it returns the fallback value. 1906 * 1907 * @param config The CarrierConfig to read the value from. 1908 * @param fallbackLimitBytes to return if the CarrierConfig can't be read. 1909 * @return limitBytes to use in the carrier NetworkPolicy. 1910 */ 1911 @VisibleForTesting getLimitBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackLimitBytes)1912 long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config, 1913 long fallbackLimitBytes) { 1914 if (config == null) { 1915 return fallbackLimitBytes; 1916 } 1917 long limitBytes = 1918 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG); 1919 1920 if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) { 1921 return LIMIT_DISABLED; 1922 } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1923 return getPlatformDefaultLimitBytes(); 1924 } else if (limitBytes < 0) { 1925 Slog.e(TAG, "Invalid value in " 1926 + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a " 1927 + "non-negative value but got: " + limitBytes); 1928 return fallbackLimitBytes; 1929 } 1930 return limitBytes; 1931 } 1932 1933 /** 1934 * Receiver that watches for {@link CarrierConfigManager} to be changed. 1935 */ 1936 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() { 1937 @Override 1938 public void onReceive(Context context, Intent intent) { 1939 // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED 1940 // broadcast is protected and can't be spoofed. Runs on a background handler thread. 1941 1942 if (!intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX)) { 1943 return; 1944 } 1945 final int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1); 1946 1947 // Get all of our cross-process communication with telephony out of 1948 // the way before we acquire internal locks. 1949 updateSubscriptions(); 1950 1951 synchronized (mUidRulesFirstLock) { 1952 synchronized (mNetworkPoliciesSecondLock) { 1953 final String subscriberId = mSubIdToSubscriberId.get(subId, null); 1954 if (subscriberId != null) { 1955 ensureActiveCarrierPolicyAL(subId, subscriberId); 1956 maybeUpdateCarrierPolicyCycleAL(subId, subscriberId); 1957 } else { 1958 Slog.wtf(TAG, "Missing subscriberId for subId " + subId); 1959 } 1960 1961 // update network and notification rules, as the data cycle changed and it's 1962 // possible that we should be triggering warnings/limits now 1963 handleNetworkPoliciesUpdateAL(true); 1964 } 1965 } 1966 } 1967 }; 1968 1969 /** 1970 * Handles all tasks that need to be run after a new network policy has been set, or an existing 1971 * one has been updated. 1972 * 1973 * @param shouldNormalizePolicies true iff network policies need to be normalized after the 1974 * update. 1975 */ 1976 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies)1977 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) { 1978 if (shouldNormalizePolicies) { 1979 normalizePoliciesNL(); 1980 } 1981 updateNetworkEnabledNL(); 1982 updateNetworkRulesNL(); 1983 updateNotificationsNL(); 1984 writePolicyAL(); 1985 } 1986 1987 /** 1988 * Proactively control network data connections when they exceed 1989 * {@link NetworkPolicy#limitBytes}. 1990 */ 1991 @GuardedBy("mNetworkPoliciesSecondLock") updateNetworkEnabledNL()1992 void updateNetworkEnabledNL() { 1993 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()"); 1994 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkEnabledNL"); 1995 1996 // TODO: reset any policy-disabled networks when any policy is removed 1997 // completely, which is currently rare case. 1998 1999 final long startTime = mStatLogger.getTime(); 2000 2001 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2002 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2003 // shortcut when policy has no limit 2004 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 2005 setNetworkTemplateEnabled(policy.template, true); 2006 continue; 2007 } 2008 2009 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager 2010 .cycleIterator(policy).next(); 2011 final long start = cycle.first.toInstant().toEpochMilli(); 2012 final long end = cycle.second.toInstant().toEpochMilli(); 2013 final long totalBytes = getTotalBytes(policy.template, start, end); 2014 2015 // disable data connection when over limit and not snoozed 2016 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 2017 && policy.lastLimitSnooze < start; 2018 final boolean networkEnabled = !overLimitWithoutSnooze; 2019 2020 setNetworkTemplateEnabled(policy.template, networkEnabled); 2021 } 2022 2023 mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime); 2024 Trace.traceEnd(TRACE_TAG_NETWORK); 2025 } 2026 2027 /** 2028 * Proactively disable networks that match the given 2029 * {@link NetworkTemplate}. 2030 */ 2031 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 2032 // Don't call setNetworkTemplateEnabledInner() directly because we may have a lock 2033 // held. Call it via the handler. 2034 mHandler.obtainMessage(MSG_SET_NETWORK_TEMPLATE_ENABLED, enabled ? 1 : 0, 0, template) 2035 .sendToTarget(); 2036 } 2037 2038 private void setNetworkTemplateEnabledInner(NetworkTemplate template, boolean enabled) { 2039 // TODO: reach into ConnectivityManager to proactively disable bringing 2040 // up this network, since we know that traffic will be blocked. 2041 2042 if (template.getMatchRule() == MATCH_MOBILE 2043 || template.getMatchRule() == MATCH_CARRIER) { 2044 // If carrier data usage hits the limit or if the user resumes the data, we need to 2045 // notify telephony. 2046 2047 // TODO: It needs to check if it matches the merged WIFI and notify to wifi module. 2048 final IntArray matchingSubIds = new IntArray(); 2049 synchronized (mNetworkPoliciesSecondLock) { 2050 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { 2051 final int subId = mSubIdToSubscriberId.keyAt(i); 2052 final String subscriberId = mSubIdToSubscriberId.valueAt(i); 2053 final NetworkIdentity probeIdent = new NetworkIdentity.Builder() 2054 .setType(TYPE_MOBILE) 2055 .setSubscriberId(subscriberId) 2056 .setMetered(true) 2057 .setDefaultNetwork(true) 2058 .setSubId(subId).build(); 2059 // Template is matched when subscriber id matches. 2060 if (template.matches(probeIdent)) { 2061 matchingSubIds.add(subId); 2062 } 2063 } 2064 } 2065 2066 // Only talk with telephony outside of locks 2067 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 2068 for (int i = 0; i < matchingSubIds.size(); i++) { 2069 final int subId = matchingSubIds.get(i); 2070 tm.createForSubscriptionId(subId).setPolicyDataEnabled(enabled); 2071 } 2072 } 2073 } 2074 2075 /** 2076 * Collect all ifaces from a {@link NetworkStateSnapshot} into the given set. 2077 */ 2078 private static void collectIfaces(ArraySet<String> ifaces, NetworkStateSnapshot snapshot) { 2079 ifaces.addAll(snapshot.getLinkProperties().getAllInterfaceNames()); 2080 } 2081 2082 /** 2083 * Examine all currently active subscriptions from 2084 * {@link SubscriptionManager#getActiveSubscriptionInfoList()} and update 2085 * internal data structures. 2086 * <p> 2087 * Callers <em>must not</em> hold any locks when this method called. 2088 */ 2089 void updateSubscriptions() { 2090 if (LOGV) Slog.v(TAG, "updateSubscriptions()"); 2091 Trace.traceBegin(TRACE_TAG_NETWORK, "updateSubscriptions"); 2092 2093 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 2094 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class); 2095 final List<SubscriptionInfo> subList = CollectionUtils.emptyIfNull( 2096 sm.getActiveSubscriptionInfoList()); 2097 2098 final List<String[]> mergedSubscriberIdsList = new ArrayList(); 2099 final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subList.size()); 2100 final SparseArray<PersistableBundle> subIdToCarrierConfig = 2101 new SparseArray<PersistableBundle>(); 2102 for (final SubscriptionInfo sub : subList) { 2103 final int subId = sub.getSubscriptionId(); 2104 final TelephonyManager tmSub = tm.createForSubscriptionId(subId); 2105 final String subscriberId = tmSub.getSubscriberId(); 2106 if (!TextUtils.isEmpty(subscriberId)) { 2107 subIdToSubscriberId.put(tmSub.getSubscriptionId(), subscriberId); 2108 } else { 2109 Slog.wtf(TAG, "Missing subscriberId for subId " + tmSub.getSubscriptionId()); 2110 } 2111 2112 final String[] mergedSubscriberId = ArrayUtils.defeatNullable( 2113 tmSub.getMergedImsisFromGroup()); 2114 mergedSubscriberIdsList.add(mergedSubscriberId); 2115 2116 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); 2117 if (config != null) { 2118 subIdToCarrierConfig.put(subId, config); 2119 } else { 2120 Slog.e(TAG, "Missing CarrierConfig for subId " + subId); 2121 } 2122 } 2123 2124 synchronized (mNetworkPoliciesSecondLock) { 2125 mSubIdToSubscriberId.clear(); 2126 for (int i = 0; i < subIdToSubscriberId.size(); i++) { 2127 mSubIdToSubscriberId.put(subIdToSubscriberId.keyAt(i), 2128 subIdToSubscriberId.valueAt(i)); 2129 } 2130 2131 mMergedSubscriberIds = mergedSubscriberIdsList; 2132 2133 mSubIdToCarrierConfig.clear(); 2134 for (int i = 0; i < subIdToCarrierConfig.size(); i++) { 2135 mSubIdToCarrierConfig.put(subIdToCarrierConfig.keyAt(i), 2136 subIdToCarrierConfig.valueAt(i)); 2137 } 2138 } 2139 2140 Trace.traceEnd(TRACE_TAG_NETWORK); 2141 } 2142 2143 /** 2144 * Examine all connected {@link NetworkStateSnapshot}, looking for 2145 * {@link NetworkPolicy} that need to be enforced. When matches found, set 2146 * remaining quota based on usage cycle and historical stats. 2147 */ 2148 @GuardedBy("mNetworkPoliciesSecondLock") 2149 void updateNetworkRulesNL() { 2150 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()"); 2151 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL"); 2152 2153 final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshots(); 2154 2155 // First, generate identities of all connected networks so we can 2156 // quickly compare them against all defined policies below. 2157 mNetIdToSubId.clear(); 2158 final ArrayMap<NetworkStateSnapshot, NetworkIdentity> identified = new ArrayMap<>(); 2159 for (final NetworkStateSnapshot snapshot : snapshots) { 2160 final int subId = snapshot.getSubId(); 2161 mNetIdToSubId.put(snapshot.getNetwork().getNetId(), subId); 2162 2163 // Policies matched by NPMS only match by subscriber ID or by network ID. 2164 final NetworkIdentity ident = new NetworkIdentity.Builder() 2165 .setNetworkStateSnapshot(snapshot).setDefaultNetwork(true).build(); 2166 identified.put(snapshot, ident); 2167 } 2168 2169 final ArraySet<String> newMeteredIfaces = new ArraySet<>(); 2170 long lowestRule = Long.MAX_VALUE; 2171 2172 // For every well-defined policy, compute remaining data based on 2173 // current cycle and historical stats, and push to kernel. 2174 final ArraySet<String> matchingIfaces = new ArraySet<>(); 2175 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 2176 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2177 2178 // Collect all ifaces that match this policy 2179 matchingIfaces.clear(); 2180 for (int j = identified.size() - 1; j >= 0; j--) { 2181 if (policy.template.matches(identified.valueAt(j))) { 2182 collectIfaces(matchingIfaces, identified.keyAt(j)); 2183 } 2184 } 2185 2186 if (LOGD) { 2187 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces); 2188 } 2189 2190 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 2191 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 2192 long limitBytes = Long.MAX_VALUE; 2193 long warningBytes = Long.MAX_VALUE; 2194 if ((hasLimit || hasWarning) && policy.hasCycle()) { 2195 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager 2196 .cycleIterator(policy).next(); 2197 final long start = cycle.first.toInstant().toEpochMilli(); 2198 final long end = cycle.second.toInstant().toEpochMilli(); 2199 final long totalBytes = getTotalBytes(policy.template, start, end); 2200 2201 // If the limit notification is not snoozed, the limit quota needs to be calculated. 2202 if (hasLimit && policy.lastLimitSnooze < start) { 2203 // remaining "quota" bytes are based on total usage in 2204 // current cycle. kernel doesn't like 0-byte rules, so we 2205 // set 1-byte quota and disable the radio later. 2206 limitBytes = Math.max(1, policy.limitBytes - totalBytes); 2207 } 2208 2209 // If the warning notification was snoozed by user, or the service already knows 2210 // it is over warning bytes, doesn't need to calculate warning bytes. 2211 if (hasWarning && policy.lastWarningSnooze < start 2212 && !policy.isOverWarning(totalBytes)) { 2213 warningBytes = Math.max(1, policy.warningBytes - totalBytes); 2214 } 2215 } 2216 2217 if (hasWarning || hasLimit || policy.metered) { 2218 if (matchingIfaces.size() > 1) { 2219 // TODO: switch to shared quota once NMS supports 2220 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 2221 } 2222 2223 // Set the interface warning and limit. For interfaces which has no cycle, 2224 // or metered with no policy quotas, or snoozed notification; we still need to put 2225 // iptables rule hooks to restrict apps for data saver, so push really high quota. 2226 // TODO: Push NetworkStatsProvider.QUOTA_UNLIMITED instead of Long.MAX_VALUE to 2227 // providers. 2228 for (int j = matchingIfaces.size() - 1; j >= 0; j--) { 2229 final String iface = matchingIfaces.valueAt(j); 2230 setInterfaceQuotasAsync(iface, warningBytes, limitBytes); 2231 newMeteredIfaces.add(iface); 2232 } 2233 } 2234 2235 // keep track of lowest warning or limit of active policies 2236 if (hasWarning && policy.warningBytes < lowestRule) { 2237 lowestRule = policy.warningBytes; 2238 } 2239 if (hasLimit && policy.limitBytes < lowestRule) { 2240 lowestRule = policy.limitBytes; 2241 } 2242 } 2243 2244 // One final pass to catch any metered ifaces that don't have explicitly 2245 // defined policies; typically Wi-Fi networks. 2246 for (final NetworkStateSnapshot snapshot : snapshots) { 2247 if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)) { 2248 matchingIfaces.clear(); 2249 collectIfaces(matchingIfaces, snapshot); 2250 for (int j = matchingIfaces.size() - 1; j >= 0; j--) { 2251 final String iface = matchingIfaces.valueAt(j); 2252 if (!newMeteredIfaces.contains(iface)) { 2253 setInterfaceQuotasAsync(iface, Long.MAX_VALUE, Long.MAX_VALUE); 2254 newMeteredIfaces.add(iface); 2255 } 2256 } 2257 } 2258 } 2259 2260 // Remove quota from any interfaces that are no longer metered. 2261 synchronized (mMeteredIfacesLock) { 2262 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) { 2263 final String iface = mMeteredIfaces.valueAt(i); 2264 if (!newMeteredIfaces.contains(iface)) { 2265 removeInterfaceQuotasAsync(iface); 2266 } 2267 } 2268 mMeteredIfaces = newMeteredIfaces; 2269 } 2270 2271 final ContentResolver cr = mContext.getContentResolver(); 2272 final boolean quotaEnabled = Settings.Global.getInt(cr, 2273 NETPOLICY_QUOTA_ENABLED, 1) != 0; 2274 final long quotaUnlimited = Settings.Global.getLong(cr, 2275 NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT); 2276 final float quotaLimited = Settings.Global.getFloat(cr, 2277 NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT); 2278 2279 // Finally, calculate our opportunistic quotas 2280 mSubscriptionOpportunisticQuota.clear(); 2281 for (final NetworkStateSnapshot snapshot : snapshots) { 2282 if (!quotaEnabled) continue; 2283 if (snapshot.getNetwork() == null) continue; 2284 final int subId = getSubIdLocked(snapshot.getNetwork()); 2285 if (subId == INVALID_SUBSCRIPTION_ID) continue; 2286 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId); 2287 if (plan == null) continue; 2288 2289 final long quotaBytes; 2290 final long limitBytes = plan.getDataLimitBytes(); 2291 if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_ROAMING)) { 2292 // Clamp to 0 when roaming 2293 quotaBytes = 0; 2294 } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) { 2295 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN; 2296 } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) { 2297 // Unlimited data; let's use 20MiB/day (600MiB/month) 2298 quotaBytes = quotaUnlimited; 2299 } else { 2300 // Limited data; let's only use 10% of remaining budget 2301 final Range<ZonedDateTime> cycle = plan.cycleIterator().next(); 2302 final long start = cycle.getLower().toInstant().toEpochMilli(); 2303 final long end = cycle.getUpper().toInstant().toEpochMilli(); 2304 final Instant now = mClock.instant(); 2305 final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone()) 2306 .truncatedTo(ChronoUnit.DAYS) 2307 .toInstant().toEpochMilli(); 2308 final String subscriberId = snapshot.getSubscriberId(); 2309 final long totalBytes = subscriberId == null 2310 ? 0 : getTotalBytes( 2311 buildTemplateCarrierMetered(subscriberId), start, startOfDay); 2312 final long remainingBytes = limitBytes - totalBytes; 2313 // Number of remaining days including current day 2314 final long remainingDays = 2315 1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1)); 2316 2317 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited)); 2318 } 2319 2320 mSubscriptionOpportunisticQuota.put(subId, quotaBytes); 2321 } 2322 2323 final String[] meteredIfaces; 2324 synchronized (mMeteredIfacesLock) { 2325 meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 2326 } 2327 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 2328 2329 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 2330 2331 Trace.traceEnd(TRACE_TAG_NETWORK); 2332 } 2333 2334 /** 2335 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 2336 * have at least a default carrier policy defined. 2337 */ 2338 @GuardedBy("mNetworkPoliciesSecondLock") 2339 private void ensureActiveCarrierPolicyAL() { 2340 if (LOGV) Slog.v(TAG, "ensureActiveCarrierPolicyAL()"); 2341 if (mSuppressDefaultPolicy) return; 2342 2343 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { 2344 final int subId = mSubIdToSubscriberId.keyAt(i); 2345 final String subscriberId = mSubIdToSubscriberId.valueAt(i); 2346 2347 ensureActiveCarrierPolicyAL(subId, subscriberId); 2348 } 2349 } 2350 2351 /** 2352 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 2353 * have at least a default carrier policy defined. 2354 * 2355 * @param subId to build a default policy for 2356 * @param subscriberId that we check for an existing policy 2357 * @return true if a carrier network policy was added, or false one already existed. 2358 */ 2359 @GuardedBy("mNetworkPoliciesSecondLock") 2360 private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) { 2361 // Poke around to see if we already have a policy 2362 final NetworkIdentity probeIdent = new NetworkIdentity.Builder() 2363 .setType(TYPE_MOBILE) 2364 .setSubscriberId(subscriberId) 2365 .setMetered(true) 2366 .setDefaultNetwork(true) 2367 .setSubId(subId).build(); 2368 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 2369 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 2370 if (template.matches(probeIdent)) { 2371 if (LOGD) { 2372 Slog.d(TAG, "Found template " + template + " which matches subscriber " 2373 + NetworkIdentityUtils.scrubSubscriberId(subscriberId)); 2374 } 2375 return false; 2376 } 2377 } 2378 2379 Slog.i(TAG, "No policy for subscriber " 2380 + NetworkIdentityUtils.scrubSubscriberId(subscriberId) 2381 + "; generating default policy"); 2382 final NetworkPolicy policy = buildDefaultCarrierPolicy(subId, subscriberId); 2383 addNetworkPolicyAL(policy); 2384 return true; 2385 } 2386 2387 private long getPlatformDefaultWarningBytes() { 2388 final int dataWarningConfig = mContext.getResources().getInteger( 2389 com.android.internal.R.integer.config_networkPolicyDefaultWarning); 2390 if (dataWarningConfig == WARNING_DISABLED) { 2391 return WARNING_DISABLED; 2392 } else { 2393 return DataUnit.MEBIBYTES.toBytes(dataWarningConfig); 2394 } 2395 } 2396 2397 private long getPlatformDefaultLimitBytes() { 2398 return LIMIT_DISABLED; 2399 } 2400 2401 @VisibleForTesting 2402 NetworkPolicy buildDefaultCarrierPolicy(int subId, String subscriberId) { 2403 final NetworkTemplate template = buildTemplateCarrierMetered(subscriberId); 2404 final RecurrenceRule cycleRule = NetworkPolicy 2405 .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault()); 2406 final NetworkPolicy policy = new NetworkPolicy(template, cycleRule, 2407 getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(), 2408 SNOOZE_NEVER, SNOOZE_NEVER, true, true); 2409 synchronized (mUidRulesFirstLock) { 2410 synchronized (mNetworkPoliciesSecondLock) { 2411 updateDefaultCarrierPolicyAL(subId, policy); 2412 } 2413 } 2414 return policy; 2415 } 2416 2417 /** 2418 * Template to match all metered carrier networks with the given IMSI. 2419 * 2420 * @hide 2421 */ 2422 public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) { 2423 Objects.requireNonNull(subscriberId); 2424 return new NetworkTemplate.Builder(MATCH_CARRIER) 2425 .setSubscriberIds(Set.of(subscriberId)) 2426 .setMeteredness(METERED_YES).build(); 2427 } 2428 2429 /** 2430 * Update the given {@link NetworkPolicy} based on any carrier-provided 2431 * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}. 2432 * Leaves policy untouched if the user has modified it. 2433 * 2434 * @return if the policy was modified 2435 */ 2436 @GuardedBy("mNetworkPoliciesSecondLock") 2437 private boolean updateDefaultCarrierPolicyAL(int subId, NetworkPolicy policy) { 2438 if (!policy.inferred) { 2439 if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy); 2440 return false; 2441 } 2442 2443 final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule, 2444 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze, 2445 policy.lastLimitSnooze, policy.metered, policy.inferred); 2446 2447 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId); 2448 if (!ArrayUtils.isEmpty(plans)) { 2449 final SubscriptionPlan plan = plans[0]; 2450 policy.cycleRule = plan.getCycleRule(); 2451 final long planLimitBytes = plan.getDataLimitBytes(); 2452 if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) { 2453 policy.warningBytes = getPlatformDefaultWarningBytes(); 2454 policy.limitBytes = getPlatformDefaultLimitBytes(); 2455 } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) { 2456 policy.warningBytes = NetworkPolicy.WARNING_DISABLED; 2457 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 2458 } else { 2459 policy.warningBytes = (planLimitBytes * 9) / 10; 2460 switch (plan.getDataLimitBehavior()) { 2461 case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED: 2462 case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED: 2463 policy.limitBytes = planLimitBytes; 2464 break; 2465 default: 2466 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 2467 break; 2468 } 2469 } 2470 } else { 2471 final PersistableBundle config = mSubIdToCarrierConfig.get(subId); 2472 final int currentCycleDay; 2473 if (policy.cycleRule.isMonthly()) { 2474 currentCycleDay = policy.cycleRule.start.getDayOfMonth(); 2475 } else { 2476 currentCycleDay = NetworkPolicy.CYCLE_NONE; 2477 } 2478 final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay); 2479 policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault()); 2480 policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes); 2481 policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes); 2482 } 2483 2484 if (policy.equals(original)) { 2485 return false; 2486 } else { 2487 Slog.d(TAG, "Updated " + original + " to " + policy); 2488 return true; 2489 } 2490 } 2491 2492 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) 2493 private void readPolicyAL() { 2494 if (LOGV) Slog.v(TAG, "readPolicyAL()"); 2495 2496 // clear any existing policy and read from disk 2497 mNetworkPolicy.clear(); 2498 mSubscriptionPlans.clear(); 2499 mSubscriptionPlansOwner.clear(); 2500 mUidPolicy.clear(); 2501 2502 FileInputStream fis = null; 2503 try { 2504 fis = mPolicyFile.openRead(); 2505 final TypedXmlPullParser in = Xml.resolvePullParser(fis); 2506 2507 // Must save the <restrict-background> tags and convert them to <uid-policy> later, 2508 // to skip UIDs that were explicitly denied. 2509 final SparseBooleanArray restrictBackgroundAllowedUids = new SparseBooleanArray(); 2510 2511 int type; 2512 int version = VERSION_INIT; 2513 boolean insideAllowlist = false; 2514 while ((type = in.next()) != END_DOCUMENT) { 2515 final String tag = in.getName(); 2516 if (type == START_TAG) { 2517 if (TAG_POLICY_LIST.equals(tag)) { 2518 final boolean oldValue = mRestrictBackground; 2519 version = readIntAttribute(in, ATTR_VERSION); 2520 mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND) 2521 && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND); 2522 } else if (TAG_NETWORK_POLICY.equals(tag)) { 2523 int templateType = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 2524 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 2525 final String networkId; 2526 final int subscriberIdMatchRule; 2527 final int templateMeteredness; 2528 if (version >= VERSION_ADDED_NETWORK_ID) { 2529 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 2530 } else { 2531 networkId = null; 2532 } 2533 2534 if (version >= VERSION_SUPPORTED_CARRIER_USAGE) { 2535 subscriberIdMatchRule = readIntAttribute(in, 2536 ATTR_SUBSCRIBER_ID_MATCH_RULE); 2537 templateMeteredness = readIntAttribute(in, ATTR_TEMPLATE_METERED); 2538 2539 } else { 2540 subscriberIdMatchRule = 2541 NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT; 2542 if (templateType == MATCH_MOBILE) { 2543 Log.d(TAG, "Update template match rule from mobile to carrier and" 2544 + " force to metered"); 2545 templateType = MATCH_CARRIER; 2546 templateMeteredness = METERED_YES; 2547 } else { 2548 templateMeteredness = METERED_ALL; 2549 } 2550 } 2551 final RecurrenceRule cycleRule; 2552 if (version >= VERSION_ADDED_CYCLE) { 2553 final String start = readStringAttribute(in, ATTR_CYCLE_START); 2554 final String end = readStringAttribute(in, ATTR_CYCLE_END); 2555 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD); 2556 cycleRule = new RecurrenceRule( 2557 RecurrenceRule.convertZonedDateTime(start), 2558 RecurrenceRule.convertZonedDateTime(end), 2559 RecurrenceRule.convertPeriod(period)); 2560 } else { 2561 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 2562 final String cycleTimezone; 2563 if (version >= VERSION_ADDED_TIMEZONE) { 2564 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 2565 } else { 2566 cycleTimezone = "UTC"; 2567 } 2568 cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone)); 2569 } 2570 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 2571 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 2572 final long lastLimitSnooze; 2573 if (version >= VERSION_SPLIT_SNOOZE) { 2574 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 2575 } else if (version >= VERSION_ADDED_SNOOZE) { 2576 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 2577 } else { 2578 lastLimitSnooze = SNOOZE_NEVER; 2579 } 2580 final boolean metered; 2581 if (version >= VERSION_ADDED_METERED) { 2582 metered = readBooleanAttribute(in, ATTR_METERED); 2583 } else { 2584 switch (templateType) { 2585 case MATCH_MOBILE: 2586 metered = true; 2587 break; 2588 default: 2589 metered = false; 2590 } 2591 } 2592 final long lastWarningSnooze; 2593 if (version >= VERSION_SPLIT_SNOOZE) { 2594 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 2595 } else { 2596 lastWarningSnooze = SNOOZE_NEVER; 2597 } 2598 final boolean inferred; 2599 if (version >= VERSION_ADDED_INFERRED) { 2600 inferred = readBooleanAttribute(in, ATTR_INFERRED); 2601 } else { 2602 inferred = false; 2603 } 2604 final NetworkTemplate.Builder builder = 2605 new NetworkTemplate.Builder(templateType) 2606 .setMeteredness(templateMeteredness); 2607 if (subscriberIdMatchRule 2608 == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT) { 2609 final ArraySet<String> ids = new ArraySet<>(); 2610 ids.add(subscriberId); 2611 builder.setSubscriberIds(ids); 2612 } 2613 if (networkId != null) { 2614 builder.setWifiNetworkKeys(Set.of(networkId)); 2615 } 2616 final NetworkTemplate template = builder.build(); 2617 if (NetworkPolicy.isTemplatePersistable(template)) { 2618 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule, 2619 warningBytes, limitBytes, lastWarningSnooze, 2620 lastLimitSnooze, metered, inferred)); 2621 } 2622 } else if (TAG_UID_POLICY.equals(tag)) { 2623 final int uid = readIntAttribute(in, ATTR_UID); 2624 final int policy = readIntAttribute(in, ATTR_POLICY); 2625 2626 if (UserHandle.isApp(uid)) { 2627 setUidPolicyUncheckedUL(uid, policy, false); 2628 } else { 2629 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 2630 } 2631 } else if (TAG_APP_POLICY.equals(tag)) { 2632 final int appId = readIntAttribute(in, ATTR_APP_ID); 2633 final int policy = readIntAttribute(in, ATTR_POLICY); 2634 2635 // TODO: set for other users during upgrade 2636 // app policy is deprecated so this is only used in pre system user split. 2637 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId); 2638 if (UserHandle.isApp(uid)) { 2639 setUidPolicyUncheckedUL(uid, policy, false); 2640 } else { 2641 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 2642 } 2643 } else if (TAG_WHITELIST.equals(tag)) { 2644 insideAllowlist = true; 2645 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) { 2646 final int uid = readIntAttribute(in, ATTR_UID); 2647 restrictBackgroundAllowedUids.append(uid, true); 2648 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) { 2649 final int uid = readIntAttribute(in, ATTR_UID); 2650 mRestrictBackgroundAllowlistRevokedUids.put(uid, true); 2651 } 2652 } else if (type == END_TAG) { 2653 if (TAG_WHITELIST.equals(tag)) { 2654 insideAllowlist = false; 2655 } 2656 2657 } 2658 } 2659 2660 final int size = restrictBackgroundAllowedUids.size(); 2661 for (int i = 0; i < size; i++) { 2662 final int uid = restrictBackgroundAllowedUids.keyAt(i); 2663 final int policy = mUidPolicy.get(uid, POLICY_NONE); 2664 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) { Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid + " because its policy is " + uidPoliciesToString(policy))2665 Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid 2666 + " because its policy is " + uidPoliciesToString(policy)); 2667 continue; 2668 } 2669 if (UserHandle.isApp(uid)) { 2670 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND; 2671 if (LOGV) Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy))2672 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy)); setUidPolicyUncheckedUL(uid, newPolicy, false)2673 setUidPolicyUncheckedUL(uid, newPolicy, false); 2674 } else { Slog.w(TAG, "unable to update policy on UID " + uid)2675 Slog.w(TAG, "unable to update policy on UID " + uid); 2676 } 2677 } 2678 2679 } catch (FileNotFoundException e) { 2680 // missing policy is okay, probably first boot 2681 upgradeDefaultBackgroundDataUL(); 2682 } catch (Exception e) { 2683 Log.wtf(TAG, "problem reading network policy", e); 2684 } finally { 2685 IoUtils.closeQuietly(fis); 2686 } 2687 } 2688 2689 /** 2690 * Upgrade legacy background data flags, notifying listeners of one last 2691 * change to always-true. 2692 */ 2693 private void upgradeDefaultBackgroundDataUL() { 2694 // This method is only called when we're unable to find the network policy flag, which 2695 // usually happens on first boot of a new device and not one that has received an OTA. 2696 2697 // Seed from the default value configured for this device. 2698 mLoadedRestrictBackground = Settings.Global.getInt( 2699 mContext.getContentResolver(), Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 0) == 1; 2700 2701 // NOTE: We used to read the legacy setting here : 2702 // 2703 // final int legacyFlagValue = Settings.Secure.getInt( 2704 // mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..); 2705 // 2706 // This is no longer necessary because we will never upgrade directly from Gingerbread 2707 // to O+. Devices upgrading from ICS onwards to O will have a netpolicy.xml file that 2708 // contains the correct value that we will continue to use. 2709 } 2710 2711 /** 2712 * Perform upgrade step of moving any user-defined meterness overrides over 2713 * into {@link WifiConfiguration}. 2714 */ 2715 private void upgradeWifiMeteredOverride() { 2716 final ArrayMap<String, Boolean> wifiNetworkKeys = new ArrayMap<>(); 2717 synchronized (mNetworkPoliciesSecondLock) { 2718 for (int i = 0; i < mNetworkPolicy.size();) { 2719 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2720 if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI 2721 && !policy.inferred) { 2722 mNetworkPolicy.removeAt(i); 2723 final Set<String> keys = policy.template.getWifiNetworkKeys(); 2724 wifiNetworkKeys.put(keys.isEmpty() ? null : keys.iterator().next(), 2725 policy.metered); 2726 } else { 2727 i++; 2728 } 2729 } 2730 } 2731 2732 if (wifiNetworkKeys.isEmpty()) { 2733 return; 2734 } 2735 final WifiManager wm = mContext.getSystemService(WifiManager.class); 2736 final List<WifiConfiguration> configs = wm.getConfiguredNetworks(); 2737 for (int i = 0; i < configs.size(); ++i) { 2738 final WifiConfiguration config = configs.get(i); 2739 for (String key : config.getAllNetworkKeys()) { 2740 final Boolean metered = wifiNetworkKeys.get(key); 2741 if (metered != null) { 2742 Slog.d(TAG, "Found network " + key + "; upgrading metered hint"); 2743 config.meteredOverride = metered 2744 ? WifiConfiguration.METERED_OVERRIDE_METERED 2745 : WifiConfiguration.METERED_OVERRIDE_NOT_METERED; 2746 wm.updateNetwork(config); 2747 break; 2748 } 2749 } 2750 } 2751 2752 synchronized (mUidRulesFirstLock) { 2753 synchronized (mNetworkPoliciesSecondLock) { 2754 writePolicyAL(); 2755 } 2756 } 2757 } 2758 2759 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) 2760 void writePolicyAL() { 2761 if (LOGV) Slog.v(TAG, "writePolicyAL()"); 2762 2763 FileOutputStream fos = null; 2764 try { 2765 fos = mPolicyFile.startWrite(); 2766 2767 TypedXmlSerializer out = Xml.resolveSerializer(fos); 2768 out.startDocument(null, true); 2769 2770 out.startTag(null, TAG_POLICY_LIST); 2771 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 2772 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 2773 2774 // write all known network policies 2775 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2776 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2777 final NetworkTemplate template = policy.template; 2778 if (!NetworkPolicy.isTemplatePersistable(template)) continue; 2779 2780 out.startTag(null, TAG_NETWORK_POLICY); 2781 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 2782 final String subscriberId = template.getSubscriberIds().isEmpty() ? null 2783 : template.getSubscriberIds().iterator().next(); 2784 if (subscriberId != null) { 2785 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 2786 } 2787 final int subscriberIdMatchRule = template.getSubscriberIds().isEmpty() 2788 ? NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL 2789 : NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT; 2790 writeIntAttribute(out, ATTR_SUBSCRIBER_ID_MATCH_RULE, subscriberIdMatchRule); 2791 if (!template.getWifiNetworkKeys().isEmpty()) { 2792 out.attribute(null, ATTR_NETWORK_ID, 2793 template.getWifiNetworkKeys().iterator().next()); 2794 } 2795 writeIntAttribute(out, ATTR_TEMPLATE_METERED, 2796 template.getMeteredness()); 2797 writeStringAttribute(out, ATTR_CYCLE_START, 2798 RecurrenceRule.convertZonedDateTime(policy.cycleRule.start)); 2799 writeStringAttribute(out, ATTR_CYCLE_END, 2800 RecurrenceRule.convertZonedDateTime(policy.cycleRule.end)); 2801 writeStringAttribute(out, ATTR_CYCLE_PERIOD, 2802 RecurrenceRule.convertPeriod(policy.cycleRule.period)); 2803 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 2804 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 2805 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 2806 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 2807 writeBooleanAttribute(out, ATTR_METERED, policy.metered); 2808 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 2809 out.endTag(null, TAG_NETWORK_POLICY); 2810 } 2811 2812 // write all known uid policies 2813 for (int i = 0; i < mUidPolicy.size(); i++) { 2814 final int uid = mUidPolicy.keyAt(i); 2815 final int policy = mUidPolicy.valueAt(i); 2816 2817 // skip writing empty policies 2818 if (policy == POLICY_NONE) continue; 2819 2820 out.startTag(null, TAG_UID_POLICY); 2821 writeIntAttribute(out, ATTR_UID, uid); 2822 writeIntAttribute(out, ATTR_POLICY, policy); 2823 out.endTag(null, TAG_UID_POLICY); 2824 } 2825 2826 out.endTag(null, TAG_POLICY_LIST); 2827 2828 // write all allowlists 2829 out.startTag(null, TAG_WHITELIST); 2830 2831 // revoked restrict background allowlist 2832 int size = mRestrictBackgroundAllowlistRevokedUids.size(); 2833 for (int i = 0; i < size; i++) { 2834 final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i); 2835 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 2836 writeIntAttribute(out, ATTR_UID, uid); 2837 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 2838 } 2839 2840 out.endTag(null, TAG_WHITELIST); 2841 2842 out.endDocument(); 2843 2844 mPolicyFile.finishWrite(fos); 2845 } catch (IOException e) { 2846 if (fos != null) { 2847 mPolicyFile.failWrite(fos); 2848 } 2849 } 2850 } 2851 2852 @Override 2853 public void setUidPolicy(int uid, int policy) { 2854 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2855 2856 if (!UserHandle.isApp(uid)) { 2857 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2858 } 2859 synchronized (mUidRulesFirstLock) { 2860 final long token = Binder.clearCallingIdentity(); 2861 try { 2862 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2863 if (oldPolicy != policy) { 2864 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2865 mLogger.uidPolicyChanged(uid, oldPolicy, policy); 2866 } 2867 } finally { 2868 Binder.restoreCallingIdentity(token); 2869 } 2870 } 2871 } 2872 2873 @Override 2874 public void addUidPolicy(int uid, int policy) { 2875 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2876 2877 if (!UserHandle.isApp(uid)) { 2878 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2879 } 2880 2881 synchronized (mUidRulesFirstLock) { 2882 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2883 policy |= oldPolicy; 2884 if (oldPolicy != policy) { 2885 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2886 mLogger.uidPolicyChanged(uid, oldPolicy, policy); 2887 } 2888 } 2889 } 2890 2891 @Override 2892 public void removeUidPolicy(int uid, int policy) { 2893 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2894 2895 if (!UserHandle.isApp(uid)) { 2896 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2897 } 2898 2899 synchronized (mUidRulesFirstLock) { 2900 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2901 policy = oldPolicy & ~policy; 2902 if (oldPolicy != policy) { 2903 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2904 mLogger.uidPolicyChanged(uid, oldPolicy, policy); 2905 } 2906 } 2907 } 2908 2909 @GuardedBy("mUidRulesFirstLock") 2910 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) { 2911 setUidPolicyUncheckedUL(uid, policy, false); 2912 2913 final boolean notifyApp; 2914 if (!isUidValidForAllowlistRulesUL(uid)) { 2915 notifyApp = false; 2916 } else { 2917 final boolean wasDenied = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; 2918 final boolean isDenied = policy == POLICY_REJECT_METERED_BACKGROUND; 2919 final boolean wasAllowed = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; 2920 final boolean isAllowed = policy == POLICY_ALLOW_METERED_BACKGROUND; 2921 final boolean wasBlocked = wasDenied || (mRestrictBackground && !wasAllowed); 2922 final boolean isBlocked = isDenied || (mRestrictBackground && !isAllowed); 2923 if ((wasAllowed && (!isAllowed || isDenied)) 2924 && mDefaultRestrictBackgroundAllowlistUids.get(uid) 2925 && !mRestrictBackgroundAllowlistRevokedUids.get(uid)) { 2926 if (LOGD) 2927 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background allowlist"); 2928 mRestrictBackgroundAllowlistRevokedUids.append(uid, true); 2929 } 2930 notifyApp = wasBlocked != isBlocked; 2931 } 2932 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp)) 2933 .sendToTarget(); 2934 if (persist) { 2935 synchronized (mNetworkPoliciesSecondLock) { 2936 writePolicyAL(); 2937 } 2938 } 2939 } 2940 2941 @GuardedBy("mUidRulesFirstLock") 2942 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) { 2943 if (policy == POLICY_NONE) { 2944 mUidPolicy.delete(uid); 2945 } else { 2946 mUidPolicy.put(uid, policy); 2947 } 2948 2949 // uid policy changed, recompute rules and persist policy. 2950 updateRulesForDataUsageRestrictionsUL(uid); 2951 if (persist) { 2952 synchronized (mNetworkPoliciesSecondLock) { 2953 writePolicyAL(); 2954 } 2955 } 2956 } 2957 2958 @Override 2959 public int getUidPolicy(int uid) { 2960 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2961 2962 synchronized (mUidRulesFirstLock) { 2963 return mUidPolicy.get(uid, POLICY_NONE); 2964 } 2965 } 2966 2967 @Override 2968 public int[] getUidsWithPolicy(int policy) { 2969 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2970 2971 int[] uids = new int[0]; 2972 synchronized (mUidRulesFirstLock) { 2973 for (int i = 0; i < mUidPolicy.size(); i++) { 2974 final int uid = mUidPolicy.keyAt(i); 2975 final int uidPolicy = mUidPolicy.valueAt(i); 2976 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) || 2977 (uidPolicy & policy) != 0) { 2978 uids = appendInt(uids, uid); 2979 } 2980 } 2981 } 2982 return uids; 2983 } 2984 2985 /** 2986 * Removes any persistable state associated with given {@link UserHandle}, persisting 2987 * if any changes that are made. 2988 */ 2989 @GuardedBy("mUidRulesFirstLock") 2990 boolean removeUserStateUL(int userId, boolean writePolicy, boolean updateGlobalRules) { 2991 2992 mLogger.removingUserState(userId); 2993 boolean changed = false; 2994 2995 // Remove entries from revoked default restricted background UID allowlist 2996 for (int i = mRestrictBackgroundAllowlistRevokedUids.size() - 1; i >= 0; i--) { 2997 final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i); 2998 if (UserHandle.getUserId(uid) == userId) { 2999 mRestrictBackgroundAllowlistRevokedUids.removeAt(i); 3000 changed = true; 3001 } 3002 } 3003 3004 // Remove associated UID policies 3005 int[] uids = new int[0]; 3006 for (int i = 0; i < mUidPolicy.size(); i++) { 3007 final int uid = mUidPolicy.keyAt(i); 3008 if (UserHandle.getUserId(uid) == userId) { 3009 uids = appendInt(uids, uid); 3010 } 3011 } 3012 3013 if (uids.length > 0) { 3014 for (int uid : uids) { 3015 mUidPolicy.delete(uid); 3016 } 3017 changed = true; 3018 } 3019 synchronized (mNetworkPoliciesSecondLock) { 3020 if (updateGlobalRules) { 3021 updateRulesForGlobalChangeAL(true); 3022 } 3023 if (writePolicy && changed) { 3024 writePolicyAL(); 3025 } 3026 } 3027 return changed; 3028 } 3029 3030 private boolean checkAnyPermissionOf(String... permissions) { 3031 for (String permission : permissions) { 3032 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { 3033 return true; 3034 } 3035 } 3036 return false; 3037 } 3038 3039 private void enforceAnyPermissionOf(String... permissions) { 3040 if (!checkAnyPermissionOf(permissions)) { 3041 throw new SecurityException("Requires one of the following permissions: " 3042 + String.join(", ", permissions) + "."); 3043 } 3044 } 3045 3046 @Override 3047 public void registerListener(@NonNull INetworkPolicyListener listener) { 3048 Objects.requireNonNull(listener); 3049 // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps 3050 // have declared OBSERVE_NETWORK_POLICY. 3051 enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY); 3052 mListeners.register(listener); 3053 // TODO: Send callbacks to the newly registered listener 3054 } 3055 3056 @Override 3057 public void unregisterListener(@NonNull INetworkPolicyListener listener) { 3058 Objects.requireNonNull(listener); 3059 // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps 3060 // have declared OBSERVE_NETWORK_POLICY. 3061 enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY); 3062 mListeners.unregister(listener); 3063 } 3064 3065 @Override 3066 public void setNetworkPolicies(NetworkPolicy[] policies) { 3067 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3068 3069 final long token = Binder.clearCallingIdentity(); 3070 try { 3071 synchronized (mUidRulesFirstLock) { 3072 synchronized (mNetworkPoliciesSecondLock) { 3073 normalizePoliciesNL(policies); 3074 handleNetworkPoliciesUpdateAL(false); 3075 } 3076 } 3077 } finally { 3078 Binder.restoreCallingIdentity(token); 3079 } 3080 } 3081 3082 void addNetworkPolicyAL(NetworkPolicy policy) { 3083 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 3084 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy); 3085 setNetworkPolicies(policies); 3086 } 3087 3088 @Override 3089 public NetworkPolicy[] getNetworkPolicies(String callingPackage) { 3090 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3091 try { 3092 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); 3093 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED 3094 // permission 3095 } catch (SecurityException e) { 3096 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 3097 3098 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 3099 callingPackage) != AppOpsManager.MODE_ALLOWED) { 3100 return new NetworkPolicy[0]; 3101 } 3102 } 3103 3104 synchronized (mNetworkPoliciesSecondLock) { 3105 final int size = mNetworkPolicy.size(); 3106 final NetworkPolicy[] policies = new NetworkPolicy[size]; 3107 for (int i = 0; i < size; i++) { 3108 policies[i] = mNetworkPolicy.valueAt(i); 3109 } 3110 return policies; 3111 } 3112 } 3113 3114 @GuardedBy("mNetworkPoliciesSecondLock") 3115 private void normalizePoliciesNL() { 3116 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName())); 3117 } 3118 3119 @GuardedBy("mNetworkPoliciesSecondLock") 3120 private void normalizePoliciesNL(NetworkPolicy[] policies) { 3121 mNetworkPolicy.clear(); 3122 for (NetworkPolicy policy : policies) { 3123 if (policy == null) { 3124 continue; 3125 } 3126 // When two normalized templates conflict, prefer the most 3127 // restrictive policy 3128 policy.template = normalizeTemplate(policy.template, mMergedSubscriberIds); 3129 final NetworkPolicy existing = mNetworkPolicy.get(policy.template); 3130 if (existing == null || existing.compareTo(policy) > 0) { 3131 if (existing != null) { 3132 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy); 3133 } 3134 mNetworkPolicy.put(policy.template, policy); 3135 } 3136 } 3137 } 3138 3139 /** 3140 * Examine the given template and normalize it. 3141 * We pick the "lowest" merged subscriber as the primary 3142 * for key purposes, and expand the template to match all other merged 3143 * subscribers. 3144 * 3145 * There can be multiple merged subscriberIds for multi-SIM devices. 3146 * 3147 * <p> 3148 * For example, given an incoming template matching B, and the currently 3149 * active merge set [A,B], we'd return a new template that primarily matches 3150 * A, but also matches B. 3151 */ 3152 @VisibleForTesting(visibility = PRIVATE) 3153 static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template, 3154 @NonNull List<String[]> mergedList) { 3155 // Now there are several types of network which uses Subscriber Id to store network 3156 // information. For instance: 3157 // 1. A merged carrier wifi network which has TYPE_WIFI with a Subscriber Id. 3158 // 2. A typical cellular network could have TYPE_MOBILE with a Subscriber Id. 3159 3160 if (template.getSubscriberIds().isEmpty()) return template; 3161 3162 for (final String[] merged : mergedList) { 3163 // In some rare cases (e.g. b/243015487), merged subscriberId list might contain 3164 // duplicated items. Deduplication for better error handling. 3165 final ArraySet mergedSet = new ArraySet(merged); 3166 if (mergedSet.size() != merged.length) { 3167 Log.wtf(TAG, "Duplicated merged list detected: " + Arrays.toString(merged)); 3168 } 3169 // TODO: Handle incompatible subscriberIds if that happens in practice. 3170 for (final String subscriberId : template.getSubscriberIds()) { 3171 if (com.android.net.module.util.CollectionUtils.contains(merged, subscriberId)) { 3172 // Requested template subscriber is part of the merged group; return 3173 // a template that matches all merged subscribers. 3174 return new NetworkTemplate.Builder(template.getMatchRule()) 3175 .setWifiNetworkKeys(template.getWifiNetworkKeys()) 3176 .setSubscriberIds(mergedSet) 3177 .setMeteredness(template.getMeteredness()) 3178 .build(); 3179 } 3180 } 3181 } 3182 3183 return template; 3184 } 3185 3186 @Override 3187 public void snoozeLimit(NetworkTemplate template) { 3188 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3189 3190 final long token = Binder.clearCallingIdentity(); 3191 try { 3192 performSnooze(template, TYPE_LIMIT); 3193 } finally { 3194 Binder.restoreCallingIdentity(token); 3195 } 3196 } 3197 3198 void performSnooze(NetworkTemplate template, int type) { 3199 final long currentTime = mClock.millis(); 3200 synchronized (mUidRulesFirstLock) { 3201 synchronized (mNetworkPoliciesSecondLock) { 3202 // find and snooze local policy that matches 3203 final NetworkPolicy policy = mNetworkPolicy.get(template); 3204 if (policy == null) { 3205 throw new IllegalArgumentException("unable to find policy for " + template); 3206 } 3207 3208 switch (type) { 3209 case TYPE_WARNING: 3210 policy.lastWarningSnooze = currentTime; 3211 break; 3212 case TYPE_LIMIT: 3213 policy.lastLimitSnooze = currentTime; 3214 break; 3215 case TYPE_RAPID: 3216 policy.lastRapidSnooze = currentTime; 3217 break; 3218 default: 3219 throw new IllegalArgumentException("unexpected type"); 3220 } 3221 3222 handleNetworkPoliciesUpdateAL(true); 3223 } 3224 } 3225 } 3226 3227 @Override 3228 public void setRestrictBackground(boolean restrictBackground) { 3229 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground"); 3230 try { 3231 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3232 final int callingUid = Binder.getCallingUid(); 3233 final long token = Binder.clearCallingIdentity(); 3234 try { 3235 synchronized (mUidRulesFirstLock) { 3236 setRestrictBackgroundUL(restrictBackground, "uid:" + callingUid); 3237 } 3238 } finally { 3239 Binder.restoreCallingIdentity(token); 3240 } 3241 } finally { 3242 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3243 } 3244 } 3245 3246 @GuardedBy("mUidRulesFirstLock") 3247 private void setRestrictBackgroundUL(boolean restrictBackground, String reason) { 3248 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL"); 3249 try { 3250 if (restrictBackground == mRestrictBackground) { 3251 // Ideally, UI should never allow this scenario... 3252 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground); 3253 return; 3254 } 3255 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground + "; reason: " + reason); 3256 final boolean oldRestrictBackground = mRestrictBackground; 3257 mRestrictBackground = restrictBackground; 3258 // Must allow foreground apps before turning data saver mode on. 3259 // TODO: there is no need to iterate through all apps here, just those in the foreground, 3260 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 3261 updateRulesForRestrictBackgroundUL(); 3262 try { 3263 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 3264 Slog.e(TAG, 3265 "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 3266 mRestrictBackground = oldRestrictBackground; 3267 // TODO: if it knew the foreground apps (see TODO above), it could call 3268 // updateRulesForRestrictBackgroundUL() again to restore state. 3269 return; 3270 } 3271 } catch (RemoteException e) { 3272 // ignored; service lives in system_server 3273 } 3274 3275 sendRestrictBackgroundChangedMsg(); 3276 mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground); 3277 3278 if (mRestrictBackgroundLowPowerMode) { 3279 mRestrictBackgroundChangedInBsm = true; 3280 } 3281 synchronized (mNetworkPoliciesSecondLock) { 3282 updateNotificationsNL(); 3283 writePolicyAL(); 3284 } 3285 } finally { 3286 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3287 } 3288 } 3289 3290 private void sendRestrictBackgroundChangedMsg() { 3291 mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED); 3292 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0) 3293 .sendToTarget(); 3294 } 3295 3296 @Override 3297 public int getRestrictBackgroundByCaller() { 3298 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 3299 return getRestrictBackgroundStatusInternal(Binder.getCallingUid()); 3300 } 3301 3302 @Override 3303 public int getRestrictBackgroundStatus(int uid) { 3304 PermissionUtils.enforceNetworkStackPermission(mContext); 3305 return getRestrictBackgroundStatusInternal(uid); 3306 } 3307 3308 private int getRestrictBackgroundStatusInternal(int uid) { 3309 synchronized (mUidRulesFirstLock) { 3310 // Must clear identity because getUidPolicy() is restricted to system. 3311 final long token = Binder.clearCallingIdentity(); 3312 final int policy; 3313 try { 3314 policy = getUidPolicy(uid); 3315 } finally { 3316 Binder.restoreCallingIdentity(token); 3317 } 3318 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 3319 // App is restricted. 3320 return RESTRICT_BACKGROUND_STATUS_ENABLED; 3321 } 3322 if (!mRestrictBackground) { 3323 return RESTRICT_BACKGROUND_STATUS_DISABLED; 3324 } 3325 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0 3326 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 3327 : RESTRICT_BACKGROUND_STATUS_ENABLED; 3328 } 3329 } 3330 3331 @Override 3332 public boolean getRestrictBackground() { 3333 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3334 3335 synchronized (mUidRulesFirstLock) { 3336 return mRestrictBackground; 3337 } 3338 } 3339 3340 @Override 3341 public void setDeviceIdleMode(boolean enabled) { 3342 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3343 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode"); 3344 try { 3345 synchronized (mUidRulesFirstLock) { 3346 if (mDeviceIdleMode == enabled) { 3347 return; 3348 } 3349 mDeviceIdleMode = enabled; 3350 mLogger.deviceIdleModeEnabled(enabled); 3351 if (mSystemReady) { 3352 // Device idle change means we need to rebuild rules for all 3353 // known apps, so do a global refresh. 3354 handleDeviceIdleModeChangedUL(enabled); 3355 } 3356 } 3357 if (enabled) { 3358 EventLogTags.writeDeviceIdleOnPhase("net"); 3359 } else { 3360 EventLogTags.writeDeviceIdleOffPhase("net"); 3361 } 3362 } finally { 3363 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3364 } 3365 } 3366 3367 @Override 3368 public void setWifiMeteredOverride(String networkId, int meteredOverride) { 3369 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 3370 final long token = Binder.clearCallingIdentity(); 3371 try { 3372 final WifiManager wm = mContext.getSystemService(WifiManager.class); 3373 final List<WifiConfiguration> configs = wm.getConfiguredNetworks(); 3374 for (WifiConfiguration config : configs) { 3375 if (Objects.equals(resolveNetworkId(config), networkId)) { 3376 config.meteredOverride = meteredOverride; 3377 wm.updateNetwork(config); 3378 } 3379 } 3380 } finally { 3381 Binder.restoreCallingIdentity(token); 3382 } 3383 } 3384 3385 private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) { 3386 // Verify they're not lying about package name 3387 mAppOps.checkPackage(callingUid, callingPackage); 3388 3389 final PersistableBundle config; 3390 final TelephonyManager tm; 3391 final long token = Binder.clearCallingIdentity(); 3392 try { 3393 config = mCarrierConfigManager.getConfigForSubId(subId); 3394 tm = mContext.getSystemService(TelephonyManager.class); 3395 } finally { 3396 Binder.restoreCallingIdentity(token); 3397 } 3398 3399 // First check: does caller have carrier privilege? 3400 if (tm != null && tm.hasCarrierPrivileges(subId)) { 3401 return; 3402 } 3403 3404 // Second check: has the CarrierService delegated access? 3405 if (config != null) { 3406 final String overridePackage = config 3407 .getString(CarrierConfigManager.KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING, null); 3408 if (!TextUtils.isEmpty(overridePackage) 3409 && Objects.equals(overridePackage, callingPackage)) { 3410 return; 3411 } 3412 } 3413 3414 // Third check: is caller the fallback/default CarrierService? 3415 final String defaultPackage = mCarrierConfigManager.getDefaultCarrierServicePackageName(); 3416 if (!TextUtils.isEmpty(defaultPackage) 3417 && Objects.equals(defaultPackage, callingPackage)) { 3418 return; 3419 } 3420 3421 // Fourth check: is caller a testing app? 3422 final String testPackage = SystemProperties.get(PROP_SUB_PLAN_OWNER + "." + subId, null); 3423 if (!TextUtils.isEmpty(testPackage) 3424 && Objects.equals(testPackage, callingPackage)) { 3425 return; 3426 } 3427 3428 // Fifth check: is caller a legacy testing app? 3429 final String legacyTestPackage = SystemProperties.get("fw.sub_plan_owner." + subId, null); 3430 if (!TextUtils.isEmpty(legacyTestPackage) 3431 && Objects.equals(legacyTestPackage, callingPackage)) { 3432 return; 3433 } 3434 3435 // Final check: does the caller hold a permission? 3436 mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG); 3437 } 3438 3439 private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { 3440 // nothing to check if no plans 3441 if (plans.length == 0) { 3442 Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans."); 3443 return; 3444 } 3445 3446 final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes(); 3447 final ArraySet<Integer> allNetworksSet = new ArraySet<>(); 3448 addAll(allNetworksSet, allNetworkTypes); 3449 3450 final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>(); 3451 boolean hasGeneralPlan = false; 3452 for (int i = 0; i < plans.length; i++) { 3453 final int[] planNetworkTypes = plans[i].getNetworkTypes(); 3454 final ArraySet<Integer> planNetworksSet = new ArraySet<>(); 3455 for (int j = 0; j < planNetworkTypes.length; j++) { 3456 // ensure all network types are valid 3457 if (allNetworksSet.contains(planNetworkTypes[j])) { 3458 // ensure no duplicate network types in the same SubscriptionPlan 3459 if (!planNetworksSet.add(planNetworkTypes[j])) { 3460 throw new IllegalArgumentException( 3461 "Subscription plan contains duplicate network types."); 3462 } 3463 } else { 3464 throw new IllegalArgumentException("Invalid network type: " 3465 + planNetworkTypes[j]); 3466 } 3467 } 3468 3469 if (planNetworkTypes.length == allNetworkTypes.length) { 3470 hasGeneralPlan = true; 3471 } else { 3472 // ensure no network type applies to multiple plans 3473 if (!addAll(applicableNetworkTypes, planNetworkTypes)) { 3474 throw new IllegalArgumentException( 3475 "Multiple subscription plans defined for a single network type."); 3476 } 3477 } 3478 } 3479 3480 // ensure at least one plan applies for every network type 3481 if (!hasGeneralPlan) { 3482 throw new IllegalArgumentException( 3483 "No generic subscription plan that applies to all network types."); 3484 } 3485 } 3486 3487 /** 3488 * Adds all of the {@code elements} to the {@code set}. 3489 * 3490 * @return {@code false} if any element is not added because the set already has the value. 3491 */ 3492 private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) { 3493 boolean result = true; 3494 for (int i = 0; i < elements.length; i++) { 3495 result &= set.add(elements[i]); 3496 } 3497 return result; 3498 } 3499 3500 /** 3501 * Get subscription plan for the given networkTemplate. 3502 * 3503 * @param template the networkTemplate to get the subscription plan for. 3504 */ 3505 @Override 3506 public SubscriptionPlan getSubscriptionPlan(@NonNull NetworkTemplate template) { 3507 enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3508 synchronized (mNetworkPoliciesSecondLock) { 3509 final int subId = findRelevantSubIdNL(template); 3510 return getPrimarySubscriptionPlanLocked(subId); 3511 } 3512 } 3513 3514 /** 3515 * Notifies that the specified {@link NetworkStatsProvider} has reached its quota 3516 * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or 3517 * {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}. 3518 */ 3519 @Override 3520 public void notifyStatsProviderWarningOrLimitReached() { 3521 enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3522 // This API may be called before the system is ready. 3523 synchronized (mNetworkPoliciesSecondLock) { 3524 if (!mSystemReady) return; 3525 } 3526 mHandler.obtainMessage(MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED).sendToTarget(); 3527 } 3528 3529 @Override 3530 public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) { 3531 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); 3532 3533 final String fake = SystemProperties.get("fw.fake_plan"); 3534 if (!TextUtils.isEmpty(fake)) { 3535 final List<SubscriptionPlan> plans = new ArrayList<>(); 3536 if ("month_hard".equals(fake)) { 3537 plans.add(SubscriptionPlan.Builder 3538 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) 3539 .setTitle("G-Mobile") 3540 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3541 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) 3542 .setDataUsage(DataUnit.GIBIBYTES.toBytes(1), 3543 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) 3544 .build()); 3545 plans.add(SubscriptionPlan.Builder 3546 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3547 .setTitle("G-Mobile Happy") 3548 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, 3549 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) 3550 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3551 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) 3552 .build()); 3553 plans.add(SubscriptionPlan.Builder 3554 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3555 .setTitle("G-Mobile, Charged after limit") 3556 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3557 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) 3558 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3559 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) 3560 .build()); 3561 } else if ("month_soft".equals(fake)) { 3562 plans.add(SubscriptionPlan.Builder 3563 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) 3564 .setTitle("G-Mobile is the carriers name who this plan belongs to") 3565 .setSummary("Crazy unlimited bandwidth plan with incredibly long title " 3566 + "that should be cut off to prevent UI from looking terrible") 3567 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3568 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3569 .setDataUsage(DataUnit.GIBIBYTES.toBytes(1), 3570 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3571 .build()); 3572 plans.add(SubscriptionPlan.Builder 3573 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3574 .setTitle("G-Mobile, Throttled after limit") 3575 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3576 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3577 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3578 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3579 .build()); 3580 plans.add(SubscriptionPlan.Builder 3581 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3582 .setTitle("G-Mobile, No data connection after limit") 3583 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3584 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 3585 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3586 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3587 .build()); 3588 3589 } else if ("month_over".equals(fake)) { 3590 plans.add(SubscriptionPlan.Builder 3591 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) 3592 .setTitle("G-Mobile is the carriers name who this plan belongs to") 3593 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3594 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3595 .setDataUsage(DataUnit.GIBIBYTES.toBytes(6), 3596 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3597 .build()); 3598 plans.add(SubscriptionPlan.Builder 3599 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3600 .setTitle("G-Mobile, Throttled after limit") 3601 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3602 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3603 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3604 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3605 .build()); 3606 plans.add(SubscriptionPlan.Builder 3607 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) 3608 .setTitle("G-Mobile, No data connection after limit") 3609 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3610 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 3611 .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), 3612 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3613 .build()); 3614 3615 } else if ("month_none".equals(fake)) { 3616 plans.add(SubscriptionPlan.Builder 3617 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) 3618 .setTitle("G-Mobile") 3619 .build()); 3620 } else if ("prepaid".equals(fake)) { 3621 plans.add(SubscriptionPlan.Builder 3622 .createNonrecurring(ZonedDateTime.now().minusDays(20), 3623 ZonedDateTime.now().plusDays(10)) 3624 .setTitle("G-Mobile") 3625 .setDataLimit(DataUnit.MEBIBYTES.toBytes(512), 3626 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 3627 .setDataUsage(DataUnit.MEBIBYTES.toBytes(100), 3628 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) 3629 .build()); 3630 } else if ("prepaid_crazy".equals(fake)) { 3631 plans.add(SubscriptionPlan.Builder 3632 .createNonrecurring(ZonedDateTime.now().minusDays(20), 3633 ZonedDateTime.now().plusDays(10)) 3634 .setTitle("G-Mobile Anytime") 3635 .setDataLimit(DataUnit.MEBIBYTES.toBytes(512), 3636 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 3637 .setDataUsage(DataUnit.MEBIBYTES.toBytes(100), 3638 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) 3639 .build()); 3640 plans.add(SubscriptionPlan.Builder 3641 .createNonrecurring(ZonedDateTime.now().minusDays(10), 3642 ZonedDateTime.now().plusDays(20)) 3643 .setTitle("G-Mobile Nickel Nights") 3644 .setSummary("5¢/GB between 1-5AM") 3645 .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), 3646 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3647 .setDataUsage(DataUnit.MEBIBYTES.toBytes(15), 3648 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli()) 3649 .build()); 3650 plans.add(SubscriptionPlan.Builder 3651 .createNonrecurring(ZonedDateTime.now().minusDays(10), 3652 ZonedDateTime.now().plusDays(20)) 3653 .setTitle("G-Mobile Bonus 3G") 3654 .setSummary("Unlimited 3G data") 3655 .setDataLimit(DataUnit.GIBIBYTES.toBytes(1), 3656 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3657 .setDataUsage(DataUnit.MEBIBYTES.toBytes(300), 3658 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) 3659 .build()); 3660 } else if ("unlimited".equals(fake)) { 3661 plans.add(SubscriptionPlan.Builder 3662 .createNonrecurring(ZonedDateTime.now().minusDays(20), 3663 ZonedDateTime.now().plusDays(10)) 3664 .setTitle("G-Mobile Awesome") 3665 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, 3666 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 3667 .setDataUsage(DataUnit.MEBIBYTES.toBytes(50), 3668 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) 3669 .build()); 3670 } 3671 return plans.toArray(new SubscriptionPlan[plans.size()]); 3672 } 3673 3674 synchronized (mNetworkPoliciesSecondLock) { 3675 // Only give out plan details to the package that defined them, 3676 // so that we don't risk leaking plans between apps. We always 3677 // let in core system components (like the Settings app). 3678 final String ownerPackage = mSubscriptionPlansOwner.get(subId); 3679 if (Objects.equals(ownerPackage, callingPackage) 3680 || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID) 3681 || (UserHandle.getCallingAppId() == android.os.Process.PHONE_UID)) { 3682 return mSubscriptionPlans.get(subId); 3683 } else { 3684 Log.w(TAG, "Not returning plans because caller " + callingPackage 3685 + " doesn't match owner " + ownerPackage); 3686 return null; 3687 } 3688 } 3689 } 3690 3691 @Override 3692 public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, 3693 long expirationDurationMillis, String callingPackage) { 3694 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); 3695 enforceSubscriptionPlanValidity(plans); 3696 3697 for (SubscriptionPlan plan : plans) { 3698 Objects.requireNonNull(plan); 3699 } 3700 3701 final long token = Binder.clearCallingIdentity(); 3702 try { 3703 setSubscriptionPlansInternal(subId, plans, expirationDurationMillis, callingPackage); 3704 } finally { 3705 Binder.restoreCallingIdentity(token); 3706 } 3707 } 3708 3709 private void setSubscriptionPlansInternal(int subId, SubscriptionPlan[] plans, 3710 long expirationDurationMillis, String callingPackage) { 3711 synchronized (mUidRulesFirstLock) { 3712 synchronized (mNetworkPoliciesSecondLock) { 3713 mSubscriptionPlans.put(subId, plans); 3714 mSubscriptionPlansOwner.put(subId, callingPackage); 3715 3716 final String subscriberId = mSubIdToSubscriberId.get(subId, null); 3717 if (subscriberId != null) { 3718 ensureActiveCarrierPolicyAL(subId, subscriberId); 3719 maybeUpdateCarrierPolicyCycleAL(subId, subscriberId); 3720 } else { 3721 Slog.wtf(TAG, "Missing subscriberId for subId " + subId); 3722 } 3723 3724 handleNetworkPoliciesUpdateAL(true); 3725 3726 final Intent intent = new Intent( 3727 SubscriptionManager.ACTION_SUBSCRIPTION_PLANS_CHANGED); 3728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3729 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); 3730 mContext.sendBroadcast(intent, 3731 android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS); 3732 mHandler.sendMessage(mHandler.obtainMessage( 3733 MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans)); 3734 final int setPlansId = mSetSubscriptionPlansIdCounter++; 3735 mSetSubscriptionPlansIds.put(subId, setPlansId); 3736 if (expirationDurationMillis > 0) { 3737 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_SUBSCRIPTION_PLANS, 3738 subId, setPlansId, callingPackage), expirationDurationMillis); 3739 } 3740 } 3741 } 3742 } 3743 3744 /** 3745 * Only visible for testing purposes. This doesn't give any access to 3746 * existing plans; it simply lets the debug package define new plans. 3747 */ 3748 void setSubscriptionPlansOwner(int subId, String packageName) { 3749 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG); 3750 SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName); 3751 } 3752 3753 @Override 3754 public String getSubscriptionPlansOwner(int subId) { 3755 if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) { 3756 throw new SecurityException(); 3757 } 3758 3759 synchronized (mNetworkPoliciesSecondLock) { 3760 return mSubscriptionPlansOwner.get(subId); 3761 } 3762 } 3763 3764 @Override 3765 public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, 3766 int[] networkTypes, long expirationDurationMillis, String callingPackage) { 3767 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); 3768 3769 final ArraySet<Integer> allNetworksSet = new ArraySet<>(); 3770 addAll(allNetworksSet, TelephonyManager.getAllNetworkTypes()); 3771 final IntArray applicableNetworks = new IntArray(); 3772 3773 // ensure all network types are valid 3774 for (int networkType : networkTypes) { 3775 if (allNetworksSet.contains(networkType)) { 3776 applicableNetworks.add(networkType); 3777 } else { 3778 Log.d(TAG, "setSubscriptionOverride removing invalid network type: " + networkType); 3779 } 3780 } 3781 3782 // We can only override when carrier told us about plans. For the unmetered case, 3783 // allow override without having plans defined. 3784 synchronized (mNetworkPoliciesSecondLock) { 3785 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId); 3786 if (overrideMask != SUBSCRIPTION_OVERRIDE_UNMETERED && plan == null 3787 || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) { 3788 throw new IllegalStateException( 3789 "Must provide valid SubscriptionPlan to enable overriding"); 3790 } 3791 } 3792 3793 // Only allow overrides when feature is enabled. However, we always 3794 // allow disabling of overrides for safety reasons. 3795 final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(), 3796 NETPOLICY_OVERRIDE_ENABLED, 1) != 0; 3797 if (overrideEnabled || overrideValue == 0) { 3798 SomeArgs args = SomeArgs.obtain(); 3799 args.arg1 = subId; 3800 args.arg2 = overrideMask; 3801 args.arg3 = overrideValue; 3802 args.arg4 = applicableNetworks.toArray(); 3803 mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args)); 3804 if (expirationDurationMillis > 0) { 3805 args.arg3 = 0; 3806 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args), 3807 expirationDurationMillis); 3808 } 3809 } 3810 } 3811 3812 /** 3813 * Get multipath preference value for the given network. 3814 */ 3815 public int getMultipathPreference(Network network) { 3816 PermissionUtils.enforceNetworkStackPermission(mContext); 3817 final Integer preference = mMultipathPolicyTracker.getMultipathPreference(network); 3818 if (preference != null) { 3819 return preference; 3820 } 3821 return 0; 3822 } 3823 3824 @NeverCompile // Avoid size overhead of debugging code. 3825 @Override 3826 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 3827 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return; 3828 3829 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 3830 3831 final ArraySet<String> argSet = new ArraySet<String>(args.length); 3832 for (String arg : args) { 3833 argSet.add(arg); 3834 } 3835 3836 synchronized (mUidRulesFirstLock) { 3837 synchronized (mNetworkPoliciesSecondLock) { 3838 if (argSet.contains("--unsnooze")) { 3839 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 3840 mNetworkPolicy.valueAt(i).clearSnooze(); 3841 } 3842 3843 handleNetworkPoliciesUpdateAL(true); 3844 3845 fout.println("Cleared snooze timestamps"); 3846 return; 3847 } 3848 3849 fout.print("System ready: "); fout.println(mSystemReady); 3850 fout.print("Restrict background: "); fout.println(mRestrictBackground); 3851 fout.print("Restrict power: "); fout.println(mRestrictPower); 3852 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 3853 fout.print("Restricted networking mode: "); fout.println(mRestrictedNetworkingMode); 3854 fout.print("Low Power Standby mode: "); fout.println(mLowPowerStandbyActive); 3855 synchronized (mMeteredIfacesLock) { 3856 fout.print("Metered ifaces: "); 3857 fout.println(mMeteredIfaces); 3858 } 3859 3860 fout.println(); 3861 fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode); 3862 fout.println("mRestrictBackgroundBeforeBsm: " + mRestrictBackgroundBeforeBsm); 3863 fout.println("mLoadedRestrictBackground: " + mLoadedRestrictBackground); 3864 fout.println("mRestrictBackgroundChangedInBsm: " + mRestrictBackgroundChangedInBsm); 3865 3866 fout.println(); 3867 fout.println("Network policies:"); 3868 fout.increaseIndent(); 3869 for (int i = 0; i < mNetworkPolicy.size(); i++) { 3870 fout.println(mNetworkPolicy.valueAt(i).toString()); 3871 } 3872 fout.decreaseIndent(); 3873 3874 fout.println(); 3875 fout.println("Subscription plans:"); 3876 fout.increaseIndent(); 3877 for (int i = 0; i < mSubscriptionPlans.size(); i++) { 3878 final int subId = mSubscriptionPlans.keyAt(i); 3879 fout.println("Subscriber ID " + subId + ":"); 3880 fout.increaseIndent(); 3881 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i); 3882 if (!ArrayUtils.isEmpty(plans)) { 3883 for (SubscriptionPlan plan : plans) { 3884 fout.println(plan); 3885 } 3886 } 3887 fout.decreaseIndent(); 3888 } 3889 fout.decreaseIndent(); 3890 3891 fout.println(); 3892 fout.println("Active subscriptions:"); 3893 fout.increaseIndent(); 3894 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { 3895 final int subId = mSubIdToSubscriberId.keyAt(i); 3896 final String subscriberId = mSubIdToSubscriberId.valueAt(i); 3897 3898 fout.println(subId + "=" 3899 + NetworkIdentityUtils.scrubSubscriberId(subscriberId)); 3900 } 3901 fout.decreaseIndent(); 3902 3903 fout.println(); 3904 for (String[] mergedSubscribers : mMergedSubscriberIds) { 3905 fout.println("Merged subscriptions: " + Arrays.toString( 3906 NetworkIdentityUtils.scrubSubscriberIds(mergedSubscribers))); 3907 } 3908 3909 fout.println(); 3910 fout.println("Policy for UIDs:"); 3911 fout.increaseIndent(); 3912 int size = mUidPolicy.size(); 3913 for (int i = 0; i < size; i++) { 3914 final int uid = mUidPolicy.keyAt(i); 3915 final int policy = mUidPolicy.valueAt(i); 3916 fout.print("UID="); 3917 fout.print(uid); 3918 fout.print(" policy="); 3919 fout.print(uidPoliciesToString(policy)); 3920 fout.println(); 3921 } 3922 fout.decreaseIndent(); 3923 3924 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 3925 if (size > 0) { 3926 fout.println("Power save whitelist (except idle) app ids:"); 3927 fout.increaseIndent(); 3928 for (int i = 0; i < size; i++) { 3929 fout.print("UID="); 3930 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 3931 fout.print(": "); 3932 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 3933 fout.println(); 3934 } 3935 fout.decreaseIndent(); 3936 } 3937 3938 size = mPowerSaveWhitelistAppIds.size(); 3939 if (size > 0) { 3940 fout.println("Power save whitelist app ids:"); 3941 fout.increaseIndent(); 3942 for (int i = 0; i < size; i++) { 3943 fout.print("UID="); 3944 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 3945 fout.print(": "); 3946 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 3947 fout.println(); 3948 } 3949 fout.decreaseIndent(); 3950 } 3951 3952 size = mAppIdleTempWhitelistAppIds.size(); 3953 if (size > 0) { 3954 fout.println("App idle whitelist app ids:"); 3955 fout.increaseIndent(); 3956 for (int i = 0; i < size; i++) { 3957 fout.print("UID="); 3958 fout.print(mAppIdleTempWhitelistAppIds.keyAt(i)); 3959 fout.print(": "); 3960 fout.print(mAppIdleTempWhitelistAppIds.valueAt(i)); 3961 fout.println(); 3962 } 3963 fout.decreaseIndent(); 3964 } 3965 3966 size = mDefaultRestrictBackgroundAllowlistUids.size(); 3967 if (size > 0) { 3968 fout.println("Default restrict background allowlist uids:"); 3969 fout.increaseIndent(); 3970 for (int i = 0; i < size; i++) { 3971 fout.print("UID="); 3972 fout.print(mDefaultRestrictBackgroundAllowlistUids.keyAt(i)); 3973 fout.println(); 3974 } 3975 fout.decreaseIndent(); 3976 } 3977 3978 size = mRestrictBackgroundAllowlistRevokedUids.size(); 3979 if (size > 0) { 3980 fout.println("Default restrict background allowlist uids revoked by users:"); 3981 fout.increaseIndent(); 3982 for (int i = 0; i < size; i++) { 3983 fout.print("UID="); 3984 fout.print(mRestrictBackgroundAllowlistRevokedUids.keyAt(i)); 3985 fout.println(); 3986 } 3987 fout.decreaseIndent(); 3988 } 3989 3990 size = mLowPowerStandbyAllowlistUids.size(); 3991 if (size > 0) { 3992 fout.println("Low Power Standby allowlist uids:"); 3993 fout.increaseIndent(); 3994 for (int i = 0; i < size; i++) { 3995 fout.print("UID="); 3996 fout.print(mLowPowerStandbyAllowlistUids.keyAt(i)); 3997 fout.println(); 3998 } 3999 fout.decreaseIndent(); 4000 } 4001 4002 final SparseBooleanArray knownUids = new SparseBooleanArray(); 4003 collectKeys(mUidState, knownUids); 4004 synchronized (mUidBlockedState) { 4005 collectKeys(mUidBlockedState, knownUids); 4006 } 4007 4008 fout.println("Status for all known UIDs:"); 4009 fout.increaseIndent(); 4010 size = knownUids.size(); 4011 for (int i = 0; i < size; i++) { 4012 final int uid = knownUids.keyAt(i); 4013 fout.print("UID="); 4014 fout.print(uid); 4015 4016 final UidState uidState = mUidState.get(uid); 4017 if (uidState == null) { 4018 fout.print(" state={null}"); 4019 } else { 4020 fout.print(" state="); 4021 fout.print(uidState.toString()); 4022 } 4023 4024 synchronized (mUidBlockedState) { 4025 final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); 4026 if (uidBlockedState == null) { 4027 fout.print(" blocked_state={null}"); 4028 } else { 4029 fout.print(" blocked_state="); 4030 fout.print(uidBlockedState); 4031 } 4032 } 4033 fout.println(); 4034 } 4035 fout.decreaseIndent(); 4036 4037 fout.println("Admin restricted uids for metered data:"); 4038 fout.increaseIndent(); 4039 size = mMeteredRestrictedUids.size(); 4040 for (int i = 0; i < size; ++i) { 4041 fout.print("u" + mMeteredRestrictedUids.keyAt(i) + ": "); 4042 fout.println(mMeteredRestrictedUids.valueAt(i)); 4043 } 4044 fout.decreaseIndent(); 4045 4046 fout.println(); 4047 mStatLogger.dump(fout); 4048 4049 mLogger.dumpLogs(fout); 4050 } 4051 } 4052 fout.println(); 4053 mMultipathPolicyTracker.dump(fout); 4054 } 4055 4056 @Override 4057 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 4058 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 4059 @NonNull String[] args) { 4060 return new NetworkPolicyManagerShellCommand(mContext, this).exec(this, 4061 in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); 4062 } 4063 4064 void setDebugUid(int uid) { 4065 mLogger.setDebugUid(uid); 4066 } 4067 4068 @VisibleForTesting 4069 boolean isUidForeground(int uid) { 4070 synchronized (mUidRulesFirstLock) { 4071 return isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid)); 4072 } 4073 } 4074 4075 @GuardedBy("mUidRulesFirstLock") 4076 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) { 4077 final UidState uidState = mUidState.get(uid); 4078 return isProcStateAllowedWhileOnRestrictBackground(uidState); 4079 } 4080 4081 @GuardedBy("mUidRulesFirstLock") 4082 private boolean isUidForegroundOnRestrictPowerUL(int uid) { 4083 final UidState uidState = mUidState.get(uid); 4084 return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState); 4085 } 4086 4087 @GuardedBy("mUidRulesFirstLock") 4088 private boolean isUidTop(int uid) { 4089 final UidState uidState = mUidState.get(uid); 4090 return isProcStateAllowedWhileInLowPowerStandby(uidState); 4091 } 4092 4093 /** 4094 * Process state of UID changed; if needed, will trigger 4095 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and 4096 * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated. 4097 */ 4098 @GuardedBy("mUidRulesFirstLock") 4099 private boolean updateUidStateUL(int uid, int procState, long procStateSeq, 4100 @ProcessCapability int capability) { 4101 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL"); 4102 try { 4103 final UidState oldUidState = mUidState.get(uid); 4104 if (oldUidState != null && procStateSeq < oldUidState.procStateSeq) { 4105 if (LOGV) { 4106 Slog.v(TAG, "Ignoring older uid state updates; uid=" + uid 4107 + ",procState=" + procStateToString(procState) + ",seq=" + procStateSeq 4108 + ",cap=" + capability + ",oldUidState=" + oldUidState); 4109 } 4110 return false; 4111 } 4112 if (oldUidState == null || oldUidState.procState != procState 4113 || oldUidState.capability != capability) { 4114 final UidState newUidState = new UidState(uid, procState, procStateSeq, capability); 4115 // state changed, push updated rules 4116 mUidState.put(uid, newUidState); 4117 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState); 4118 boolean allowedWhileIdleOrPowerSaveModeChanged = 4119 isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 4120 != isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState); 4121 if (allowedWhileIdleOrPowerSaveModeChanged) { 4122 updateRuleForAppIdleUL(uid, procState); 4123 if (mDeviceIdleMode) { 4124 updateRuleForDeviceIdleUL(uid); 4125 } 4126 if (mRestrictPower) { 4127 updateRuleForRestrictPowerUL(uid); 4128 } 4129 updateRulesForPowerRestrictionsUL(uid, procState); 4130 } 4131 if (mLowPowerStandbyActive) { 4132 boolean allowedInLpsChanged = 4133 isProcStateAllowedWhileInLowPowerStandby(oldUidState) 4134 != isProcStateAllowedWhileInLowPowerStandby(newUidState); 4135 if (allowedInLpsChanged) { 4136 if (!allowedWhileIdleOrPowerSaveModeChanged) { 4137 updateRulesForPowerRestrictionsUL(uid, procState); 4138 } 4139 updateRuleForLowPowerStandbyUL(uid); 4140 } 4141 } 4142 return true; 4143 } 4144 } finally { 4145 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4146 } 4147 return false; 4148 } 4149 4150 @GuardedBy("mUidRulesFirstLock") 4151 private boolean removeUidStateUL(int uid) { 4152 final int index = mUidState.indexOfKey(uid); 4153 if (index >= 0) { 4154 final UidState oldUidState = mUidState.valueAt(index); 4155 mUidState.removeAt(index); 4156 if (oldUidState != null) { 4157 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, null); 4158 if (mDeviceIdleMode) { 4159 updateRuleForDeviceIdleUL(uid); 4160 } 4161 if (mRestrictPower) { 4162 updateRuleForRestrictPowerUL(uid); 4163 } 4164 updateRulesForPowerRestrictionsUL(uid); 4165 if (mLowPowerStandbyActive) { 4166 updateRuleForLowPowerStandbyUL(uid); 4167 } 4168 return true; 4169 } 4170 } 4171 return false; 4172 } 4173 4174 // adjust stats accounting based on foreground status 4175 private void updateNetworkStats(int uid, boolean uidForeground) { 4176 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 4177 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 4178 "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B")); 4179 } 4180 try { 4181 mNetworkStats.noteUidForeground(uid, uidForeground); 4182 } finally { 4183 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4184 } 4185 } 4186 4187 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, 4188 @Nullable UidState oldUidState, @Nullable UidState newUidState) { 4189 final boolean oldForeground = 4190 isProcStateAllowedWhileOnRestrictBackground(oldUidState); 4191 final boolean newForeground = 4192 isProcStateAllowedWhileOnRestrictBackground(newUidState); 4193 if (oldForeground != newForeground) { 4194 updateRulesForDataUsageRestrictionsUL(uid); 4195 } 4196 } 4197 4198 @VisibleForTesting 4199 boolean isRestrictedModeEnabled() { 4200 synchronized (mUidRulesFirstLock) { 4201 return mRestrictedNetworkingMode; 4202 } 4203 } 4204 4205 /** 4206 * updates restricted mode state / access for all apps 4207 * Called on initialization and when restricted mode is enabled / disabled. 4208 */ 4209 @VisibleForTesting 4210 @GuardedBy("mUidRulesFirstLock") 4211 void updateRestrictedModeAllowlistUL() { 4212 mUidFirewallRestrictedModeRules.clear(); 4213 forEachUid("updateRestrictedModeAllowlist", uid -> { 4214 synchronized (mUidRulesFirstLock) { 4215 final int effectiveBlockedReasons = updateBlockedReasonsForRestrictedModeUL( 4216 uid); 4217 final int newFirewallRule = getRestrictedModeFirewallRule(effectiveBlockedReasons); 4218 4219 // setUidFirewallRulesUL will allowlist all uids that are passed to it, so only add 4220 // non-default rules. 4221 if (newFirewallRule != FIREWALL_RULE_DEFAULT) { 4222 mUidFirewallRestrictedModeRules.append(uid, newFirewallRule); 4223 } 4224 } 4225 }); 4226 if (mRestrictedNetworkingMode) { 4227 // firewall rules only need to be set when this mode is being enabled. 4228 setUidFirewallRulesUL(FIREWALL_CHAIN_RESTRICTED, mUidFirewallRestrictedModeRules); 4229 } 4230 enableFirewallChainUL(FIREWALL_CHAIN_RESTRICTED, mRestrictedNetworkingMode); 4231 } 4232 4233 // updates restricted mode state / access for a single app / uid. 4234 @VisibleForTesting 4235 @GuardedBy("mUidRulesFirstLock") 4236 void updateRestrictedModeForUidUL(int uid) { 4237 final int effectiveBlockedReasons = updateBlockedReasonsForRestrictedModeUL(uid); 4238 4239 // if restricted networking mode is on, and the app has an access exemption, the uid rule 4240 // will not change, but the firewall rule will have to be updated. 4241 if (mRestrictedNetworkingMode) { 4242 // Note: setUidFirewallRule also updates mUidFirewallRestrictedModeRules. 4243 // In this case, default firewall rules can also be added. 4244 setUidFirewallRuleUL(FIREWALL_CHAIN_RESTRICTED, uid, 4245 getRestrictedModeFirewallRule(effectiveBlockedReasons)); 4246 } 4247 } 4248 4249 @GuardedBy("mUidRulesFirstLock") 4250 private int updateBlockedReasonsForRestrictedModeUL(int uid) { 4251 final boolean hasRestrictedModeAccess = hasRestrictedModeAccess(uid); 4252 final int oldEffectiveBlockedReasons; 4253 final int newEffectiveBlockedReasons; 4254 final int uidRules; 4255 synchronized (mUidBlockedState) { 4256 final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid( 4257 mUidBlockedState, uid); 4258 oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 4259 if (mRestrictedNetworkingMode) { 4260 uidBlockedState.blockedReasons |= BLOCKED_REASON_RESTRICTED_MODE; 4261 } else { 4262 uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE; 4263 } 4264 if (hasRestrictedModeAccess) { 4265 uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; 4266 } else { 4267 uidBlockedState.allowedReasons &= ~ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; 4268 } 4269 uidBlockedState.updateEffectiveBlockedReasons(); 4270 4271 newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 4272 uidRules = oldEffectiveBlockedReasons == newEffectiveBlockedReasons 4273 ? RULE_NONE 4274 : uidBlockedState.deriveUidRules(); 4275 } 4276 if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) { 4277 handleBlockedReasonsChanged(uid, 4278 newEffectiveBlockedReasons, oldEffectiveBlockedReasons); 4279 4280 postUidRulesChangedMsg(uid, uidRules); 4281 } 4282 return newEffectiveBlockedReasons; 4283 } 4284 4285 private static int getRestrictedModeFirewallRule(int effectiveBlockedReasons) { 4286 if ((effectiveBlockedReasons & BLOCKED_REASON_RESTRICTED_MODE) != 0) { 4287 // rejected in restricted mode, this is the default behavior. 4288 return FIREWALL_RULE_DEFAULT; 4289 } else { 4290 return FIREWALL_RULE_ALLOW; 4291 } 4292 } 4293 4294 private boolean hasRestrictedModeAccess(int uid) { 4295 try { 4296 // TODO: this needs to be kept in sync with 4297 // PermissionMonitor#hasRestrictedNetworkPermission 4298 return mIPm.checkUidPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, uid) 4299 == PERMISSION_GRANTED 4300 || mIPm.checkUidPermission(NETWORK_STACK, uid) == PERMISSION_GRANTED 4301 || mIPm.checkUidPermission(PERMISSION_MAINLINE_NETWORK_STACK, uid) 4302 == PERMISSION_GRANTED; 4303 } catch (RemoteException e) { 4304 return false; 4305 } 4306 } 4307 4308 @GuardedBy("mUidRulesFirstLock") 4309 void updateRulesForPowerSaveUL() { 4310 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL"); 4311 try { 4312 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 4313 mUidFirewallPowerSaveRules); 4314 } finally { 4315 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4316 } 4317 } 4318 4319 @GuardedBy("mUidRulesFirstLock") 4320 void updateRuleForRestrictPowerUL(int uid) { 4321 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 4322 } 4323 4324 @GuardedBy("mUidRulesFirstLock") 4325 void updateRulesForDeviceIdleUL() { 4326 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL"); 4327 try { 4328 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 4329 mUidFirewallDozableRules); 4330 } finally { 4331 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4332 } 4333 } 4334 4335 @GuardedBy("mUidRulesFirstLock") 4336 void updateRuleForDeviceIdleUL(int uid) { 4337 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 4338 } 4339 4340 // NOTE: since both fw_dozable and fw_powersave uses the same map 4341 // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method. 4342 @GuardedBy("mUidRulesFirstLock") 4343 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain, 4344 SparseIntArray rules) { 4345 if (enabled) { 4346 // Sync the whitelists before enabling the chain. We don't care about the rules if 4347 // we are disabling the chain. 4348 final SparseIntArray uidRules = rules; 4349 uidRules.clear(); 4350 final List<UserInfo> users = mUserManager.getUsers(); 4351 for (int ui = users.size() - 1; ui >= 0; ui--) { 4352 UserInfo user = users.get(ui); 4353 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id); 4354 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id); 4355 if (chain == FIREWALL_CHAIN_POWERSAVE) { 4356 updateRulesForWhitelistedAppIds(uidRules, 4357 mPowerSaveWhitelistExceptIdleAppIds, user.id); 4358 } 4359 } 4360 for (int i = mUidState.size() - 1; i >= 0; i--) { 4361 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 4362 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 4363 } 4364 } 4365 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE); 4366 } else { 4367 setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE); 4368 } 4369 } 4370 4371 private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules, 4372 final SparseBooleanArray whitelistedAppIds, int userId) { 4373 for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) { 4374 if (whitelistedAppIds.valueAt(i)) { 4375 final int appId = whitelistedAppIds.keyAt(i); 4376 final int uid = UserHandle.getUid(userId, appId); 4377 uidRules.put(uid, FIREWALL_RULE_ALLOW); 4378 } 4379 } 4380 } 4381 4382 @GuardedBy("mUidRulesFirstLock") 4383 void updateRulesForLowPowerStandbyUL() { 4384 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForLowPowerStandbyUL"); 4385 try { 4386 if (mLowPowerStandbyActive) { 4387 mUidFirewallLowPowerStandbyModeRules.clear(); 4388 for (int i = mUidState.size() - 1; i >= 0; i--) { 4389 final int uid = mUidState.keyAt(i); 4390 final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid); 4391 if (hasInternetPermissionUL(uid) && (effectiveBlockedReasons 4392 & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) { 4393 mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW); 4394 } 4395 } 4396 setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, 4397 mUidFirewallLowPowerStandbyModeRules, CHAIN_TOGGLE_ENABLE); 4398 } else { 4399 setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, null, CHAIN_TOGGLE_DISABLE); 4400 } 4401 } finally { 4402 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4403 } 4404 } 4405 4406 @GuardedBy("mUidRulesFirstLock") 4407 void updateRuleForLowPowerStandbyUL(int uid) { 4408 if (!hasInternetPermissionUL(uid)) { 4409 return; 4410 } 4411 4412 final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid); 4413 if (mUidState.contains(uid) 4414 && (effectiveBlockedReasons & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) { 4415 mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW); 4416 setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_ALLOW); 4417 } else { 4418 mUidFirewallLowPowerStandbyModeRules.delete(uid); 4419 setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT); 4420 } 4421 } 4422 4423 /** 4424 * Returns whether a uid is allowlisted from power saving restrictions (eg: Battery Saver, Doze 4425 * mode, and app idle). 4426 * 4427 * @param deviceIdleMode if true then we don't consider 4428 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is 4429 * allowlisted. 4430 */ 4431 @GuardedBy("mUidRulesFirstLock") 4432 private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) { 4433 final int appId = UserHandle.getAppId(uid); 4434 boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) 4435 || mPowerSaveWhitelistAppIds.get(appId); 4436 if (!deviceIdleMode) { 4437 isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid); 4438 } 4439 return isWhitelisted; 4440 } 4441 4442 /** 4443 * Returns whether a uid is allowlisted from power saving restrictions, except Device idle 4444 * (eg: Battery Saver and app idle). 4445 */ 4446 @GuardedBy("mUidRulesFirstLock") 4447 private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) { 4448 final int appId = UserHandle.getAppId(uid); 4449 return mPowerSaveWhitelistExceptIdleAppIds.get(appId); 4450 } 4451 4452 /** 4453 * Returns whether a uid is allowlisted from low power standby restrictions. 4454 */ 4455 @GuardedBy("mUidRulesFirstLock") 4456 private boolean isAllowlistedFromLowPowerStandbyUL(int uid) { 4457 return mLowPowerStandbyAllowlistUids.get(uid); 4458 } 4459 4460 // NOTE: since both fw_dozable and fw_powersave uses the same map 4461 // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method. 4462 @GuardedBy("mUidRulesFirstLock") 4463 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) { 4464 if (enabled) { 4465 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, 4466 chain == FIREWALL_CHAIN_DOZABLE); 4467 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) { 4468 setUidFirewallRuleUL(chain, uid, FIREWALL_RULE_ALLOW); 4469 } else { 4470 setUidFirewallRuleUL(chain, uid, FIREWALL_RULE_DEFAULT); 4471 } 4472 } 4473 } 4474 4475 @GuardedBy("mUidRulesFirstLock") 4476 void updateRulesForAppIdleUL() { 4477 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL"); 4478 try { 4479 final SparseIntArray uidRules = mUidFirewallStandbyRules; 4480 uidRules.clear(); 4481 4482 // Fully update the app idle firewall chain. 4483 final List<UserInfo> users = mUserManager.getUsers(); 4484 for (int ui = users.size() - 1; ui >= 0; ui--) { 4485 UserInfo user = users.get(ui); 4486 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 4487 for (int uid : idleUids) { 4488 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 4489 // quick check: if this uid doesn't have INTERNET permission, it 4490 // doesn't have network access anyway, so it is a waste to mess 4491 // with it here. 4492 if (hasInternetPermissionUL(uid) && !isUidForegroundOnRestrictPowerUL(uid)) { 4493 uidRules.put(uid, FIREWALL_RULE_DENY); 4494 } 4495 } 4496 } 4497 } 4498 4499 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE); 4500 } finally { 4501 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4502 } 4503 } 4504 4505 @GuardedBy("mUidRulesFirstLock") 4506 void updateRuleForAppIdleUL(int uid, int uidProcessState) { 4507 if (!isUidValidForDenylistRulesUL(uid)) return; 4508 4509 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 4510 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid ); 4511 } 4512 try { 4513 int appId = UserHandle.getAppId(uid); 4514 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid, uidProcessState) 4515 && !isUidForegroundOnRestrictPowerUL(uid)) { 4516 setUidFirewallRuleUL(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 4517 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid); 4518 } else { 4519 setUidFirewallRuleUL(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 4520 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT"); 4521 } 4522 } finally { 4523 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4524 } 4525 } 4526 4527 /** 4528 * Toggle the firewall standby chain and inform listeners if the uid rules have effectively 4529 * changed. 4530 */ 4531 @GuardedBy("mUidRulesFirstLock") 4532 private void updateRulesForAppIdleParoleUL() { 4533 final boolean paroled = mAppStandby.isInParole(); 4534 final boolean enableChain = !paroled; 4535 4536 int ruleCount = mUidFirewallStandbyRules.size(); 4537 final SparseIntArray blockedUids = new SparseIntArray(); 4538 for (int i = 0; i < ruleCount; i++) { 4539 final int uid = mUidFirewallStandbyRules.keyAt(i); 4540 if (!isUidValidForDenylistRulesUL(uid)) { 4541 continue; 4542 } 4543 final int blockedReasons = getBlockedReasons(uid); 4544 if (!enableChain && (blockedReasons & ~BLOCKED_METERED_REASON_MASK) 4545 == BLOCKED_REASON_NONE) { 4546 // Chain isn't enabled and the uid had no restrictions to begin with. 4547 continue; 4548 } 4549 final boolean isUidIdle = !paroled && isUidIdle(uid); 4550 if (isUidIdle && !mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid)) 4551 && !isUidForegroundOnRestrictPowerUL(uid)) { 4552 mUidFirewallStandbyRules.put(uid, FIREWALL_RULE_DENY); 4553 blockedUids.put(uid, FIREWALL_RULE_DENY); 4554 } else { 4555 mUidFirewallStandbyRules.put(uid, FIREWALL_RULE_DEFAULT); 4556 } 4557 updateRulesForPowerRestrictionsUL(uid, isUidIdle); 4558 } 4559 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, blockedUids, 4560 enableChain ? CHAIN_TOGGLE_ENABLE : CHAIN_TOGGLE_DISABLE); 4561 } 4562 4563 /** 4564 * Update rules that might be changed by {@link #mRestrictBackground}, 4565 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 4566 */ 4567 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) 4568 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) { 4569 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 4570 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 4571 "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-")); 4572 } 4573 try { 4574 updateRulesForAppIdleUL(); 4575 updateRulesForRestrictPowerUL(); 4576 updateRulesForRestrictBackgroundUL(); 4577 updateRestrictedModeAllowlistUL(); 4578 4579 // If the set of restricted networks may have changed, re-evaluate those. 4580 if (restrictedNetworksChanged) { 4581 normalizePoliciesNL(); 4582 updateNetworkRulesNL(); 4583 } 4584 } finally { 4585 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4586 } 4587 } 4588 4589 @GuardedBy("mUidRulesFirstLock") 4590 private void handleDeviceIdleModeChangedUL(boolean enabled) { 4591 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL"); 4592 try { 4593 updateRulesForDeviceIdleUL(); 4594 if (enabled) { 4595 forEachUid("updateRulesForRestrictPower", uid -> { 4596 synchronized (mUidRulesFirstLock) { 4597 updateRulesForPowerRestrictionsUL(uid); 4598 } 4599 }); 4600 } else { 4601 // TODO: Note that we could handle the case of enabling-doze state similar 4602 // to this but first, we need to update how we listen to uid state changes 4603 // so that we always get a callback when a process moves from a NONEXISTENT state 4604 // to a "background" state. 4605 handleDeviceIdleModeDisabledUL(); 4606 } 4607 } finally { 4608 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4609 } 4610 } 4611 4612 @GuardedBy("mUidRulesFirstLock") 4613 private void handleDeviceIdleModeDisabledUL() { 4614 Trace.traceBegin(TRACE_TAG_NETWORK, "handleDeviceIdleModeDisabledUL"); 4615 try { 4616 final SparseArray<SomeArgs> uidStateUpdates = new SparseArray<>(); 4617 synchronized (mUidBlockedState) { 4618 final int size = mUidBlockedState.size(); 4619 for (int i = 0; i < size; ++i) { 4620 final int uid = mUidBlockedState.keyAt(i); 4621 final UidBlockedState uidBlockedState = mUidBlockedState.valueAt(i); 4622 if ((uidBlockedState.blockedReasons & BLOCKED_REASON_DOZE) == 0) { 4623 continue; 4624 } 4625 uidBlockedState.blockedReasons &= ~BLOCKED_REASON_DOZE; 4626 final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 4627 uidBlockedState.updateEffectiveBlockedReasons(); 4628 if (LOGV) { 4629 Log.v(TAG, "handleDeviceIdleModeDisabled(" + uid + "); " 4630 + "newUidBlockedState=" + uidBlockedState 4631 + ", oldEffectiveBlockedReasons=" + oldEffectiveBlockedReasons); 4632 } 4633 if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) { 4634 final SomeArgs someArgs = SomeArgs.obtain(); 4635 someArgs.argi1 = oldEffectiveBlockedReasons; 4636 someArgs.argi2 = uidBlockedState.effectiveBlockedReasons; 4637 someArgs.argi3 = uidBlockedState.deriveUidRules(); 4638 uidStateUpdates.append(uid, someArgs); 4639 // TODO: Update the state for all changed uids together. 4640 mActivityManagerInternal.onUidBlockedReasonsChanged(uid, 4641 uidBlockedState.effectiveBlockedReasons); 4642 } 4643 } 4644 } 4645 if (uidStateUpdates.size() != 0) { 4646 mHandler.obtainMessage(MSG_UIDS_BLOCKED_REASONS_CHANGED, uidStateUpdates) 4647 .sendToTarget(); 4648 } 4649 } finally { 4650 Trace.traceEnd(TRACE_TAG_NETWORK); 4651 } 4652 } 4653 4654 // TODO: rename / document to make it clear these are global (not app-specific) rules 4655 @GuardedBy("mUidRulesFirstLock") 4656 private void updateRulesForRestrictPowerUL() { 4657 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL"); 4658 try { 4659 updateRulesForDeviceIdleUL(); 4660 updateRulesForPowerSaveUL(); 4661 forEachUid("updateRulesForRestrictPower", 4662 uid -> updateRulesForPowerRestrictionsUL(uid)); 4663 } finally { 4664 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4665 } 4666 } 4667 4668 @GuardedBy("mUidRulesFirstLock") 4669 private void updateRulesForRestrictBackgroundUL() { 4670 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL"); 4671 try { 4672 forEachUid("updateRulesForRestrictBackground", 4673 uid -> updateRulesForDataUsageRestrictionsUL(uid)); 4674 } finally { 4675 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4676 } 4677 } 4678 4679 private void forEachUid(String tag, IntConsumer consumer) { 4680 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 4681 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "forEachUid-" + tag); 4682 } 4683 try { 4684 // update rules for all installed applications 4685 final List<UserInfo> users; 4686 4687 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users"); 4688 try { 4689 users = mUserManager.getUsers(); 4690 } finally { 4691 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4692 } 4693 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "iterate-uids"); 4694 try { 4695 final PackageManagerInternal packageManagerInternal = LocalServices.getService( 4696 PackageManagerInternal.class); 4697 final int usersSize = users.size(); 4698 for (int i = 0; i < usersSize; ++i) { 4699 final int userId = users.get(i).id; 4700 final SparseBooleanArray sharedAppIdsHandled = new SparseBooleanArray(); 4701 packageManagerInternal.forEachInstalledPackage(androidPackage -> { 4702 final int appId = androidPackage.getUid(); 4703 if (androidPackage.getSharedUserId() != null) { 4704 if (sharedAppIdsHandled.indexOfKey(appId) < 0) { 4705 sharedAppIdsHandled.put(appId, true); 4706 } else { 4707 return; 4708 } 4709 } 4710 final int uid = UserHandle.getUid(userId, appId); 4711 consumer.accept(uid); 4712 }, userId); 4713 } 4714 } finally { 4715 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4716 } 4717 } finally { 4718 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4719 } 4720 } 4721 4722 @GuardedBy("mUidRulesFirstLock") 4723 private void updateRulesForTempWhitelistChangeUL(int appId) { 4724 final List<UserInfo> users = mUserManager.getUsers(); 4725 final int numUsers = users.size(); 4726 for (int i = 0; i < numUsers; i++) { 4727 final UserInfo user = users.get(i); 4728 int uid = UserHandle.getUid(user.id, appId); 4729 // Update external firewall rules. 4730 updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); 4731 updateRuleForDeviceIdleUL(uid); 4732 updateRuleForRestrictPowerUL(uid); 4733 // Update internal rules. 4734 updateRulesForPowerRestrictionsUL(uid); 4735 } 4736 } 4737 4738 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 4739 // methods below could be merged into a isUidValidForRules() method. 4740 @GuardedBy("mUidRulesFirstLock") 4741 private boolean isUidValidForDenylistRulesUL(int uid) { 4742 // allow rules on specific system services, and any apps 4743 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 4744 || isUidValidForAllowlistRulesUL(uid)) { 4745 return true; 4746 } 4747 4748 return false; 4749 } 4750 4751 @GuardedBy("mUidRulesFirstLock") 4752 private boolean isUidValidForAllowlistRulesUL(int uid) { 4753 return UserHandle.isApp(uid) && hasInternetPermissionUL(uid); 4754 } 4755 4756 /** 4757 * Set whether or not an app should be allowlisted for network access while in app idle. Other 4758 * power saving restrictions may still apply. 4759 */ 4760 @VisibleForTesting 4761 void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { 4762 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 4763 4764 synchronized (mUidRulesFirstLock) { 4765 if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) { 4766 // No change. 4767 return; 4768 } 4769 4770 final long token = Binder.clearCallingIdentity(); 4771 try { 4772 mLogger.appIdleWlChanged(uid, shouldWhitelist); 4773 if (shouldWhitelist) { 4774 mAppIdleTempWhitelistAppIds.put(uid, true); 4775 } else { 4776 mAppIdleTempWhitelistAppIds.delete(uid); 4777 } 4778 updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); 4779 updateRulesForPowerRestrictionsUL(uid); 4780 } finally { 4781 Binder.restoreCallingIdentity(token); 4782 } 4783 } 4784 } 4785 4786 /** Return the list of UIDs currently in the app idle allowlist. */ 4787 @VisibleForTesting 4788 int[] getAppIdleWhitelist() { 4789 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 4790 4791 synchronized (mUidRulesFirstLock) { 4792 final int len = mAppIdleTempWhitelistAppIds.size(); 4793 int[] uids = new int[len]; 4794 for (int i = 0; i < len; ++i) { 4795 uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i); 4796 } 4797 return uids; 4798 } 4799 } 4800 4801 /** Returns if the UID is currently considered idle. */ 4802 @VisibleForTesting 4803 boolean isUidIdle(int uid) { 4804 return isUidIdle(uid, PROCESS_STATE_UNKNOWN); 4805 } 4806 4807 private boolean isUidIdle(int uid, int uidProcessState) { 4808 synchronized (mUidRulesFirstLock) { 4809 if (uidProcessState != PROCESS_STATE_UNKNOWN && isProcStateConsideredInteraction( 4810 uidProcessState)) { 4811 return false; 4812 } 4813 if (mAppIdleTempWhitelistAppIds.get(uid)) { 4814 // UID is temporarily allowlisted. 4815 return false; 4816 } 4817 } 4818 4819 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 4820 final int userId = UserHandle.getUserId(uid); 4821 4822 if (packages != null) { 4823 for (String packageName : packages) { 4824 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 4825 return false; 4826 } 4827 } 4828 } 4829 return true; 4830 } 4831 4832 /** 4833 * Checks if an uid has INTERNET permissions. 4834 * <p> 4835 * Useful for the cases where the lack of network access can simplify the rules. 4836 */ 4837 @GuardedBy("mUidRulesFirstLock") 4838 private boolean hasInternetPermissionUL(int uid) { 4839 try { 4840 if (mInternetPermissionMap.get(uid)) { 4841 return true; 4842 } 4843 // If the cache shows that uid doesn't have internet permission, 4844 // then always re-check with PackageManager just to be safe. 4845 final boolean hasPermission = mIPm.checkUidPermission(Manifest.permission.INTERNET, 4846 uid) == PackageManager.PERMISSION_GRANTED; 4847 mInternetPermissionMap.put(uid, hasPermission); 4848 return hasPermission; 4849 } catch (RemoteException e) { 4850 // ignored; service lives in system_server 4851 } 4852 return true; 4853 } 4854 4855 /** 4856 * Clears all state - internal and external - associated with an UID. 4857 */ 4858 @GuardedBy("mUidRulesFirstLock") 4859 private void onUidDeletedUL(int uid) { 4860 // First cleanup in-memory state synchronously... 4861 synchronized (mUidBlockedState) { 4862 mUidBlockedState.delete(uid); 4863 } 4864 mUidState.delete(uid); 4865 mActivityManagerInternal.onUidBlockedReasonsChanged(uid, BLOCKED_REASON_NONE); 4866 mUidPolicy.delete(uid); 4867 mUidFirewallStandbyRules.delete(uid); 4868 mUidFirewallDozableRules.delete(uid); 4869 mUidFirewallPowerSaveRules.delete(uid); 4870 mPowerSaveWhitelistExceptIdleAppIds.delete(uid); 4871 mPowerSaveWhitelistAppIds.delete(uid); 4872 mPowerSaveTempWhitelistAppIds.delete(uid); 4873 mAppIdleTempWhitelistAppIds.delete(uid); 4874 mUidFirewallRestrictedModeRules.delete(uid); 4875 mUidFirewallLowPowerStandbyModeRules.delete(uid); 4876 synchronized (mUidStateCallbackInfos) { 4877 mUidStateCallbackInfos.remove(uid); 4878 } 4879 4880 // ...then update iptables asynchronously. 4881 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget(); 4882 } 4883 4884 /** 4885 * Applies network rules to bandwidth and firewall controllers based on uid policy. 4886 * 4887 * <p>There are currently 4 types of restriction rules: 4888 * <ul> 4889 * <li>Doze mode 4890 * <li>App idle mode 4891 * <li>Battery Saver Mode (also referred as power save). 4892 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data'). 4893 * </ul> 4894 * 4895 * <p>This method changes both the external firewall rules and the internal state. 4896 */ 4897 @GuardedBy("mUidRulesFirstLock") 4898 private void updateRestrictionRulesForUidUL(int uid) { 4899 // Methods below only changes the firewall rules for the power-related modes. 4900 updateRuleForDeviceIdleUL(uid); 4901 updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); 4902 updateRuleForRestrictPowerUL(uid); 4903 4904 // If the uid has the necessary permissions, then it should be added to the restricted mode 4905 // firewall allowlist. 4906 updateRestrictedModeForUidUL(uid); 4907 4908 // Update internal state for power-related modes. 4909 updateRulesForPowerRestrictionsUL(uid); 4910 4911 // Update firewall and internal rules for Data Saver Mode. 4912 updateRulesForDataUsageRestrictionsUL(uid); 4913 } 4914 4915 /** 4916 * Applies network rules to bandwidth controllers based on process state and user-defined 4917 * restrictions (allowlist / denylist). 4918 * 4919 * <p> 4920 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 4921 * networks: 4922 * <ul> 4923 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (denylist). 4924 * <li>@{code bw_happy_box}: UIDs added to this chain have access (allowlist), unless they're 4925 * also in denylist. 4926 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 4927 * no UIDs other than those in allowlist will have access. 4928 * <ul> 4929 * 4930 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 4931 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundAllowlistedUid(int)} / 4932 * {@link #removeRestrictBackgroundDenylistedUid(int)} methods (for denylist and allowlist 4933 * respectively): these methods set the proper internal state (denylist / allowlist), then call 4934 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to 4935 * {@link INetworkManagementService}, but this method should also be called in events (like 4936 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 4937 * following rules should also be applied: 4938 * 4939 * <ul> 4940 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 4941 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 4942 * <li>If the foreground app was restricted by the user (i.e. has the policy 4943 * {@code POLICY_REJECT_METERED_BACKGROUND}), it should be temporarily removed from 4944 * {@code bw_penalty_box}. 4945 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 4946 * </ul> 4947 * 4948 * <p>For optimization, the rules are only applied on user apps that have internet access 4949 * permission, since there is no need to change the {@code iptables} rule if the app does not 4950 * have permission to use the internet. 4951 * 4952 * <p>The {@link #mUidBlockedState} map is used to define the transition of states of an UID. 4953 * 4954 */ 4955 private void updateRulesForDataUsageRestrictionsUL(int uid) { 4956 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 4957 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 4958 "updateRulesForDataUsageRestrictionsUL: " + uid); 4959 } 4960 try { 4961 updateRulesForDataUsageRestrictionsULInner(uid); 4962 } finally { 4963 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 4964 } 4965 } 4966 4967 @GuardedBy("mUidRulesFirstLock") 4968 private void updateRulesForDataUsageRestrictionsULInner(int uid) { 4969 if (!isUidValidForAllowlistRulesUL(uid)) { 4970 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 4971 return; 4972 } 4973 4974 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 4975 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid); 4976 final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid); 4977 4978 final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 4979 final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; 4980 4981 int newBlockedReasons = BLOCKED_REASON_NONE; 4982 int newAllowedReasons = ALLOWED_REASON_NONE; 4983 newBlockedReasons |= (isRestrictedByAdmin ? BLOCKED_METERED_REASON_ADMIN_DISABLED : 0); 4984 newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0); 4985 newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0); 4986 4987 newAllowedReasons |= (isSystem(uid) ? ALLOWED_METERED_REASON_SYSTEM : 0); 4988 newAllowedReasons |= (isForeground ? ALLOWED_METERED_REASON_FOREGROUND : 0); 4989 newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0); 4990 4991 final int oldEffectiveBlockedReasons; 4992 final int newEffectiveBlockedReasons; 4993 final int oldAllowedReasons; 4994 final int uidRules; 4995 synchronized (mUidBlockedState) { 4996 final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid( 4997 mUidBlockedState, uid); 4998 final UidBlockedState previousUidBlockedState = getOrCreateUidBlockedStateForUid( 4999 mTmpUidBlockedState, uid); 5000 previousUidBlockedState.copyFrom(uidBlockedState); 5001 5002 uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons 5003 & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons; 5004 uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons 5005 & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons; 5006 uidBlockedState.updateEffectiveBlockedReasons(); 5007 5008 oldEffectiveBlockedReasons = previousUidBlockedState.effectiveBlockedReasons; 5009 newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 5010 oldAllowedReasons = previousUidBlockedState.allowedReasons; 5011 uidRules = (oldEffectiveBlockedReasons == newEffectiveBlockedReasons) 5012 ? RULE_NONE : uidBlockedState.deriveUidRules(); 5013 5014 if (LOGV) { 5015 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")" 5016 + ": isForeground=" + isForeground 5017 + ", isDenied=" + isDenied 5018 + ", isAllowed=" + isAllowed 5019 + ", isRestrictedByAdmin=" + isRestrictedByAdmin 5020 + ", oldBlockedState=" + previousUidBlockedState 5021 + ", newBlockedState=" + uidBlockedState 5022 + ", newBlockedMeteredReasons=" + blockedReasonsToString(newBlockedReasons) 5023 + ", newAllowedMeteredReasons=" + allowedReasonsToString( 5024 newAllowedReasons)); 5025 } 5026 } 5027 if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) { 5028 handleBlockedReasonsChanged(uid, 5029 newEffectiveBlockedReasons, oldEffectiveBlockedReasons); 5030 5031 postUidRulesChangedMsg(uid, uidRules); 5032 } 5033 5034 // Note that the conditionals below are for avoiding unnecessary calls to netd. 5035 // TODO: Measure the performance for doing a no-op call to netd so that we can 5036 // remove the conditionals to simplify the logic below. We can also further reduce 5037 // some calls to netd if they turn out to be costly. 5038 final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED 5039 | BLOCKED_METERED_REASON_USER_RESTRICTED; 5040 if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE 5041 || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) { 5042 setMeteredNetworkDenylist(uid, 5043 (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE); 5044 } 5045 final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND 5046 | ALLOWED_METERED_REASON_USER_EXEMPTED; 5047 if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE 5048 || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) { 5049 setMeteredNetworkAllowlist(uid, 5050 (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE); 5051 } 5052 } 5053 5054 /** 5055 * Updates the power-related part of the {@link #mUidBlockedState} for a given map, and 5056 * notify external listeners in case of change. 5057 * <p> 5058 * There are 3 power-related rules that affects whether an app has background access on 5059 * non-metered networks, and when the condition applies and the UID is not allowed for power 5060 * restriction, it's added to the equivalent firewall chain: 5061 * <ul> 5062 * <li>App is idle: {@code fw_standby} firewall chain. 5063 * <li>Device is idle: {@code fw_dozable} firewall chain. 5064 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain. 5065 * </ul> 5066 * <p> 5067 * This method updates the power-related part of the {@link #mUidBlockedState} for a given 5068 * uid based on these modes, the UID process state (foreground or not), and the UID 5069 * allowlist state. 5070 * <p> 5071 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}. 5072 */ 5073 @GuardedBy("mUidRulesFirstLock") 5074 private void updateRulesForPowerRestrictionsUL(int uid) { 5075 updateRulesForPowerRestrictionsUL(uid, PROCESS_STATE_UNKNOWN); 5076 } 5077 5078 @GuardedBy("mUidRulesFirstLock") 5079 private void updateRulesForPowerRestrictionsUL(int uid, int uidProcState) { 5080 updateRulesForPowerRestrictionsUL(uid, isUidIdle(uid, uidProcState)); 5081 } 5082 5083 /** 5084 * Similar to above but ignores idle state if app standby is currently disabled by parole. 5085 * 5086 * @param uid the uid of the app to update rules for 5087 * @param oldUidRules the current rules for the uid, in order to determine if there's a change 5088 * @param isUidIdle whether uid is idle or not 5089 */ 5090 @GuardedBy("mUidRulesFirstLock") 5091 private void updateRulesForPowerRestrictionsUL(int uid, boolean isUidIdle) { 5092 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 5093 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 5094 "updateRulesForPowerRestrictionsUL: " + uid + "/" 5095 + (isUidIdle ? "I" : "-")); 5096 } 5097 try { 5098 updateRulesForPowerRestrictionsULInner(uid, isUidIdle); 5099 } finally { 5100 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 5101 } 5102 } 5103 5104 @GuardedBy("mUidRulesFirstLock") 5105 private void updateRulesForPowerRestrictionsULInner(int uid, boolean isUidIdle) { 5106 if (!isUidValidForDenylistRulesUL(uid)) { 5107 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); 5108 return; 5109 } 5110 5111 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid); 5112 final boolean isTop = isUidTop(uid); 5113 5114 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode); 5115 5116 final int oldEffectiveBlockedReasons; 5117 final int newEffectiveBlockedReasons; 5118 final int uidRules; 5119 synchronized (mUidBlockedState) { 5120 final UidBlockedState uidBlockedState = getOrCreateUidBlockedStateForUid( 5121 mUidBlockedState, uid); 5122 final UidBlockedState previousUidBlockedState = getOrCreateUidBlockedStateForUid( 5123 mTmpUidBlockedState, uid); 5124 previousUidBlockedState.copyFrom(uidBlockedState); 5125 5126 int newBlockedReasons = BLOCKED_REASON_NONE; 5127 int newAllowedReasons = ALLOWED_REASON_NONE; 5128 newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0); 5129 newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0); 5130 newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0); 5131 newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0); 5132 newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE); 5133 5134 newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0); 5135 newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0); 5136 newAllowedReasons |= (isTop ? ALLOWED_REASON_TOP : 0); 5137 newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true) 5138 ? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0); 5139 newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid) 5140 ? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0); 5141 newAllowedReasons |= (uidBlockedState.allowedReasons 5142 & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS); 5143 newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid)) 5144 ? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0; 5145 5146 uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons 5147 & BLOCKED_METERED_REASON_MASK) | newBlockedReasons; 5148 uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons 5149 & ALLOWED_METERED_REASON_MASK) | newAllowedReasons; 5150 uidBlockedState.updateEffectiveBlockedReasons(); 5151 5152 if (LOGV) { 5153 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")" 5154 + ", isIdle: " + isUidIdle 5155 + ", mRestrictPower: " + mRestrictPower 5156 + ", mDeviceIdleMode: " + mDeviceIdleMode 5157 + ", isForeground=" + isForeground 5158 + ", isTop=" + isTop 5159 + ", isWhitelisted=" + isWhitelisted 5160 + ", oldUidBlockedState=" + previousUidBlockedState 5161 + ", newUidBlockedState=" + uidBlockedState); 5162 } 5163 5164 oldEffectiveBlockedReasons = previousUidBlockedState.effectiveBlockedReasons; 5165 newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 5166 uidRules = oldEffectiveBlockedReasons == newEffectiveBlockedReasons 5167 ? RULE_NONE 5168 : uidBlockedState.deriveUidRules(); 5169 } 5170 if (oldEffectiveBlockedReasons != newEffectiveBlockedReasons) { 5171 handleBlockedReasonsChanged(uid, 5172 newEffectiveBlockedReasons, 5173 oldEffectiveBlockedReasons); 5174 5175 postUidRulesChangedMsg(uid, uidRules); 5176 } 5177 } 5178 5179 private class NetPolicyAppIdleStateChangeListener extends AppIdleStateChangeListener { 5180 @Override 5181 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket, 5182 int reason) { 5183 try { 5184 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 5185 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 5186 synchronized (mUidRulesFirstLock) { 5187 mLogger.appIdleStateChanged(uid, idle); 5188 updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); 5189 updateRulesForPowerRestrictionsUL(uid); 5190 } 5191 } catch (NameNotFoundException nnfe) { 5192 } 5193 } 5194 5195 @Override 5196 public void onParoleStateChanged(boolean isParoleOn) { 5197 synchronized (mUidRulesFirstLock) { 5198 mLogger.paroleStateChanged(isParoleOn); 5199 updateRulesForAppIdleParoleUL(); 5200 } 5201 } 5202 } 5203 5204 private void handleBlockedReasonsChanged(int uid, int newEffectiveBlockedReasons, 5205 int oldEffectiveBlockedReasons) { 5206 mActivityManagerInternal.onUidBlockedReasonsChanged(uid, newEffectiveBlockedReasons); 5207 postBlockedReasonsChangedMsg(uid, newEffectiveBlockedReasons, oldEffectiveBlockedReasons); 5208 } 5209 5210 private void postBlockedReasonsChangedMsg(int uid, int newEffectiveBlockedReasons, 5211 int oldEffectiveBlockedReasons) { 5212 mHandler.obtainMessage(MSG_UID_BLOCKED_REASON_CHANGED, uid, 5213 newEffectiveBlockedReasons, oldEffectiveBlockedReasons) 5214 .sendToTarget(); 5215 } 5216 5217 private void postUidRulesChangedMsg(int uid, int uidRules) { 5218 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules) 5219 .sendToTarget(); 5220 } 5221 5222 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { 5223 try { 5224 listener.onUidRulesChanged(uid, uidRules); 5225 } catch (RemoteException ignored) { 5226 // Ignore if there is an error sending the callback to the client. 5227 } 5228 } 5229 5230 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, 5231 String[] meteredIfaces) { 5232 try { 5233 listener.onMeteredIfacesChanged(meteredIfaces); 5234 } catch (RemoteException ignored) { 5235 // Ignore if there is an error sending the callback to the client. 5236 } 5237 } 5238 5239 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, 5240 boolean restrictBackground) { 5241 try { 5242 listener.onRestrictBackgroundChanged(restrictBackground); 5243 } catch (RemoteException ignored) { 5244 // Ignore if there is an error sending the callback to the client. 5245 } 5246 } 5247 5248 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid, 5249 int uidPolicies) { 5250 try { 5251 listener.onUidPoliciesChanged(uid, uidPolicies); 5252 } catch (RemoteException ignored) { 5253 // Ignore if there is an error sending the callback to the client. 5254 } 5255 } 5256 5257 private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId, 5258 int overrideMask, int overrideValue, int[] networkTypes) { 5259 try { 5260 listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes); 5261 } catch (RemoteException ignored) { 5262 // Ignore if there is an error sending the callback to the client. 5263 } 5264 } 5265 5266 private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId, 5267 SubscriptionPlan[] plans) { 5268 try { 5269 listener.onSubscriptionPlansChanged(subId, plans); 5270 } catch (RemoteException ignored) { 5271 // Ignore if there is an error sending the callback to the client. 5272 } 5273 } 5274 5275 private void dispatchBlockedReasonChanged(INetworkPolicyListener listener, int uid, 5276 int oldBlockedReasons, int newBlockedReasons) { 5277 try { 5278 listener.onBlockedReasonChanged(uid, oldBlockedReasons, newBlockedReasons); 5279 } catch (RemoteException ignored) { 5280 // Ignore if there is an error sending the callback to the client. 5281 } 5282 } 5283 5284 private final Handler.Callback mHandlerCallback = new Handler.Callback() { 5285 @Override 5286 public boolean handleMessage(Message msg) { 5287 switch (msg.what) { 5288 case MSG_RULES_CHANGED: { 5289 final int uid = msg.arg1; 5290 final int uidRules = msg.arg2; 5291 if (LOGV) { 5292 Slog.v(TAG, "Dispatching rules=" + uidRulesToString(uidRules) 5293 + " for uid=" + uid); 5294 } 5295 final int length = mListeners.beginBroadcast(); 5296 for (int i = 0; i < length; i++) { 5297 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5298 dispatchUidRulesChanged(listener, uid, uidRules); 5299 } 5300 mListeners.finishBroadcast(); 5301 return true; 5302 } 5303 case MSG_METERED_IFACES_CHANGED: { 5304 final String[] meteredIfaces = (String[]) msg.obj; 5305 final int length = mListeners.beginBroadcast(); 5306 for (int i = 0; i < length; i++) { 5307 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5308 dispatchMeteredIfacesChanged(listener, meteredIfaces); 5309 } 5310 mListeners.finishBroadcast(); 5311 return true; 5312 } 5313 case MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED: { 5314 mNetworkStats.forceUpdate(); 5315 5316 synchronized (mNetworkPoliciesSecondLock) { 5317 // Some providers might hit the limit reached event prior to others. Thus, 5318 // re-calculate and update interface quota for every provider is needed. 5319 updateNetworkRulesNL(); 5320 updateNetworkEnabledNL(); 5321 updateNotificationsNL(); 5322 } 5323 return true; 5324 } 5325 case MSG_LIMIT_REACHED: { 5326 final String iface = (String) msg.obj; 5327 synchronized (mMeteredIfacesLock) { 5328 // fast return if not needed. 5329 if (!mMeteredIfaces.contains(iface)) { 5330 return true; 5331 } 5332 } 5333 5334 // force stats update to make sure the service have the numbers that caused 5335 // alert to trigger. 5336 mNetworkStats.forceUpdate(); 5337 5338 synchronized (mNetworkPoliciesSecondLock) { 5339 updateNetworkRulesNL(); 5340 updateNetworkEnabledNL(); 5341 updateNotificationsNL(); 5342 } 5343 return true; 5344 } 5345 case MSG_RESTRICT_BACKGROUND_CHANGED: { 5346 final boolean restrictBackground = msg.arg1 != 0; 5347 final int length = mListeners.beginBroadcast(); 5348 for (int i = 0; i < length; i++) { 5349 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5350 dispatchRestrictBackgroundChanged(listener, restrictBackground); 5351 } 5352 mListeners.finishBroadcast(); 5353 final Intent intent = 5354 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 5355 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 5356 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 5357 return true; 5358 } 5359 case MSG_POLICIES_CHANGED: { 5360 final int uid = msg.arg1; 5361 final int policy = msg.arg2; 5362 final Boolean notifyApp = (Boolean) msg.obj; 5363 // First notify internal listeners... 5364 final int length = mListeners.beginBroadcast(); 5365 for (int i = 0; i < length; i++) { 5366 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5367 dispatchUidPoliciesChanged(listener, uid, policy); 5368 } 5369 mListeners.finishBroadcast(); 5370 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 5371 if (notifyApp.booleanValue()) { 5372 broadcastRestrictBackgroundChanged(uid, notifyApp); 5373 } 5374 return true; 5375 } 5376 case MSG_ADVISE_PERSIST_THRESHOLD: { 5377 final long lowestRule = (Long) msg.obj; 5378 // make sure stats are recorded frequently enough; we aim 5379 // for 2MB threshold for 2GB/month rules. 5380 final long persistThreshold = lowestRule / 1000; 5381 // TODO: Sync internal naming with the API surface. 5382 mNetworkStats.setDefaultGlobalAlert(persistThreshold); 5383 return true; 5384 } 5385 case MSG_UPDATE_INTERFACE_QUOTAS: { 5386 final IfaceQuotas val = (IfaceQuotas) msg.obj; 5387 // TODO: Consider set a new limit before removing the original one. 5388 removeInterfaceLimit(val.iface); 5389 setInterfaceLimit(val.iface, val.limit); 5390 mNetworkStats.setStatsProviderWarningAndLimitAsync(val.iface, val.warning, 5391 val.limit); 5392 return true; 5393 } 5394 case MSG_REMOVE_INTERFACE_QUOTAS: { 5395 final String iface = (String) msg.obj; 5396 removeInterfaceLimit(iface); 5397 mNetworkStats.setStatsProviderWarningAndLimitAsync(iface, QUOTA_UNLIMITED, 5398 QUOTA_UNLIMITED); 5399 return true; 5400 } 5401 case MSG_RESET_FIREWALL_RULES_BY_UID: { 5402 resetUidFirewallRules(msg.arg1); 5403 return true; 5404 } 5405 case MSG_SUBSCRIPTION_OVERRIDE: { 5406 final SomeArgs args = (SomeArgs) msg.obj; 5407 final int subId = (int) args.arg1; 5408 final int overrideMask = (int) args.arg2; 5409 final int overrideValue = (int) args.arg3; 5410 final int[] networkTypes = (int[]) args.arg4; 5411 final int length = mListeners.beginBroadcast(); 5412 for (int i = 0; i < length; i++) { 5413 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5414 dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue, 5415 networkTypes); 5416 } 5417 mListeners.finishBroadcast(); 5418 return true; 5419 } 5420 case MSG_METERED_RESTRICTED_PACKAGES_CHANGED: { 5421 final int userId = msg.arg1; 5422 final Set<String> packageNames = (Set<String>) msg.obj; 5423 setMeteredRestrictedPackagesInternal(packageNames, userId); 5424 return true; 5425 } 5426 case MSG_SET_NETWORK_TEMPLATE_ENABLED: { 5427 final NetworkTemplate template = (NetworkTemplate) msg.obj; 5428 final boolean enabled = msg.arg1 != 0; 5429 setNetworkTemplateEnabledInner(template, enabled); 5430 return true; 5431 } 5432 case MSG_SUBSCRIPTION_PLANS_CHANGED: { 5433 final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; 5434 final int subId = msg.arg1; 5435 final int length = mListeners.beginBroadcast(); 5436 for (int i = 0; i < length; i++) { 5437 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5438 dispatchSubscriptionPlansChanged(listener, subId, plans); 5439 } 5440 mListeners.finishBroadcast(); 5441 return true; 5442 } 5443 case MSG_CLEAR_SUBSCRIPTION_PLANS: { 5444 synchronized (mUidRulesFirstLock) { 5445 synchronized (mNetworkPoliciesSecondLock) { 5446 int subId = msg.arg1; 5447 if (msg.arg2 == mSetSubscriptionPlansIds.get(subId)) { 5448 if (LOGD) Slog.d(TAG, "Clearing expired subscription plans."); 5449 setSubscriptionPlansInternal(subId, new SubscriptionPlan[]{}, 5450 0 /* expirationDurationMillis */, 5451 (String) msg.obj /* callingPackage */); 5452 } else { 5453 if (LOGD) Slog.d(TAG, "Ignoring stale CLEAR_SUBSCRIPTION_PLANS."); 5454 } 5455 } 5456 } 5457 return true; 5458 } 5459 case MSG_UID_BLOCKED_REASON_CHANGED: { 5460 final int uid = msg.arg1; 5461 final int newBlockedReasons = msg.arg2; 5462 final int oldBlockedReasons = (int) msg.obj; 5463 final int length = mListeners.beginBroadcast(); 5464 for (int i = 0; i < length; i++) { 5465 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5466 dispatchBlockedReasonChanged(listener, uid, 5467 oldBlockedReasons, newBlockedReasons); 5468 } 5469 mListeners.finishBroadcast(); 5470 return true; 5471 } 5472 case MSG_UIDS_BLOCKED_REASONS_CHANGED: { 5473 final SparseArray<SomeArgs> uidStateUpdates = (SparseArray<SomeArgs>) msg.obj; 5474 final int uidsSize = uidStateUpdates.size(); 5475 final int listenersSize = mListeners.beginBroadcast(); 5476 for (int i = 0; i < listenersSize; ++i) { 5477 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 5478 for (int uidIndex = 0; uidIndex < uidsSize; ++uidIndex) { 5479 final int uid = uidStateUpdates.keyAt(uidIndex); 5480 final SomeArgs someArgs = uidStateUpdates.valueAt(uidIndex); 5481 final int oldBlockedReasons = someArgs.argi1; 5482 final int newBlockedReasons = someArgs.argi2; 5483 final int uidRules = someArgs.argi3; 5484 5485 dispatchBlockedReasonChanged(listener, uid, 5486 oldBlockedReasons, newBlockedReasons); 5487 if (LOGV) { 5488 Slog.v(TAG, "Dispatching rules=" + uidRulesToString(uidRules) 5489 + " for uid=" + uid); 5490 } 5491 dispatchUidRulesChanged(listener, uid, uidRules); 5492 } 5493 } 5494 mListeners.finishBroadcast(); 5495 5496 for (int uidIndex = 0; uidIndex < uidsSize; ++uidIndex) { 5497 uidStateUpdates.valueAt(uidIndex).recycle(); 5498 } 5499 return true; 5500 } 5501 default: { 5502 return false; 5503 } 5504 } 5505 } 5506 }; 5507 5508 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() { 5509 @Override 5510 public boolean handleMessage(Message msg) { 5511 switch (msg.what) { 5512 case UID_MSG_STATE_CHANGED: { 5513 handleUidChanged((UidStateCallbackInfo) msg.obj); 5514 return true; 5515 } 5516 case UID_MSG_GONE: { 5517 final int uid = msg.arg1; 5518 handleUidGone(uid); 5519 return true; 5520 } 5521 default: { 5522 return false; 5523 } 5524 } 5525 } 5526 }; 5527 5528 void handleUidChanged(@NonNull UidStateCallbackInfo uidStateCallbackInfo) { 5529 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); 5530 try { 5531 boolean updated; 5532 final int uid; 5533 final int procState; 5534 final long procStateSeq; 5535 final int capability; 5536 synchronized (mUidRulesFirstLock) { 5537 synchronized (mUidStateCallbackInfos) { 5538 uid = uidStateCallbackInfo.uid; 5539 procState = uidStateCallbackInfo.procState; 5540 procStateSeq = uidStateCallbackInfo.procStateSeq; 5541 capability = uidStateCallbackInfo.capability; 5542 uidStateCallbackInfo.isPending = false; 5543 } 5544 5545 // We received a uid state change callback, add it to the history so that it 5546 // will be useful for debugging. 5547 mLogger.uidStateChanged(uid, procState, procStateSeq, capability); 5548 // Now update the network policy rules as per the updated uid state. 5549 updated = updateUidStateUL(uid, procState, procStateSeq, capability); 5550 // Updating the network rules is done, so notify AMS about this. 5551 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); 5552 } 5553 // Do this without the lock held. handleUidChanged() and handleUidGone() are 5554 // called from the handler, so there's no multi-threading issue. 5555 if (updated) { 5556 updateNetworkStats(uid, isProcStateAllowedWhileOnRestrictBackground(procState)); 5557 } 5558 } finally { 5559 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 5560 } 5561 } 5562 5563 void handleUidGone(int uid) { 5564 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); 5565 try { 5566 boolean updated; 5567 synchronized (mUidRulesFirstLock) { 5568 updated = removeUidStateUL(uid); 5569 } 5570 // Do this without the lock held. handleUidChanged() and handleUidGone() are 5571 // called from the handler, so there's no multi-threading issue. 5572 if (updated) { 5573 updateNetworkStats(uid, false); 5574 } 5575 } finally { 5576 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 5577 } 5578 } 5579 5580 private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) { 5581 final PackageManager pm = mContext.getPackageManager(); 5582 final String[] packages = pm.getPackagesForUid(uid); 5583 if (packages != null) { 5584 final int userId = UserHandle.getUserId(uid); 5585 for (String packageName : packages) { 5586 final Intent intent = 5587 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 5588 intent.setPackage(packageName); 5589 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 5590 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 5591 } 5592 } 5593 } 5594 5595 private static final class IfaceQuotas { 5596 @NonNull public final String iface; 5597 // Warning and limit bytes of interface qutoas, could be QUOTA_UNLIMITED or Long.MAX_VALUE 5598 // if not set. 0 is not acceptable since kernel doesn't like 0-byte rules. 5599 public final long warning; 5600 public final long limit; 5601 5602 private IfaceQuotas(@NonNull String iface, long warning, long limit) { 5603 this.iface = iface; 5604 this.warning = warning; 5605 this.limit = limit; 5606 } 5607 } 5608 5609 private void setInterfaceQuotasAsync(@NonNull String iface, 5610 long warningBytes, long limitBytes) { 5611 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTAS, 5612 new IfaceQuotas(iface, warningBytes, limitBytes)).sendToTarget(); 5613 } 5614 5615 private void setInterfaceLimit(String iface, long limitBytes) { 5616 try { 5617 // For legacy design the data warning is covered by global alert, where the 5618 // kernel will notify upper layer for a small amount of change of traffic 5619 // statistics. Thus, passing warning is not needed. 5620 mNetworkManager.setInterfaceQuota(iface, limitBytes); 5621 } catch (IllegalStateException e) { 5622 Log.wtf(TAG, "problem setting interface quota", e); 5623 } catch (RemoteException e) { 5624 // ignored; service lives in system_server 5625 } 5626 } 5627 5628 private void removeInterfaceQuotasAsync(String iface) { 5629 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTAS, iface).sendToTarget(); 5630 } 5631 5632 private void removeInterfaceLimit(String iface) { 5633 try { 5634 mNetworkManager.removeInterfaceQuota(iface); 5635 } catch (IllegalStateException e) { 5636 Log.wtf(TAG, "problem removing interface quota", e); 5637 } catch (RemoteException e) { 5638 // ignored; service lives in system_server 5639 } 5640 } 5641 5642 private void setMeteredNetworkDenylist(int uid, boolean enable) { 5643 if (LOGV) Slog.v(TAG, "setMeteredNetworkDenylist " + uid + ": " + enable); 5644 try { 5645 mNetworkManager.setUidOnMeteredNetworkDenylist(uid, enable); 5646 mLogger.meteredDenylistChanged(uid, enable); 5647 if (Process.isApplicationUid(uid)) { 5648 final int sdkSandboxUid = Process.toSdkSandboxUid(uid); 5649 mNetworkManager.setUidOnMeteredNetworkDenylist(sdkSandboxUid, enable); 5650 mLogger.meteredDenylistChanged(sdkSandboxUid, enable); 5651 } 5652 } catch (IllegalStateException e) { 5653 Log.wtf(TAG, "problem setting denylist (" + enable + ") rules for " + uid, e); 5654 } catch (RemoteException e) { 5655 // ignored; service lives in system_server 5656 } 5657 } 5658 5659 private void setMeteredNetworkAllowlist(int uid, boolean enable) { 5660 if (LOGV) Slog.v(TAG, "setMeteredNetworkAllowlist " + uid + ": " + enable); 5661 try { 5662 mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, enable); 5663 mLogger.meteredAllowlistChanged(uid, enable); 5664 if (Process.isApplicationUid(uid)) { 5665 final int sdkSandboxUid = Process.toSdkSandboxUid(uid); 5666 mNetworkManager.setUidOnMeteredNetworkAllowlist(sdkSandboxUid, enable); 5667 mLogger.meteredAllowlistChanged(sdkSandboxUid, enable); 5668 } 5669 } catch (IllegalStateException e) { 5670 Log.wtf(TAG, "problem setting allowlist (" + enable + ") rules for " + uid, e); 5671 } catch (RemoteException e) { 5672 // ignored; service lives in system_server 5673 } 5674 } 5675 5676 private static final int CHAIN_TOGGLE_NONE = 0; 5677 private static final int CHAIN_TOGGLE_ENABLE = 1; 5678 private static final int CHAIN_TOGGLE_DISABLE = 2; 5679 @Retention(RetentionPolicy.SOURCE) 5680 @IntDef(flag = false, value = { 5681 CHAIN_TOGGLE_NONE, 5682 CHAIN_TOGGLE_ENABLE, 5683 CHAIN_TOGGLE_DISABLE 5684 }) 5685 public @interface ChainToggleType { 5686 } 5687 5688 /** 5689 * Calls {@link #setUidFirewallRulesUL(int, SparseIntArray)} and 5690 * {@link #enableFirewallChainUL(int, boolean)} synchronously. 5691 * 5692 * @param chain firewall chain. 5693 * @param uidRules new UID rules; if {@code null}, only toggles chain state. 5694 * @param toggle whether the chain should be enabled, disabled, or not changed. 5695 */ 5696 @GuardedBy("mUidRulesFirstLock") 5697 private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules, 5698 @ChainToggleType int toggle) { 5699 if (uidRules != null) { 5700 setUidFirewallRulesUL(chain, uidRules); 5701 } 5702 if (toggle != CHAIN_TOGGLE_NONE) { 5703 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE); 5704 } 5705 } 5706 5707 private void addSdkSandboxUidsIfNeeded(SparseIntArray uidRules) { 5708 final int size = uidRules.size(); 5709 final SparseIntArray sdkSandboxUids = new SparseIntArray(); 5710 for (int index = 0; index < size; index++) { 5711 final int uid = uidRules.keyAt(index); 5712 final int rule = uidRules.valueAt(index); 5713 if (Process.isApplicationUid(uid)) { 5714 sdkSandboxUids.put(Process.toSdkSandboxUid(uid), rule); 5715 } 5716 } 5717 5718 for (int index = 0; index < sdkSandboxUids.size(); index++) { 5719 final int uid = sdkSandboxUids.keyAt(index); 5720 final int rule = sdkSandboxUids.valueAt(index); 5721 uidRules.put(uid, rule); 5722 } 5723 } 5724 5725 /** 5726 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 5727 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 5728 * specified here. 5729 */ 5730 private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) { 5731 addSdkSandboxUidsIfNeeded(uidRules); 5732 try { 5733 int size = uidRules.size(); 5734 int[] uids = new int[size]; 5735 int[] rules = new int[size]; 5736 for(int index = size - 1; index >= 0; --index) { 5737 uids[index] = uidRules.keyAt(index); 5738 rules[index] = uidRules.valueAt(index); 5739 } 5740 mNetworkManager.setFirewallUidRules(chain, uids, rules); 5741 mLogger.firewallRulesChanged(chain, uids, rules); 5742 } catch (IllegalStateException e) { 5743 Log.wtf(TAG, "problem setting firewall uid rules", e); 5744 } catch (RemoteException e) { 5745 // ignored; service lives in system_server 5746 } 5747 } 5748 5749 /** 5750 * Add or remove a uid to the firewall denylist for all network ifaces. 5751 */ 5752 @GuardedBy("mUidRulesFirstLock") 5753 private void setUidFirewallRuleUL(int chain, int uid, int rule) { 5754 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 5755 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 5756 "setUidFirewallRuleUL: " + chain + "/" + uid + "/" + rule); 5757 } 5758 try { 5759 if (chain == FIREWALL_CHAIN_DOZABLE) { 5760 mUidFirewallDozableRules.put(uid, rule); 5761 } else if (chain == FIREWALL_CHAIN_STANDBY) { 5762 mUidFirewallStandbyRules.put(uid, rule); 5763 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 5764 mUidFirewallPowerSaveRules.put(uid, rule); 5765 } else if (chain == FIREWALL_CHAIN_RESTRICTED) { 5766 mUidFirewallRestrictedModeRules.put(uid, rule); 5767 } else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) { 5768 mUidFirewallLowPowerStandbyModeRules.put(uid, rule); 5769 } 5770 5771 try { 5772 mNetworkManager.setFirewallUidRule(chain, uid, rule); 5773 mLogger.uidFirewallRuleChanged(chain, uid, rule); 5774 if (Process.isApplicationUid(uid)) { 5775 final int sdkSandboxUid = Process.toSdkSandboxUid(uid); 5776 mNetworkManager.setFirewallUidRule(chain, sdkSandboxUid, rule); 5777 mLogger.uidFirewallRuleChanged(chain, sdkSandboxUid, rule); 5778 } 5779 } catch (IllegalStateException e) { 5780 Log.wtf(TAG, "problem setting firewall uid rules", e); 5781 } catch (RemoteException e) { 5782 // ignored; service lives in system_server 5783 } 5784 } finally { 5785 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 5786 } 5787 } 5788 5789 /** 5790 * Add or remove a uid to the firewall denylist for all network ifaces. 5791 */ 5792 @GuardedBy("mUidRulesFirstLock") 5793 private void enableFirewallChainUL(int chain, boolean enable) { 5794 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 5795 mFirewallChainStates.get(chain) == enable) { 5796 // All is the same, nothing to do. 5797 return; 5798 } 5799 mFirewallChainStates.put(chain, enable); 5800 try { 5801 mNetworkManager.setFirewallChainEnabled(chain, enable); 5802 mLogger.firewallChainEnabled(chain, enable); 5803 } catch (IllegalStateException e) { 5804 Log.wtf(TAG, "problem enable firewall chain", e); 5805 } catch (RemoteException e) { 5806 // ignored; service lives in system_server 5807 } 5808 } 5809 5810 /** 5811 * Resets all firewall rules associated with an UID. 5812 */ 5813 private void resetUidFirewallRules(int uid) { 5814 try { 5815 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, 5816 FIREWALL_RULE_DEFAULT); 5817 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, 5818 FIREWALL_RULE_DEFAULT); 5819 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, 5820 FIREWALL_RULE_DEFAULT); 5821 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, uid, 5822 FIREWALL_RULE_DEFAULT); 5823 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, 5824 FIREWALL_RULE_DEFAULT); 5825 mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false); 5826 mLogger.meteredAllowlistChanged(uid, false); 5827 mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false); 5828 mLogger.meteredDenylistChanged(uid, false); 5829 } catch (IllegalStateException e) { 5830 Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e); 5831 } catch (RemoteException e) { 5832 // ignored; service lives in system_server 5833 } 5834 if (Process.isApplicationUid(uid)) { 5835 resetUidFirewallRules(Process.toSdkSandboxUid(uid)); 5836 } 5837 } 5838 5839 @Deprecated 5840 private long getTotalBytes(NetworkTemplate template, long start, long end) { 5841 // Skip if not ready. NetworkStatsService will block public API calls until it is 5842 // ready. To prevent NPMS be blocked on that, skip and fail fast instead. 5843 if (!mStatsCallback.isAnyCallbackReceived()) return 0; 5844 return mDeps.getNetworkTotalBytes(template, start, end); 5845 } 5846 5847 private boolean isBandwidthControlEnabled() { 5848 final long token = Binder.clearCallingIdentity(); 5849 try { 5850 return mNetworkManager.isBandwidthControlEnabled(); 5851 } catch (RemoteException e) { 5852 // ignored; service lives in system_server 5853 return false; 5854 } finally { 5855 Binder.restoreCallingIdentity(token); 5856 } 5857 } 5858 5859 private static Intent buildSnoozeWarningIntent(NetworkTemplate template, String targetPackage) { 5860 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 5861 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5862 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 5863 intent.setPackage(targetPackage); 5864 return intent; 5865 } 5866 5867 private static Intent buildSnoozeRapidIntent(NetworkTemplate template, String targetPackage) { 5868 final Intent intent = new Intent(ACTION_SNOOZE_RAPID); 5869 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5870 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 5871 intent.setPackage(targetPackage); 5872 return intent; 5873 } 5874 5875 private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) { 5876 final Intent intent = new Intent(); 5877 intent.setComponent(ComponentName.unflattenFromString( 5878 res.getString(R.string.config_networkOverLimitComponent))); 5879 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5880 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 5881 return intent; 5882 } 5883 5884 private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) { 5885 final Intent intent = new Intent(); 5886 intent.setComponent(ComponentName.unflattenFromString( 5887 res.getString(R.string.config_dataUsageSummaryComponent))); 5888 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5889 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 5890 return intent; 5891 } 5892 5893 @VisibleForTesting 5894 void addIdleHandler(IdleHandler handler) { 5895 mHandler.getLooper().getQueue().addIdleHandler(handler); 5896 } 5897 5898 @GuardedBy("mUidRulesFirstLock") 5899 @VisibleForTesting 5900 void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) { 5901 if (mRestrictBackgroundLowPowerMode == result.batterySaverEnabled) { 5902 // Nothing changed. Nothing to do. 5903 return; 5904 } 5905 mRestrictBackgroundLowPowerMode = result.batterySaverEnabled; 5906 5907 boolean restrictBackground = mRestrictBackgroundLowPowerMode; 5908 boolean shouldInvokeRestrictBackground; 5909 // store the temporary mRestrictBackgroundChangedInBsm and update it at the end. 5910 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm; 5911 5912 if (mRestrictBackgroundLowPowerMode) { 5913 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to 5914 // turn it on. 5915 shouldInvokeRestrictBackground = !mRestrictBackground; 5916 mRestrictBackgroundBeforeBsm = mRestrictBackground; 5917 localRestrictBgChangedInBsm = false; 5918 } else { 5919 // Try to restore the restrictBackground if it doesn't change in bsm 5920 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm; 5921 restrictBackground = mRestrictBackgroundBeforeBsm; 5922 } 5923 5924 if (shouldInvokeRestrictBackground) { 5925 setRestrictBackgroundUL(restrictBackground, "low_power"); 5926 } 5927 5928 // Change it at last so setRestrictBackground() won't affect this variable 5929 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm; 5930 } 5931 5932 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 5933 final int size = source.size(); 5934 for (int i = 0; i < size; i++) { 5935 target.put(source.keyAt(i), true); 5936 } 5937 } 5938 5939 private static <T> void collectKeys(SparseArray<T> source, SparseBooleanArray target) { 5940 final int size = source.size(); 5941 for (int i = 0; i < size; i++) { 5942 target.put(source.keyAt(i), true); 5943 } 5944 } 5945 5946 @Override 5947 public void factoryReset(String subscriber) { 5948 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG); 5949 5950 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 5951 return; 5952 } 5953 5954 // Turn carrier/mobile data limit off 5955 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 5956 NetworkTemplate templateCarrier = subscriber != null 5957 ? buildTemplateCarrierMetered(subscriber) : null; 5958 NetworkTemplate templateMobile = subscriber != null 5959 ? new NetworkTemplate.Builder(MATCH_MOBILE) 5960 .setSubscriberIds(Set.of(subscriber)) 5961 .setMeteredness(android.net.NetworkStats.METERED_YES) 5962 .build() : null; 5963 for (NetworkPolicy policy : policies) { 5964 // All policies loaded from disk will be carrier templates, and setting will also only 5965 // set carrier templates, but we clear mobile templates just in case one is set by 5966 // some other caller 5967 if (policy.template.equals(templateCarrier) || policy.template.equals(templateMobile)) { 5968 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 5969 policy.inferred = false; 5970 policy.clearSnooze(); 5971 } 5972 } 5973 setNetworkPolicies(policies); 5974 5975 // Turn restrict background data off 5976 setRestrictBackground(false); 5977 5978 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 5979 // Remove app's "restrict background data" flag 5980 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 5981 setUidPolicy(uid, POLICY_NONE); 5982 } 5983 } 5984 } 5985 5986 @Override 5987 public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) { 5988 final long startTime = mStatLogger.getTime(); 5989 5990 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG); 5991 int blockedReasons; 5992 synchronized (mUidBlockedState) { 5993 final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); 5994 blockedReasons = uidBlockedState == null 5995 ? BLOCKED_REASON_NONE : uidBlockedState.effectiveBlockedReasons; 5996 if (!isNetworkMetered) { 5997 blockedReasons &= ~BLOCKED_METERED_REASON_MASK; 5998 } 5999 mLogger.networkBlocked(uid, uidBlockedState); 6000 } 6001 6002 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime); 6003 6004 return blockedReasons != BLOCKED_REASON_NONE; 6005 } 6006 6007 @Override 6008 public boolean isUidRestrictedOnMeteredNetworks(int uid) { 6009 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG); 6010 synchronized (mUidBlockedState) { 6011 final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); 6012 int blockedReasons = uidBlockedState == null 6013 ? BLOCKED_REASON_NONE : uidBlockedState.effectiveBlockedReasons; 6014 blockedReasons &= BLOCKED_METERED_REASON_MASK; 6015 return blockedReasons != BLOCKED_REASON_NONE; 6016 } 6017 } 6018 6019 private static boolean isSystem(int uid) { 6020 return uid < Process.FIRST_APPLICATION_UID; 6021 } 6022 6023 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal { 6024 6025 @Override 6026 public void resetUserState(int userId) { 6027 synchronized (mUidRulesFirstLock) { 6028 boolean changed = removeUserStateUL(userId, false, true); 6029 changed = addDefaultRestrictBackgroundAllowlistUidsUL(userId) || changed; 6030 if (changed) { 6031 synchronized (mNetworkPoliciesSecondLock) { 6032 writePolicyAL(); 6033 } 6034 } 6035 } 6036 } 6037 6038 @Override 6039 public void onTempPowerSaveWhitelistChange(int appId, boolean added, 6040 @ReasonCode int reasonCode, @Nullable String reason) { 6041 synchronized (mUidRulesFirstLock) { 6042 if (!mSystemReady) { 6043 return; 6044 } 6045 mLogger.tempPowerSaveWlChanged(appId, added, reasonCode, reason); 6046 if (added) { 6047 mPowerSaveTempWhitelistAppIds.put(appId, true); 6048 } else { 6049 mPowerSaveTempWhitelistAppIds.delete(appId); 6050 } 6051 updateRulesForTempWhitelistChangeUL(appId); 6052 } 6053 } 6054 6055 @Override 6056 public SubscriptionPlan getSubscriptionPlan(Network network) { 6057 synchronized (mNetworkPoliciesSecondLock) { 6058 final int subId = getSubIdLocked(network); 6059 return getPrimarySubscriptionPlanLocked(subId); 6060 } 6061 } 6062 6063 @Override 6064 public long getSubscriptionOpportunisticQuota(Network network, int quotaType) { 6065 final long quotaBytes; 6066 synchronized (mNetworkPoliciesSecondLock) { 6067 quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network), 6068 OPPORTUNISTIC_QUOTA_UNKNOWN); 6069 } 6070 if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) { 6071 return OPPORTUNISTIC_QUOTA_UNKNOWN; 6072 } 6073 6074 if (quotaType == QUOTA_TYPE_JOBS) { 6075 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(), 6076 NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT)); 6077 } else if (quotaType == QUOTA_TYPE_MULTIPATH) { 6078 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(), 6079 NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT)); 6080 } else { 6081 return OPPORTUNISTIC_QUOTA_UNKNOWN; 6082 } 6083 } 6084 6085 @Override 6086 public void onAdminDataAvailable() { 6087 mAdminDataAvailableLatch.countDown(); 6088 } 6089 6090 @Override 6091 public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) { 6092 NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist); 6093 } 6094 6095 @Override 6096 public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) { 6097 setMeteredRestrictedPackagesInternal(packageNames, userId); 6098 } 6099 6100 @Override 6101 public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) { 6102 mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED, 6103 userId, 0, packageNames).sendToTarget(); 6104 } 6105 6106 @Override 6107 public void setLowPowerStandbyActive(boolean active) { 6108 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setLowPowerStandbyActive"); 6109 try { 6110 synchronized (mUidRulesFirstLock) { 6111 if (mLowPowerStandbyActive == active) { 6112 return; 6113 } 6114 mLowPowerStandbyActive = active; 6115 synchronized (mNetworkPoliciesSecondLock) { 6116 if (!mSystemReady) return; 6117 } 6118 6119 forEachUid("updateRulesForRestrictPower", 6120 uid -> updateRulesForPowerRestrictionsUL(uid)); 6121 updateRulesForLowPowerStandbyUL(); 6122 } 6123 } finally { 6124 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 6125 } 6126 } 6127 6128 @Override 6129 public void setLowPowerStandbyAllowlist(int[] uids) { 6130 synchronized (mUidRulesFirstLock) { 6131 final SparseBooleanArray changedUids = new SparseBooleanArray(); 6132 for (int i = 0; i < mLowPowerStandbyAllowlistUids.size(); i++) { 6133 final int oldUid = mLowPowerStandbyAllowlistUids.keyAt(i); 6134 if (!ArrayUtils.contains(uids, oldUid)) { 6135 changedUids.put(oldUid, true); 6136 } 6137 } 6138 6139 for (int i = 0; i < changedUids.size(); i++) { 6140 final int deletedUid = changedUids.keyAt(i); 6141 mLowPowerStandbyAllowlistUids.delete(deletedUid); 6142 } 6143 6144 for (int newUid : uids) { 6145 if (mLowPowerStandbyAllowlistUids.indexOfKey(newUid) < 0) { 6146 changedUids.append(newUid, true); 6147 mLowPowerStandbyAllowlistUids.append(newUid, true); 6148 } 6149 } 6150 6151 if (!mLowPowerStandbyActive) { 6152 return; 6153 } 6154 6155 synchronized (mNetworkPoliciesSecondLock) { 6156 if (!mSystemReady) return; 6157 } 6158 6159 for (int i = 0; i < changedUids.size(); i++) { 6160 final int changedUid = changedUids.keyAt(i); 6161 updateRulesForPowerRestrictionsUL(changedUid); 6162 updateRuleForLowPowerStandbyUL(changedUid); 6163 } 6164 } 6165 } 6166 } 6167 6168 private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) { 6169 synchronized (mUidRulesFirstLock) { 6170 final Set<Integer> newRestrictedUids = new ArraySet<>(); 6171 for (String packageName : packageNames) { 6172 final int uid = getUidForPackage(packageName, userId); 6173 if (uid >= 0) { 6174 newRestrictedUids.add(uid); 6175 } 6176 } 6177 final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId); 6178 mMeteredRestrictedUids.put(userId, newRestrictedUids); 6179 handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids); 6180 mLogger.meteredRestrictedPkgsChanged(newRestrictedUids); 6181 } 6182 } 6183 6184 private int getUidForPackage(String packageName, int userId) { 6185 try { 6186 return mContext.getPackageManager().getPackageUidAsUser(packageName, 6187 PackageManager.MATCH_KNOWN_PACKAGES, userId); 6188 } catch (NameNotFoundException e) { 6189 return -1; 6190 } 6191 } 6192 6193 @GuardedBy("mNetworkPoliciesSecondLock") 6194 private int getSubIdLocked(Network network) { 6195 return mNetIdToSubId.get(network.getNetId(), INVALID_SUBSCRIPTION_ID); 6196 } 6197 6198 @GuardedBy("mNetworkPoliciesSecondLock") 6199 private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) { 6200 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId); 6201 if (!ArrayUtils.isEmpty(plans)) { 6202 for (SubscriptionPlan plan : plans) { 6203 if (plan.getCycleRule().isRecurring()) { 6204 // Recurring plans will always have an active cycle 6205 return plan; 6206 } else { 6207 // Non-recurring plans need manual test for active cycle 6208 final Range<ZonedDateTime> cycle = plan.cycleIterator().next(); 6209 if (cycle.contains(ZonedDateTime.now(mClock))) { 6210 return plan; 6211 } 6212 } 6213 } 6214 } 6215 return null; 6216 } 6217 6218 /** 6219 * This will only ever be called once - during device boot. 6220 */ 6221 private void waitForAdminData() { 6222 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { 6223 ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch, 6224 WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data"); 6225 } 6226 } 6227 6228 private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids, 6229 Set<Integer> newRestrictedUids) { 6230 if (!mNetworkManagerReady) { 6231 return; 6232 } 6233 if (oldRestrictedUids == null) { 6234 for (int uid : newRestrictedUids) { 6235 updateRulesForDataUsageRestrictionsUL(uid); 6236 } 6237 return; 6238 } 6239 for (int uid : oldRestrictedUids) { 6240 if (!newRestrictedUids.contains(uid)) { 6241 updateRulesForDataUsageRestrictionsUL(uid); 6242 } 6243 } 6244 for (int uid : newRestrictedUids) { 6245 if (!oldRestrictedUids.contains(uid)) { 6246 updateRulesForDataUsageRestrictionsUL(uid); 6247 } 6248 } 6249 } 6250 6251 @GuardedBy("mUidRulesFirstLock") 6252 private boolean isRestrictedByAdminUL(int uid) { 6253 final Set<Integer> restrictedUids = mMeteredRestrictedUids.get( 6254 UserHandle.getUserId(uid)); 6255 return restrictedUids != null && restrictedUids.contains(uid); 6256 } 6257 6258 private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle, 6259 String key, boolean defaultValue) { 6260 return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue; 6261 } 6262 6263 private static UidBlockedState getOrCreateUidBlockedStateForUid( 6264 SparseArray<UidBlockedState> uidBlockedStates, int uid) { 6265 UidBlockedState uidBlockedState = uidBlockedStates.get(uid); 6266 if (uidBlockedState == null) { 6267 uidBlockedState = new UidBlockedState(); 6268 uidBlockedStates.put(uid, uidBlockedState); 6269 } 6270 return uidBlockedState; 6271 } 6272 6273 private int getEffectiveBlockedReasons(int uid) { 6274 synchronized (mUidBlockedState) { 6275 final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); 6276 return uidBlockedState == null 6277 ? BLOCKED_REASON_NONE 6278 : uidBlockedState.effectiveBlockedReasons; 6279 } 6280 } 6281 6282 private int getBlockedReasons(int uid) { 6283 synchronized (mUidBlockedState) { 6284 final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); 6285 return uidBlockedState == null 6286 ? BLOCKED_REASON_NONE 6287 : uidBlockedState.blockedReasons; 6288 } 6289 } 6290 6291 @VisibleForTesting 6292 static final class UidBlockedState { 6293 public int blockedReasons; 6294 public int allowedReasons; 6295 public int effectiveBlockedReasons; 6296 6297 private UidBlockedState(int blockedReasons, int allowedReasons, 6298 int effectiveBlockedReasons) { 6299 this.blockedReasons = blockedReasons; 6300 this.allowedReasons = allowedReasons; 6301 this.effectiveBlockedReasons = effectiveBlockedReasons; 6302 } 6303 6304 UidBlockedState() { 6305 this(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE, BLOCKED_REASON_NONE); 6306 } 6307 6308 void updateEffectiveBlockedReasons() { 6309 if (LOGV && blockedReasons == BLOCKED_REASON_NONE) { 6310 Log.v(TAG, "updateEffectiveBlockedReasons(): no blocked reasons"); 6311 } 6312 effectiveBlockedReasons = getEffectiveBlockedReasons(blockedReasons, allowedReasons); 6313 if (LOGV) { 6314 Log.v(TAG, "updateEffectiveBlockedReasons()" 6315 + ": blockedReasons=" + Integer.toBinaryString(blockedReasons) 6316 + ", effectiveReasons=" + Integer.toBinaryString(effectiveBlockedReasons)); 6317 } 6318 } 6319 6320 @VisibleForTesting 6321 static int getEffectiveBlockedReasons(int blockedReasons, int allowedReasons) { 6322 int effectiveBlockedReasons = blockedReasons; 6323 // If the uid is not subject to any blocked reasons, then return early 6324 if (blockedReasons == BLOCKED_REASON_NONE) { 6325 return effectiveBlockedReasons; 6326 } 6327 if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) { 6328 effectiveBlockedReasons &= ALLOWED_METERED_REASON_MASK; 6329 } 6330 if ((allowedReasons & ALLOWED_METERED_REASON_SYSTEM) != 0) { 6331 effectiveBlockedReasons &= ~ALLOWED_METERED_REASON_MASK; 6332 } 6333 if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) { 6334 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; 6335 effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE; 6336 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY; 6337 } 6338 if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) { 6339 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER; 6340 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED; 6341 } 6342 if ((allowedReasons & ALLOWED_REASON_TOP) != 0) { 6343 effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY; 6344 } 6345 if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) { 6346 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; 6347 effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE; 6348 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY; 6349 } 6350 if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) { 6351 effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; 6352 effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY; 6353 } 6354 if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) { 6355 effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE; 6356 } 6357 if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) { 6358 effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER; 6359 } 6360 if ((allowedReasons & ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST) != 0) { 6361 effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY; 6362 } 6363 6364 return effectiveBlockedReasons; 6365 } 6366 6367 static int getAllowedReasonsForProcState(int procState) { 6368 if (procState > NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE) { 6369 return ALLOWED_REASON_NONE; 6370 } else if (procState <= NetworkPolicyManager.TOP_THRESHOLD_STATE) { 6371 return ALLOWED_REASON_TOP | ALLOWED_REASON_FOREGROUND 6372 | ALLOWED_METERED_REASON_FOREGROUND; 6373 } else { 6374 return ALLOWED_REASON_FOREGROUND | ALLOWED_METERED_REASON_FOREGROUND; 6375 } 6376 } 6377 6378 @Override 6379 public String toString() { 6380 return toString(blockedReasons, allowedReasons, effectiveBlockedReasons); 6381 } 6382 6383 public static String toString(int blockedReasons, int allowedReasons, 6384 int effectiveBlockedReasons) { 6385 final StringBuilder sb = new StringBuilder(); 6386 sb.append("{"); 6387 sb.append("blocked=").append(blockedReasonsToString(blockedReasons)).append(","); 6388 sb.append("allowed=").append(allowedReasonsToString(allowedReasons)).append(","); 6389 sb.append("effective=").append(blockedReasonsToString(effectiveBlockedReasons)); 6390 sb.append("}"); 6391 return sb.toString(); 6392 } 6393 6394 private static final int[] BLOCKED_REASONS = { 6395 BLOCKED_REASON_BATTERY_SAVER, 6396 BLOCKED_REASON_DOZE, 6397 BLOCKED_REASON_APP_STANDBY, 6398 BLOCKED_REASON_RESTRICTED_MODE, 6399 BLOCKED_REASON_LOW_POWER_STANDBY, 6400 BLOCKED_METERED_REASON_DATA_SAVER, 6401 BLOCKED_METERED_REASON_USER_RESTRICTED, 6402 BLOCKED_METERED_REASON_ADMIN_DISABLED, 6403 }; 6404 6405 private static final int[] ALLOWED_REASONS = { 6406 ALLOWED_REASON_SYSTEM, 6407 ALLOWED_REASON_FOREGROUND, 6408 ALLOWED_REASON_TOP, 6409 ALLOWED_REASON_POWER_SAVE_ALLOWLIST, 6410 ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST, 6411 ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS, 6412 ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST, 6413 ALLOWED_METERED_REASON_USER_EXEMPTED, 6414 ALLOWED_METERED_REASON_SYSTEM, 6415 ALLOWED_METERED_REASON_FOREGROUND, 6416 }; 6417 6418 private static String blockedReasonToString(int blockedReason) { 6419 switch (blockedReason) { 6420 case BLOCKED_REASON_NONE: 6421 return "NONE"; 6422 case BLOCKED_REASON_BATTERY_SAVER: 6423 return "BATTERY_SAVER"; 6424 case BLOCKED_REASON_DOZE: 6425 return "DOZE"; 6426 case BLOCKED_REASON_APP_STANDBY: 6427 return "APP_STANDBY"; 6428 case BLOCKED_REASON_RESTRICTED_MODE: 6429 return "RESTRICTED_MODE"; 6430 case BLOCKED_REASON_LOW_POWER_STANDBY: 6431 return "LOW_POWER_STANDBY"; 6432 case BLOCKED_METERED_REASON_DATA_SAVER: 6433 return "DATA_SAVER"; 6434 case BLOCKED_METERED_REASON_USER_RESTRICTED: 6435 return "METERED_USER_RESTRICTED"; 6436 case BLOCKED_METERED_REASON_ADMIN_DISABLED: 6437 return "METERED_ADMIN_DISABLED"; 6438 default: 6439 Slog.wtfStack(TAG, "Unknown blockedReason: " + blockedReason); 6440 return String.valueOf(blockedReason); 6441 } 6442 } 6443 6444 private static String allowedReasonToString(int allowedReason) { 6445 switch (allowedReason) { 6446 case ALLOWED_REASON_NONE: 6447 return "NONE"; 6448 case ALLOWED_REASON_SYSTEM: 6449 return "SYSTEM"; 6450 case ALLOWED_REASON_FOREGROUND: 6451 return "FOREGROUND"; 6452 case ALLOWED_REASON_TOP: 6453 return "TOP"; 6454 case ALLOWED_REASON_POWER_SAVE_ALLOWLIST: 6455 return "POWER_SAVE_ALLOWLIST"; 6456 case ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST: 6457 return "POWER_SAVE_EXCEPT_IDLE_ALLOWLIST"; 6458 case ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS: 6459 return "RESTRICTED_MODE_PERMISSIONS"; 6460 case ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST: 6461 return "LOW_POWER_STANDBY_ALLOWLIST"; 6462 case ALLOWED_METERED_REASON_USER_EXEMPTED: 6463 return "METERED_USER_EXEMPTED"; 6464 case ALLOWED_METERED_REASON_SYSTEM: 6465 return "METERED_SYSTEM"; 6466 case ALLOWED_METERED_REASON_FOREGROUND: 6467 return "METERED_FOREGROUND"; 6468 default: 6469 Slog.wtfStack(TAG, "Unknown allowedReason: " + allowedReason); 6470 return String.valueOf(allowedReason); 6471 } 6472 } 6473 6474 public static String blockedReasonsToString(int blockedReasons) { 6475 if (blockedReasons == BLOCKED_REASON_NONE) { 6476 return blockedReasonToString(BLOCKED_REASON_NONE); 6477 } 6478 final StringBuilder sb = new StringBuilder(); 6479 for (int reason : BLOCKED_REASONS) { 6480 if ((blockedReasons & reason) != 0) { 6481 sb.append(sb.length() == 0 ? "" : "|"); 6482 sb.append(blockedReasonToString(reason)); 6483 blockedReasons &= ~reason; 6484 } 6485 } 6486 if (blockedReasons != 0) { 6487 sb.append(sb.length() == 0 ? "" : "|"); 6488 sb.append(String.valueOf(blockedReasons)); 6489 Slog.wtfStack(TAG, "Unknown blockedReasons: " + blockedReasons); 6490 } 6491 return sb.toString(); 6492 } 6493 6494 public static String allowedReasonsToString(int allowedReasons) { 6495 if (allowedReasons == ALLOWED_REASON_NONE) { 6496 return allowedReasonToString(ALLOWED_REASON_NONE); 6497 } 6498 final StringBuilder sb = new StringBuilder(); 6499 for (int reason : ALLOWED_REASONS) { 6500 if ((allowedReasons & reason) != 0) { 6501 sb.append(sb.length() == 0 ? "" : "|"); 6502 sb.append(allowedReasonToString(reason)); 6503 allowedReasons &= ~reason; 6504 } 6505 } 6506 if (allowedReasons != 0) { 6507 sb.append(sb.length() == 0 ? "" : "|"); 6508 sb.append(String.valueOf(allowedReasons)); 6509 Slog.wtfStack(TAG, "Unknown allowedReasons: " + allowedReasons); 6510 } 6511 return sb.toString(); 6512 } 6513 6514 public void copyFrom(UidBlockedState uidBlockedState) { 6515 blockedReasons = uidBlockedState.blockedReasons; 6516 allowedReasons = uidBlockedState.allowedReasons; 6517 effectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; 6518 } 6519 6520 public int deriveUidRules() { 6521 int uidRule = RULE_NONE; 6522 if ((effectiveBlockedReasons & BLOCKED_REASON_RESTRICTED_MODE) != 0) { 6523 uidRule |= RULE_REJECT_RESTRICTED_MODE; 6524 } 6525 6526 int powerBlockedReasons = BLOCKED_REASON_APP_STANDBY 6527 | BLOCKED_REASON_DOZE 6528 | BLOCKED_REASON_BATTERY_SAVER 6529 | BLOCKED_REASON_LOW_POWER_STANDBY; 6530 if ((effectiveBlockedReasons & powerBlockedReasons) != 0) { 6531 uidRule |= RULE_REJECT_ALL; 6532 } else if ((blockedReasons & powerBlockedReasons) != 0) { 6533 uidRule |= RULE_ALLOW_ALL; 6534 } 6535 6536 // UidRule doesn't include RestrictBackground (DataSaver) state, so not including in 6537 // metered blocked reasons below. 6538 int meteredBlockedReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED 6539 | BLOCKED_METERED_REASON_USER_RESTRICTED; 6540 if ((effectiveBlockedReasons & meteredBlockedReasons) != 0) { 6541 uidRule |= RULE_REJECT_METERED; 6542 } else if ((blockedReasons & BLOCKED_METERED_REASON_USER_RESTRICTED) != 0 6543 && (allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) { 6544 uidRule |= RULE_TEMPORARY_ALLOW_METERED; 6545 } else if ((blockedReasons & BLOCKED_METERED_REASON_DATA_SAVER) != 0) { 6546 if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) { 6547 uidRule |= RULE_ALLOW_ALL; 6548 } else if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) { 6549 uidRule |= RULE_TEMPORARY_ALLOW_METERED; 6550 } 6551 } 6552 if (LOGV) { 6553 Slog.v(TAG, "uidBlockedState=" + this 6554 + " -> uidRule=" + uidRulesToString(uidRule)); 6555 } 6556 return uidRule; 6557 } 6558 } 6559 6560 private static class NotificationId { 6561 private final String mTag; 6562 private final int mId; 6563 6564 NotificationId(NetworkPolicy policy, int type) { 6565 mTag = buildNotificationTag(policy, type); 6566 mId = type; 6567 } 6568 6569 @Override 6570 public boolean equals(Object o) { 6571 if (this == o) return true; 6572 if (!(o instanceof NotificationId)) return false; 6573 NotificationId that = (NotificationId) o; 6574 return Objects.equals(mTag, that.mTag); 6575 } 6576 6577 @Override 6578 public int hashCode() { 6579 return Objects.hash(mTag); 6580 } 6581 6582 /** 6583 * Build unique tag that identifies an active {@link NetworkPolicy} 6584 * notification of a specific type, like {@link #TYPE_LIMIT}. 6585 */ 6586 private String buildNotificationTag(NetworkPolicy policy, int type) { 6587 return TAG + ":" + policy.template.hashCode() + ":" + type; 6588 } 6589 6590 public String getTag() { 6591 return mTag; 6592 } 6593 6594 public int getId() { 6595 return mId; 6596 } 6597 } 6598 } 6599