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