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