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