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