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