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