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