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.DUMP; 22 import static android.Manifest.permission.MANAGE_NETWORK_POLICY; 23 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 24 import static android.Manifest.permission.READ_PHONE_STATE; 25 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 26 import static android.content.Intent.ACTION_PACKAGE_ADDED; 27 import static android.content.Intent.ACTION_UID_REMOVED; 28 import static android.content.Intent.ACTION_USER_ADDED; 29 import static android.content.Intent.ACTION_USER_REMOVED; 30 import static android.content.Intent.EXTRA_UID; 31 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 32 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 33 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 34 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; 35 import static android.net.ConnectivityManager.TYPE_MOBILE; 36 import static android.net.ConnectivityManager.TYPE_WIMAX; 37 import static android.net.ConnectivityManager.isNetworkTypeMobile; 38 import static android.net.NetworkPolicy.CYCLE_NONE; 39 import static android.net.NetworkPolicy.LIMIT_DISABLED; 40 import static android.net.NetworkPolicy.SNOOZE_NEVER; 41 import static android.net.NetworkPolicy.WARNING_DISABLED; 42 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 43 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; 44 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; 45 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; 46 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; 47 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 48 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; 49 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; 50 import static android.net.NetworkPolicyManager.POLICY_NONE; 51 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 52 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 53 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 54 import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; 55 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; 56 import static android.net.NetworkPolicyManager.RULE_NONE; 57 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 58 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 59 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 60 import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 61 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 62 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 63 import static android.net.NetworkPolicyManager.uidPoliciesToString; 64 import static android.net.NetworkPolicyManager.uidRulesToString; 65 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 66 import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 67 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 68 import static android.net.NetworkTemplate.MATCH_WIFI; 69 import static android.net.NetworkTemplate.buildTemplateMobileAll; 70 import static android.net.TrafficStats.MB_IN_BYTES; 71 import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 72 import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 73 import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 74 import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 75 import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 76 import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 77 import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 78 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; 79 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; 80 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; 81 import static android.text.format.DateUtils.DAY_IN_MILLIS; 82 83 import static com.android.internal.util.ArrayUtils.appendInt; 84 import static com.android.internal.util.Preconditions.checkNotNull; 85 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 86 import static com.android.internal.util.XmlUtils.readIntAttribute; 87 import static com.android.internal.util.XmlUtils.readLongAttribute; 88 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 89 import static com.android.internal.util.XmlUtils.writeIntAttribute; 90 import static com.android.internal.util.XmlUtils.writeLongAttribute; 91 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 92 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 93 94 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 95 import static org.xmlpull.v1.XmlPullParser.END_TAG; 96 import static org.xmlpull.v1.XmlPullParser.START_TAG; 97 98 import android.Manifest; 99 import android.annotation.IntDef; 100 import android.annotation.Nullable; 101 import android.app.ActivityManager; 102 import android.app.ActivityManagerInternal; 103 import android.app.AppGlobals; 104 import android.app.AppOpsManager; 105 import android.app.IActivityManager; 106 import android.app.INotificationManager; 107 import android.app.IUidObserver; 108 import android.app.Notification; 109 import android.app.PendingIntent; 110 import android.app.usage.UsageStatsManagerInternal; 111 import android.content.BroadcastReceiver; 112 import android.content.ComponentName; 113 import android.content.Context; 114 import android.content.Intent; 115 import android.content.IntentFilter; 116 import android.content.pm.ApplicationInfo; 117 import android.content.pm.IPackageManager; 118 import android.content.pm.PackageManager; 119 import android.content.pm.PackageManager.NameNotFoundException; 120 import android.content.pm.UserInfo; 121 import android.content.res.Resources; 122 import android.net.ConnectivityManager; 123 import android.net.IConnectivityManager; 124 import android.net.INetworkManagementEventObserver; 125 import android.net.INetworkPolicyListener; 126 import android.net.INetworkPolicyManager; 127 import android.net.INetworkStatsService; 128 import android.net.LinkProperties; 129 import android.net.NetworkIdentity; 130 import android.net.NetworkInfo; 131 import android.net.NetworkPolicy; 132 import android.net.NetworkQuotaInfo; 133 import android.net.NetworkState; 134 import android.net.NetworkTemplate; 135 import android.net.wifi.WifiConfiguration; 136 import android.net.wifi.WifiInfo; 137 import android.net.wifi.WifiManager; 138 import android.os.PowerSaveState; 139 import android.os.Binder; 140 import android.os.Environment; 141 import android.os.Handler; 142 import android.os.HandlerThread; 143 import android.os.IDeviceIdleController; 144 import android.os.INetworkManagementService; 145 import android.os.Message; 146 import android.os.MessageQueue.IdleHandler; 147 import android.os.PersistableBundle; 148 import android.os.PowerManager; 149 import android.os.PowerManagerInternal; 150 import android.os.Process; 151 import android.os.RemoteCallbackList; 152 import android.os.RemoteException; 153 import android.os.ResultReceiver; 154 import android.os.ServiceManager; 155 import android.os.ShellCallback; 156 import android.os.Trace; 157 import android.os.UserHandle; 158 import android.os.UserManager; 159 import android.provider.Settings; 160 import android.telephony.CarrierConfigManager; 161 import android.telephony.SubscriptionManager; 162 import android.telephony.TelephonyManager; 163 import android.text.TextUtils; 164 import android.text.format.Formatter; 165 import android.text.format.Time; 166 import android.util.ArrayMap; 167 import android.util.ArraySet; 168 import android.util.AtomicFile; 169 import android.util.Log; 170 import android.util.NtpTrustedTime; 171 import android.util.Pair; 172 import android.util.Slog; 173 import android.util.SparseBooleanArray; 174 import android.util.SparseIntArray; 175 import android.util.TrustedTime; 176 import android.util.Xml; 177 178 import com.android.internal.R; 179 import com.android.internal.annotations.GuardedBy; 180 import com.android.internal.annotations.VisibleForTesting; 181 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 182 import com.android.internal.notification.SystemNotificationChannels; 183 import com.android.internal.telephony.PhoneConstants; 184 import com.android.internal.util.ArrayUtils; 185 import com.android.internal.util.DumpUtils; 186 import com.android.internal.util.FastXmlSerializer; 187 import com.android.internal.util.IndentingPrintWriter; 188 import com.android.server.DeviceIdleController; 189 import com.android.server.EventLogTags; 190 import com.android.server.LocalServices; 191 import com.android.server.ServiceThread; 192 import com.android.server.SystemConfig; 193 194 import com.android.server.power.BatterySaverPolicy.ServiceType; 195 import libcore.io.IoUtils; 196 197 import com.google.android.collect.Lists; 198 199 import org.xmlpull.v1.XmlPullParser; 200 import org.xmlpull.v1.XmlPullParserException; 201 import org.xmlpull.v1.XmlSerializer; 202 203 import java.io.File; 204 import java.io.FileDescriptor; 205 import java.io.FileInputStream; 206 import java.io.FileNotFoundException; 207 import java.io.FileOutputStream; 208 import java.io.IOException; 209 import java.io.PrintWriter; 210 import java.lang.annotation.Retention; 211 import java.lang.annotation.RetentionPolicy; 212 import java.nio.charset.StandardCharsets; 213 import java.util.ArrayList; 214 import java.util.Arrays; 215 import java.util.List; 216 import java.util.Calendar; 217 import java.util.Objects; 218 import java.util.concurrent.CountDownLatch; 219 import java.util.concurrent.TimeUnit; 220 221 /** 222 * Service that maintains low-level network policy rules, using 223 * {@link NetworkStatsService} statistics to drive those rules. 224 * <p> 225 * Derives active rules by combining a given policy with other system status, 226 * and delivers to listeners, such as {@link ConnectivityManager}, for 227 * enforcement. 228 * 229 * <p> 230 * This class uses 2-3 locks to synchronize state: 231 * <ul> 232 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall 233 * rules). 234 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such 235 * as network policies). 236 * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks 237 * must be held. 238 * </ul> 239 * 240 * <p> 241 * As such, methods that require synchronization have the following prefixes: 242 * <ul> 243 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}). 244 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}). 245 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock} 246 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc.. 247 * </ul> 248 */ 249 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 250 static final String TAG = "NetworkPolicy"; 251 private static final boolean LOGD = false; 252 private static final boolean LOGV = false; 253 254 private static final int VERSION_INIT = 1; 255 private static final int VERSION_ADDED_SNOOZE = 2; 256 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 257 private static final int VERSION_ADDED_METERED = 4; 258 private static final int VERSION_SPLIT_SNOOZE = 5; 259 private static final int VERSION_ADDED_TIMEZONE = 6; 260 private static final int VERSION_ADDED_INFERRED = 7; 261 private static final int VERSION_SWITCH_APP_ID = 8; 262 private static final int VERSION_ADDED_NETWORK_ID = 9; 263 private static final int VERSION_SWITCH_UID = 10; 264 private static final int VERSION_LATEST = VERSION_SWITCH_UID; 265 266 /** 267 * Max items written to {@link #ProcStateSeqHistory}. 268 */ 269 @VisibleForTesting 270 public static final int MAX_PROC_STATE_SEQ_HISTORY = 271 ActivityManager.isLowRamDeviceStatic() ? 50 : 200; 272 273 @VisibleForTesting 274 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING; 275 @VisibleForTesting 276 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT; 277 @VisibleForTesting 278 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED; 279 280 private static final String TAG_POLICY_LIST = "policy-list"; 281 private static final String TAG_NETWORK_POLICY = "network-policy"; 282 private static final String TAG_UID_POLICY = "uid-policy"; 283 private static final String TAG_APP_POLICY = "app-policy"; 284 private static final String TAG_WHITELIST = "whitelist"; 285 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background"; 286 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background"; 287 288 private static final String ATTR_VERSION = "version"; 289 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 290 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 291 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 292 private static final String ATTR_NETWORK_ID = "networkId"; 293 private static final String ATTR_CYCLE_DAY = "cycleDay"; 294 private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 295 private static final String ATTR_WARNING_BYTES = "warningBytes"; 296 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 297 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 298 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 299 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 300 private static final String ATTR_METERED = "metered"; 301 private static final String ATTR_INFERRED = "inferred"; 302 private static final String ATTR_UID = "uid"; 303 private static final String ATTR_APP_ID = "appId"; 304 private static final String ATTR_POLICY = "policy"; 305 306 private static final String ACTION_ALLOW_BACKGROUND = 307 "com.android.server.net.action.ALLOW_BACKGROUND"; 308 private static final String ACTION_SNOOZE_WARNING = 309 "com.android.server.net.action.SNOOZE_WARNING"; 310 311 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 312 313 private static final int MSG_RULES_CHANGED = 1; 314 private static final int MSG_METERED_IFACES_CHANGED = 2; 315 private static final int MSG_LIMIT_REACHED = 5; 316 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 317 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 318 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10; 319 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11; 320 private static final int MSG_POLICIES_CHANGED = 13; 321 private static final int MSG_SET_FIREWALL_RULES = 14; 322 private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15; 323 324 private static final int UID_MSG_STATE_CHANGED = 100; 325 private static final int UID_MSG_GONE = 101; 326 327 private final Context mContext; 328 private final IActivityManager mActivityManager; 329 private final INetworkStatsService mNetworkStats; 330 private final INetworkManagementService mNetworkManager; 331 private UsageStatsManagerInternal mUsageStats; 332 private final TrustedTime mTime; 333 private final UserManager mUserManager; 334 private final CarrierConfigManager mCarrierConfigManager; 335 336 private IConnectivityManager mConnManager; 337 private INotificationManager mNotifManager; 338 private PowerManagerInternal mPowerManagerInternal; 339 private IDeviceIdleController mDeviceIdleController; 340 @GuardedBy("mUidRulesFirstLock") 341 private PowerSaveState mRestrictBackgroundPowerState; 342 343 // Store the status of restrict background before turning on battery saver. 344 // Used to restore mRestrictBackground when battery saver is turned off. 345 private boolean mRestrictBackgroundBeforeBsm; 346 347 // See main javadoc for instructions on how to use these locks. 348 final Object mUidRulesFirstLock = new Object(); 349 final Object mNetworkPoliciesSecondLock = new Object(); 350 351 @GuardedBy("allLocks") volatile boolean mSystemReady; 352 353 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground; 354 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower; 355 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode; 356 // Store whether user flipped restrict background in battery saver mode 357 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm; 358 359 private final boolean mSuppressDefaultPolicy; 360 361 /** Defined network policies. */ 362 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); 363 /** Currently active network rules for ifaces. */ 364 final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>(); 365 366 /** Defined UID policies. */ 367 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray(); 368 /** Currently derived rules for each UID. */ 369 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray(); 370 371 @GuardedBy("mUidRulesFirstLock") 372 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 373 @GuardedBy("mUidRulesFirstLock") 374 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 375 @GuardedBy("mUidRulesFirstLock") 376 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 377 378 /** Set of states for the child firewall chains. True if the chain is active. */ 379 @GuardedBy("mUidRulesFirstLock") 380 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 381 382 /** 383 * UIDs that have been white-listed to always be able to have network access 384 * in power save mode, except device idle (doze) still applies. 385 * TODO: An int array might be sufficient 386 */ 387 @GuardedBy("mUidRulesFirstLock") 388 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 389 390 /** 391 * UIDs that have been white-listed to always be able to have network access 392 * in power save mode. 393 * TODO: An int array might be sufficient 394 */ 395 @GuardedBy("mUidRulesFirstLock") 396 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); 397 398 @GuardedBy("mUidRulesFirstLock") 399 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); 400 401 /** 402 * UIDs that have been initially white-listed by system to avoid restricted background. 403 */ 404 @GuardedBy("mUidRulesFirstLock") 405 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids = 406 new SparseBooleanArray(); 407 408 /** 409 * UIDs that have been initially white-listed by system to avoid restricted background, 410 * but later revoked by user. 411 */ 412 @GuardedBy("mUidRulesFirstLock") 413 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids = 414 new SparseBooleanArray(); 415 416 /** Set of ifaces that are metered. */ 417 @GuardedBy("mNetworkPoliciesSecondLock") 418 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 419 /** Set of over-limit templates that have been notified. */ 420 @GuardedBy("mNetworkPoliciesSecondLock") 421 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>(); 422 423 /** Set of currently active {@link Notification} tags. */ 424 @GuardedBy("mNetworkPoliciesSecondLock") 425 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>(); 426 427 /** Foreground at UID granularity. */ 428 @GuardedBy("mUidRulesFirstLock") 429 final SparseIntArray mUidState = new SparseIntArray(); 430 431 private final RemoteCallbackList<INetworkPolicyListener> 432 mListeners = new RemoteCallbackList<>(); 433 434 final Handler mHandler; 435 @VisibleForTesting 436 public final Handler mUidEventHandler; 437 438 private final ServiceThread mUidEventThread; 439 440 @GuardedBy("allLocks") 441 private final AtomicFile mPolicyFile; 442 443 private final AppOpsManager mAppOps; 444 445 private final IPackageManager mIPm; 446 447 private ActivityManagerInternal mActivityManagerInternal; 448 449 /** 450 * This is used for debugging purposes. Whenever the IUidObserver.onUidStateChanged is called, 451 * the uid and procStateSeq will be written to this and will be printed as part of dump. 452 */ 453 @VisibleForTesting 454 public ProcStateSeqHistory mObservedHistory 455 = new ProcStateSeqHistory(MAX_PROC_STATE_SEQ_HISTORY); 456 457 // TODO: keep whitelist of system-critical services that should never have 458 // rules enforced, such as system, phone, and radio UIDs. 459 460 // TODO: migrate notifications to SystemUI 461 NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkStatsService networkStats, INetworkManagementService networkManagement)462 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 463 INetworkStatsService networkStats, INetworkManagementService networkManagement) { 464 this(context, activityManager, networkStats, networkManagement, 465 AppGlobals.getPackageManager(), NtpTrustedTime.getInstance(context), getSystemDir(), 466 false); 467 } 468 getSystemDir()469 private static File getSystemDir() { 470 return new File(Environment.getDataDirectory(), "system"); 471 } 472 NetworkPolicyManagerService(Context context, IActivityManager activityManager, INetworkStatsService networkStats, INetworkManagementService networkManagement, IPackageManager pm, TrustedTime time, File systemDir, boolean suppressDefaultPolicy)473 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 474 INetworkStatsService networkStats, INetworkManagementService networkManagement, 475 IPackageManager pm, TrustedTime time, File systemDir, boolean suppressDefaultPolicy) { 476 mContext = checkNotNull(context, "missing context"); 477 mActivityManager = checkNotNull(activityManager, "missing activityManager"); 478 mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 479 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 480 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService( 481 Context.DEVICE_IDLE_CONTROLLER)); 482 mTime = checkNotNull(time, "missing TrustedTime"); 483 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 484 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); 485 mIPm = pm; 486 487 HandlerThread thread = new HandlerThread(TAG); 488 thread.start(); 489 mHandler = new Handler(thread.getLooper(), mHandlerCallback); 490 491 // We create another thread for the UID events, which are more time-critical. 492 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND, 493 /*allowIo=*/ false); 494 mUidEventThread.start(); 495 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback); 496 497 mSuppressDefaultPolicy = suppressDefaultPolicy; 498 499 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 500 501 mAppOps = context.getSystemService(AppOpsManager.class); 502 503 // Expose private service for system components to use. 504 LocalServices.addService(NetworkPolicyManagerInternal.class, 505 new NetworkPolicyManagerInternalImpl()); 506 } 507 bindConnectivityManager(IConnectivityManager connManager)508 public void bindConnectivityManager(IConnectivityManager connManager) { 509 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 510 } 511 bindNotificationManager(INotificationManager notifManager)512 public void bindNotificationManager(INotificationManager notifManager) { 513 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 514 } 515 updatePowerSaveWhitelistUL()516 void updatePowerSaveWhitelistUL() { 517 try { 518 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle(); 519 mPowerSaveWhitelistExceptIdleAppIds.clear(); 520 if (whitelist != null) { 521 for (int uid : whitelist) { 522 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); 523 } 524 } 525 whitelist = mDeviceIdleController.getAppIdWhitelist(); 526 mPowerSaveWhitelistAppIds.clear(); 527 if (whitelist != null) { 528 for (int uid : whitelist) { 529 mPowerSaveWhitelistAppIds.put(uid, true); 530 } 531 } 532 } catch (RemoteException e) { 533 } 534 } 535 536 /** 537 * Whitelists pre-defined apps for restrict background, but only if the user didn't already 538 * revoke the whitelist. 539 * 540 * @return whether any uid has been whitelisted. 541 */ addDefaultRestrictBackgroundWhitelistUidsUL()542 boolean addDefaultRestrictBackgroundWhitelistUidsUL() { 543 final List<UserInfo> users = mUserManager.getUsers(); 544 final int numberUsers = users.size(); 545 546 boolean changed = false; 547 for (int i = 0; i < numberUsers; i++) { 548 final UserInfo user = users.get(i); 549 changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed; 550 } 551 return changed; 552 } 553 addDefaultRestrictBackgroundWhitelistUidsUL(int userId)554 private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) { 555 final SystemConfig sysConfig = SystemConfig.getInstance(); 556 final PackageManager pm = mContext.getPackageManager(); 557 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave(); 558 boolean changed = false; 559 for (int i = 0; i < allowDataUsage.size(); i++) { 560 final String pkg = allowDataUsage.valueAt(i); 561 if (LOGD) 562 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg 563 + " and user " + userId); 564 final ApplicationInfo app; 565 try { 566 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId); 567 } catch (PackageManager.NameNotFoundException e) { 568 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg); 569 // Ignore it - some apps on allow-in-data-usage-save are optional. 570 continue; 571 } 572 if (!app.isPrivilegedApp()) { 573 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): " 574 + "skipping non-privileged app " + pkg); 575 continue; 576 } 577 final int uid = UserHandle.getUid(userId, app.uid); 578 mDefaultRestrictBackgroundWhitelistUids.append(uid, true); 579 if (LOGD) 580 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted " 581 + "background whitelist. Revoked status: " 582 + mRestrictBackgroundWhitelistRevokedUids.get(uid)); 583 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 584 if (LOGD) 585 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user " 586 + userId + ") to restrict background whitelist"); 587 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false); 588 changed = true; 589 } 590 } 591 return changed; 592 } 593 updatePowerSaveTempWhitelistUL()594 void updatePowerSaveTempWhitelistUL() { 595 try { 596 // Clear the states of the current whitelist 597 final int N = mPowerSaveTempWhitelistAppIds.size(); 598 for (int i = 0; i < N; i++) { 599 mPowerSaveTempWhitelistAppIds.setValueAt(i, false); 600 } 601 // Update the states with the new whitelist 602 final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist(); 603 if (whitelist != null) { 604 for (int uid : whitelist) { 605 mPowerSaveTempWhitelistAppIds.put(uid, true); 606 } 607 } 608 } catch (RemoteException e) { 609 } 610 } 611 612 /** 613 * Remove unnecessary entries in the temp whitelist 614 */ purgePowerSaveTempWhitelistUL()615 void purgePowerSaveTempWhitelistUL() { 616 final int N = mPowerSaveTempWhitelistAppIds.size(); 617 for (int i = N - 1; i >= 0; i--) { 618 if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) { 619 mPowerSaveTempWhitelistAppIds.removeAt(i); 620 } 621 } 622 } 623 initService(CountDownLatch initCompleteSignal)624 private void initService(CountDownLatch initCompleteSignal) { 625 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady"); 626 final int oldPriority = Process.getThreadPriority(Process.myTid()); 627 try { 628 // Boost thread's priority during system server init 629 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 630 if (!isBandwidthControlEnabled()) { 631 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 632 return; 633 } 634 635 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); 636 637 synchronized (mUidRulesFirstLock) { 638 synchronized (mNetworkPoliciesSecondLock) { 639 updatePowerSaveWhitelistUL(); 640 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 641 mPowerManagerInternal.registerLowPowerModeObserver( 642 new PowerManagerInternal.LowPowerModeListener() { 643 @Override 644 public int getServiceType() { 645 return ServiceType.NETWORK_FIREWALL; 646 } 647 648 @Override 649 public void onLowPowerModeChanged(PowerSaveState result) { 650 final boolean enabled = result.batterySaverEnabled; 651 if (LOGD) { 652 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")"); 653 } 654 synchronized (mUidRulesFirstLock) { 655 if (mRestrictPower != enabled) { 656 mRestrictPower = enabled; 657 updateRulesForRestrictPowerUL(); 658 } 659 } 660 } 661 }); 662 mRestrictPower = mPowerManagerInternal.getLowPowerState( 663 ServiceType.NETWORK_FIREWALL).batterySaverEnabled; 664 665 mSystemReady = true; 666 667 // read policy from disk 668 readPolicyAL(); 669 670 // Update the restrictBackground if battery saver is turned on 671 mRestrictBackgroundBeforeBsm = mRestrictBackground; 672 mRestrictBackgroundPowerState = mPowerManagerInternal 673 .getLowPowerState(ServiceType.DATA_SAVER); 674 final boolean localRestrictBackground = 675 mRestrictBackgroundPowerState.batterySaverEnabled; 676 if (localRestrictBackground && localRestrictBackground != mRestrictBackground) { 677 mRestrictBackground = localRestrictBackground; 678 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, 679 mRestrictBackground ? 1 : 0, 0).sendToTarget(); 680 } 681 mPowerManagerInternal.registerLowPowerModeObserver( 682 new PowerManagerInternal.LowPowerModeListener() { 683 @Override 684 public int getServiceType() { 685 return ServiceType.DATA_SAVER; 686 } 687 688 @Override 689 public void onLowPowerModeChanged(PowerSaveState result) { 690 synchronized (mUidRulesFirstLock) { 691 updateRestrictBackgroundByLowPowerModeUL(result); 692 } 693 } 694 }); 695 696 if (addDefaultRestrictBackgroundWhitelistUidsUL()) { 697 writePolicyAL(); 698 } 699 700 setRestrictBackgroundUL(mRestrictBackground); 701 updateRulesForGlobalChangeAL(false); 702 updateNotificationsNL(); 703 } 704 } 705 706 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 707 try { 708 mActivityManager.registerUidObserver(mUidObserver, 709 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE, 710 ActivityManager.PROCESS_STATE_UNKNOWN, null); 711 mNetworkManager.registerObserver(mAlertObserver); 712 } catch (RemoteException e) { 713 // ignored; both services live in system_server 714 } 715 716 // listen for changes to power save whitelist 717 final IntentFilter whitelistFilter = new IntentFilter( 718 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 719 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); 720 721 DeviceIdleController.LocalService deviceIdleService 722 = LocalServices.getService(DeviceIdleController.LocalService.class); 723 deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback); 724 725 // watch for network interfaces to be claimed 726 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 727 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 728 729 // listen for package changes to update policy 730 final IntentFilter packageFilter = new IntentFilter(); 731 packageFilter.addAction(ACTION_PACKAGE_ADDED); 732 packageFilter.addDataScheme("package"); 733 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 734 735 // listen for UID changes to update policy 736 mContext.registerReceiver( 737 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 738 739 // listen for user changes to update policy 740 final IntentFilter userFilter = new IntentFilter(); 741 userFilter.addAction(ACTION_USER_ADDED); 742 userFilter.addAction(ACTION_USER_REMOVED); 743 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 744 745 // listen for stats update events 746 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 747 mContext.registerReceiver( 748 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 749 750 // listen for restrict background changes from notifications 751 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 752 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 753 754 // listen for snooze warning from notifications 755 final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING); 756 mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter, 757 MANAGE_NETWORK_POLICY, mHandler); 758 759 // listen for configured wifi networks to be removed 760 final IntentFilter wifiConfigFilter = 761 new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); 762 mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler); 763 764 // listen for wifi state changes to catch metered hint 765 final IntentFilter wifiStateFilter = new IntentFilter( 766 WifiManager.NETWORK_STATE_CHANGED_ACTION); 767 mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); 768 769 // listen for carrier config changes to update data cycle information 770 final IntentFilter carrierConfigFilter = new IntentFilter( 771 ACTION_CARRIER_CONFIG_CHANGED); 772 mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler); 773 774 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); 775 // tell systemReady() that the service has been initialized 776 initCompleteSignal.countDown(); 777 } finally { 778 // Restore the default priority after init is done 779 Process.setThreadPriority(oldPriority); 780 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 781 } 782 } 783 networkScoreAndNetworkManagementServiceReady()784 public CountDownLatch networkScoreAndNetworkManagementServiceReady() { 785 final CountDownLatch initCompleteSignal = new CountDownLatch(1); 786 mHandler.post(() -> initService(initCompleteSignal)); 787 return initCompleteSignal; 788 } 789 systemReady(CountDownLatch initCompleteSignal)790 public void systemReady(CountDownLatch initCompleteSignal) { 791 // wait for initService to complete 792 try { 793 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) { 794 throw new IllegalStateException("Service " + TAG +" init timeout"); 795 } 796 } catch (InterruptedException e) { 797 Thread.currentThread().interrupt(); 798 throw new IllegalStateException("Service " + TAG + " init interrupted", e); 799 } 800 } 801 802 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 803 @Override public void onUidStateChanged(int uid, int procState, 804 long procStateSeq) throws RemoteException { 805 mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, 806 uid, procState, procStateSeq).sendToTarget(); 807 } 808 809 @Override public void onUidGone(int uid, boolean disabled) throws RemoteException { 810 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget(); 811 } 812 813 @Override public void onUidActive(int uid) throws RemoteException { 814 } 815 816 @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException { 817 } 818 }; 819 820 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { 821 @Override 822 public void onReceive(Context context, Intent intent) { 823 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected 824 synchronized (mUidRulesFirstLock) { 825 updatePowerSaveWhitelistUL(); 826 updateRulesForRestrictPowerUL(); 827 updateRulesForAppIdleUL(); 828 } 829 } 830 }; 831 832 final private Runnable mTempPowerSaveChangedCallback = new Runnable() { 833 @Override 834 public void run() { 835 synchronized (mUidRulesFirstLock) { 836 updatePowerSaveTempWhitelistUL(); 837 updateRulesForTempWhitelistChangeUL(); 838 purgePowerSaveTempWhitelistUL(); 839 } 840 } 841 }; 842 843 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 844 @Override 845 public void onReceive(Context context, Intent intent) { 846 // on background handler thread, and PACKAGE_ADDED is protected 847 848 final String action = intent.getAction(); 849 final int uid = intent.getIntExtra(EXTRA_UID, -1); 850 if (uid == -1) return; 851 852 if (ACTION_PACKAGE_ADDED.equals(action)) { 853 // update rules for UID, since it might be subject to 854 // global background data policy 855 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 856 synchronized (mUidRulesFirstLock) { 857 updateRestrictionRulesForUidUL(uid); 858 } 859 } 860 } 861 }; 862 863 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 864 @Override 865 public void onReceive(Context context, Intent intent) { 866 // on background handler thread, and UID_REMOVED is protected 867 868 final int uid = intent.getIntExtra(EXTRA_UID, -1); 869 if (uid == -1) return; 870 871 // remove any policy and update rules to clean up 872 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 873 synchronized (mUidRulesFirstLock) { 874 onUidDeletedUL(uid); 875 synchronized (mNetworkPoliciesSecondLock) { 876 writePolicyAL(); 877 } 878 } 879 } 880 }; 881 882 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 883 @Override 884 public void onReceive(Context context, Intent intent) { 885 // on background handler thread, and USER_ADDED and USER_REMOVED 886 // broadcasts are protected 887 888 final String action = intent.getAction(); 889 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 890 if (userId == -1) return; 891 892 switch (action) { 893 case ACTION_USER_REMOVED: 894 case ACTION_USER_ADDED: 895 synchronized (mUidRulesFirstLock) { 896 // Remove any persistable state for the given user; both cleaning up after a 897 // USER_REMOVED, and one last sanity check during USER_ADDED 898 removeUserStateUL(userId, true); 899 if (action == ACTION_USER_ADDED) { 900 // Add apps that are whitelisted by default. 901 addDefaultRestrictBackgroundWhitelistUidsUL(userId); 902 } 903 // Update global restrict for that user 904 synchronized (mNetworkPoliciesSecondLock) { 905 updateRulesForGlobalChangeAL(true); 906 } 907 } 908 break; 909 } 910 } 911 }; 912 913 /** 914 * Receiver that watches for {@link INetworkStatsService} updates, which we 915 * use to check against {@link NetworkPolicy#warningBytes}. 916 */ 917 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 918 @Override 919 public void onReceive(Context context, Intent intent) { 920 // on background handler thread, and verified 921 // READ_NETWORK_USAGE_HISTORY permission above. 922 923 maybeRefreshTrustedTime(); 924 synchronized (mNetworkPoliciesSecondLock) { 925 updateNetworkEnabledNL(); 926 updateNotificationsNL(); 927 } 928 } 929 }; 930 931 /** 932 * Receiver that watches for {@link Notification} control of 933 * {@link #mRestrictBackground}. 934 */ 935 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 936 @Override 937 public void onReceive(Context context, Intent intent) { 938 // on background handler thread, and verified MANAGE_NETWORK_POLICY 939 // permission above. 940 941 setRestrictBackground(false); 942 } 943 }; 944 945 /** 946 * Receiver that watches for {@link Notification} control of 947 * {@link NetworkPolicy#lastWarningSnooze}. 948 */ 949 final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { 950 @Override 951 public void onReceive(Context context, Intent intent) { 952 // on background handler thread, and verified MANAGE_NETWORK_POLICY 953 // permission above. 954 955 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 956 performSnooze(template, TYPE_WARNING); 957 } 958 }; 959 960 /** 961 * Receiver that watches for {@link WifiConfiguration} to be changed. 962 */ 963 final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { 964 @Override 965 public void onReceive(Context context, Intent intent) { 966 // on background handler thread, and verified CONNECTIVITY_INTERNAL 967 // permission above. 968 969 final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED); 970 if (reason == CHANGE_REASON_REMOVED) { 971 final WifiConfiguration config = intent.getParcelableExtra( 972 EXTRA_WIFI_CONFIGURATION); 973 if (config.SSID != null) { 974 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID); 975 synchronized (mUidRulesFirstLock) { 976 synchronized (mNetworkPoliciesSecondLock) { 977 if (mNetworkPolicy.containsKey(template)) { 978 mNetworkPolicy.remove(template); 979 writePolicyAL(); 980 } 981 } 982 } 983 } 984 } 985 } 986 }; 987 988 /** 989 * Receiver that watches {@link WifiInfo} state changes to infer metered 990 * state. Ignores hints when policy is user-defined. 991 */ 992 final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 993 @Override 994 public void onReceive(Context context, Intent intent) { 995 // on background handler thread, and verified CONNECTIVITY_INTERNAL 996 // permission above. 997 998 // ignore when not connected 999 final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 1000 if (!netInfo.isConnected()) return; 1001 1002 final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO); 1003 final boolean meteredHint = info.getMeteredHint(); 1004 1005 final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID()); 1006 synchronized (mUidRulesFirstLock) { 1007 synchronized (mNetworkPoliciesSecondLock) { 1008 NetworkPolicy policy = mNetworkPolicy.get(template); 1009 if (policy == null && meteredHint) { 1010 // policy doesn't exist, and AP is hinting that it's 1011 // metered: create an inferred policy. 1012 policy = newWifiPolicy(template, meteredHint); 1013 addNetworkPolicyAL(policy); 1014 1015 } else if (policy != null && policy.inferred) { 1016 // policy exists, and was inferred: update its current 1017 // metered state. 1018 policy.metered = meteredHint; 1019 1020 // since this is inferred for each wifi session, just update 1021 // rules without persisting. 1022 updateNetworkRulesNL(); 1023 } 1024 } 1025 } 1026 } 1027 }; 1028 newWifiPolicy(NetworkTemplate template, boolean metered)1029 static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) { 1030 return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC, 1031 WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, 1032 metered, true); 1033 } 1034 1035 /** 1036 * Observer that watches for {@link INetworkManagementService} alerts. 1037 */ 1038 final private INetworkManagementEventObserver mAlertObserver 1039 = new BaseNetworkObserver() { 1040 @Override 1041 public void limitReached(String limitName, String iface) { 1042 // only someone like NMS should be calling us 1043 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1044 1045 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 1046 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 1047 } 1048 } 1049 }; 1050 1051 /** 1052 * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 1053 * to show visible notifications as needed. 1054 */ updateNotificationsNL()1055 void updateNotificationsNL() { 1056 if (LOGV) Slog.v(TAG, "updateNotificationsNL()"); 1057 1058 // keep track of previously active notifications 1059 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs); 1060 mActiveNotifs.clear(); 1061 1062 // TODO: when switching to kernel notifications, compute next future 1063 // cycle boundary to recompute notifications. 1064 1065 // examine stats for each active policy 1066 final long currentTime = currentTimeMillis(); 1067 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1068 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1069 // ignore policies that aren't relevant to user 1070 if (!isTemplateRelevant(policy.template)) continue; 1071 if (!policy.hasCycle()) continue; 1072 1073 final long start = computeLastCycleBoundary(currentTime, policy); 1074 final long end = currentTime; 1075 final long totalBytes = getTotalBytes(policy.template, start, end); 1076 1077 if (policy.isOverLimit(totalBytes)) { 1078 if (policy.lastLimitSnooze >= start) { 1079 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 1080 } else { 1081 enqueueNotification(policy, TYPE_LIMIT, totalBytes); 1082 notifyOverLimitNL(policy.template); 1083 } 1084 1085 } else { 1086 notifyUnderLimitNL(policy.template); 1087 1088 if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) { 1089 enqueueNotification(policy, TYPE_WARNING, totalBytes); 1090 } 1091 } 1092 } 1093 1094 // cancel stale notifications that we didn't renew above 1095 for (int i = beforeNotifs.size()-1; i >= 0; i--) { 1096 final NotificationId notificationId = beforeNotifs.valueAt(i); 1097 if (!mActiveNotifs.contains(notificationId)) { 1098 cancelNotification(notificationId); 1099 } 1100 } 1101 } 1102 1103 /** 1104 * Test if given {@link NetworkTemplate} is relevant to user based on 1105 * current device state, such as when 1106 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 1107 * data connection status. 1108 */ isTemplateRelevant(NetworkTemplate template)1109 private boolean isTemplateRelevant(NetworkTemplate template) { 1110 if (template.isMatchRuleMobile()) { 1111 final TelephonyManager tele = TelephonyManager.from(mContext); 1112 final SubscriptionManager sub = SubscriptionManager.from(mContext); 1113 1114 // Mobile template is relevant when any active subscriber matches 1115 final int[] subIds = sub.getActiveSubscriptionIdList(); 1116 for (int subId : subIds) { 1117 final String subscriberId = tele.getSubscriberId(subId); 1118 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1119 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1120 if (template.matches(probeIdent)) { 1121 return true; 1122 } 1123 } 1124 return false; 1125 } else { 1126 return true; 1127 } 1128 } 1129 1130 /** 1131 * Notify that given {@link NetworkTemplate} is over 1132 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 1133 */ notifyOverLimitNL(NetworkTemplate template)1134 private void notifyOverLimitNL(NetworkTemplate template) { 1135 if (!mOverLimitNotified.contains(template)) { 1136 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template)); 1137 mOverLimitNotified.add(template); 1138 } 1139 } 1140 notifyUnderLimitNL(NetworkTemplate template)1141 private void notifyUnderLimitNL(NetworkTemplate template) { 1142 mOverLimitNotified.remove(template); 1143 } 1144 1145 /** 1146 * Show notification for combined {@link NetworkPolicy} and specific type, 1147 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 1148 */ enqueueNotification(NetworkPolicy policy, int type, long totalBytes)1149 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 1150 final NotificationId notificationId = new NotificationId(policy, type); 1151 final Notification.Builder builder = 1152 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS); 1153 builder.setOnlyAlertOnce(true); 1154 builder.setWhen(0L); 1155 builder.setColor(mContext.getColor( 1156 com.android.internal.R.color.system_notification_accent_color)); 1157 1158 final Resources res = mContext.getResources(); 1159 CharSequence body = null; 1160 switch (type) { 1161 case TYPE_WARNING: { 1162 final CharSequence title = res.getText(R.string.data_usage_warning_title); 1163 body = res.getString(R.string.data_usage_warning_body); 1164 1165 builder.setSmallIcon(R.drawable.stat_notify_error); 1166 builder.setTicker(title); 1167 builder.setContentTitle(title); 1168 builder.setContentText(body); 1169 builder.setDefaults(Notification.DEFAULT_ALL); 1170 builder.setChannelId(SystemNotificationChannels.NETWORK_ALERTS); 1171 1172 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template); 1173 builder.setDeleteIntent(PendingIntent.getBroadcast( 1174 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1175 1176 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template); 1177 builder.setContentIntent(PendingIntent.getActivity( 1178 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 1179 1180 break; 1181 } 1182 case TYPE_LIMIT: { 1183 body = res.getText(R.string.data_usage_limit_body); 1184 1185 final CharSequence title; 1186 int icon = R.drawable.stat_notify_disabled_data; 1187 switch (policy.template.getMatchRule()) { 1188 case MATCH_MOBILE_3G_LOWER: 1189 title = res.getText(R.string.data_usage_3g_limit_title); 1190 break; 1191 case MATCH_MOBILE_4G: 1192 title = res.getText(R.string.data_usage_4g_limit_title); 1193 break; 1194 case MATCH_MOBILE_ALL: 1195 title = res.getText(R.string.data_usage_mobile_limit_title); 1196 break; 1197 case MATCH_WIFI: 1198 title = res.getText(R.string.data_usage_wifi_limit_title); 1199 icon = R.drawable.stat_notify_error; 1200 break; 1201 default: 1202 title = null; 1203 break; 1204 } 1205 1206 builder.setOngoing(true); 1207 builder.setSmallIcon(icon); 1208 builder.setTicker(title); 1209 builder.setContentTitle(title); 1210 builder.setContentText(body); 1211 1212 final Intent intent = buildNetworkOverLimitIntent(res, policy.template); 1213 builder.setContentIntent(PendingIntent.getActivity( 1214 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1215 break; 1216 } 1217 case TYPE_LIMIT_SNOOZED: { 1218 final long overBytes = totalBytes - policy.limitBytes; 1219 body = res.getString(R.string.data_usage_limit_snoozed_body, 1220 Formatter.formatFileSize(mContext, overBytes)); 1221 1222 final CharSequence title; 1223 switch (policy.template.getMatchRule()) { 1224 case MATCH_MOBILE_3G_LOWER: 1225 title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 1226 break; 1227 case MATCH_MOBILE_4G: 1228 title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 1229 break; 1230 case MATCH_MOBILE_ALL: 1231 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 1232 break; 1233 case MATCH_WIFI: 1234 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 1235 break; 1236 default: 1237 title = null; 1238 break; 1239 } 1240 1241 builder.setOngoing(true); 1242 builder.setSmallIcon(R.drawable.stat_notify_error); 1243 builder.setTicker(title); 1244 builder.setContentTitle(title); 1245 builder.setContentText(body); 1246 1247 final Intent intent = buildViewDataUsageIntent(res, policy.template); 1248 builder.setContentIntent(PendingIntent.getActivity( 1249 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 1250 break; 1251 } 1252 } 1253 1254 // TODO: move to NotificationManager once we can mock it 1255 try { 1256 final String packageName = mContext.getPackageName(); 1257 if (!TextUtils.isEmpty(body)) { 1258 builder.setStyle(new Notification.BigTextStyle() 1259 .bigText(body)); 1260 } 1261 mNotifManager.enqueueNotificationWithTag( 1262 packageName, packageName, notificationId.getTag(), notificationId.getId(), 1263 builder.build(), UserHandle.USER_ALL); 1264 mActiveNotifs.add(notificationId); 1265 } catch (RemoteException e) { 1266 // ignored; service lives in system_server 1267 } 1268 } 1269 cancelNotification(NotificationId notificationId)1270 private void cancelNotification(NotificationId notificationId) { 1271 // TODO: move to NotificationManager once we can mock it 1272 try { 1273 final String packageName = mContext.getPackageName(); 1274 mNotifManager.cancelNotificationWithTag( 1275 packageName, notificationId.getTag(), notificationId.getId(), 1276 UserHandle.USER_ALL); 1277 } catch (RemoteException e) { 1278 // ignored; service lives in system_server 1279 } 1280 } 1281 1282 /** 1283 * Receiver that watches for {@link IConnectivityManager} to claim network 1284 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 1285 */ 1286 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 1287 @Override 1288 public void onReceive(Context context, Intent intent) { 1289 // on background handler thread, and verified CONNECTIVITY_INTERNAL 1290 // permission above. 1291 1292 maybeRefreshTrustedTime(); 1293 synchronized (mUidRulesFirstLock) { 1294 synchronized (mNetworkPoliciesSecondLock) { 1295 ensureActiveMobilePolicyAL(); 1296 normalizePoliciesNL(); 1297 updateNetworkEnabledNL(); 1298 updateNetworkRulesNL(); 1299 updateNotificationsNL(); 1300 } 1301 } 1302 } 1303 }; 1304 1305 /** 1306 * Update mobile policies with data cycle information from {@link CarrierConfigManager} 1307 * if necessary. 1308 * 1309 * @param subId that has its associated NetworkPolicy updated if necessary 1310 * @return if any policies were updated 1311 */ maybeUpdateMobilePolicyCycleNL(int subId)1312 private boolean maybeUpdateMobilePolicyCycleNL(int subId) { 1313 if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleNL()"); 1314 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); 1315 1316 if (config == null) { 1317 return false; 1318 } 1319 1320 boolean policyUpdated = false; 1321 final String subscriberId = TelephonyManager.from(mContext).getSubscriberId(subId); 1322 1323 // find and update the mobile NetworkPolicy for this subscriber id 1324 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1325 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1326 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1327 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1328 if (template.matches(probeIdent)) { 1329 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1330 1331 // only update the policy if the user didn't change any of the defaults. 1332 if (!policy.inferred) { 1333 // TODO: inferred could be split, so that if a user changes their data limit or 1334 // warning, it doesn't prevent their cycle date from being updated. 1335 if (LOGD) Slog.v(TAG, "Didn't update NetworkPolicy because policy.inferred"); 1336 continue; 1337 } 1338 1339 final int cycleDay = getCycleDayFromCarrierConfig(config, policy.cycleDay); 1340 final long warningBytes = getWarningBytesFromCarrierConfig(config, 1341 policy.warningBytes); 1342 final long limitBytes = getLimitBytesFromCarrierConfig(config, 1343 policy.limitBytes); 1344 1345 if (policy.cycleDay == cycleDay && 1346 policy.warningBytes == warningBytes && 1347 policy.limitBytes == limitBytes) { 1348 continue; 1349 } 1350 1351 policyUpdated = true; 1352 policy.cycleDay = cycleDay; 1353 policy.warningBytes = warningBytes; 1354 policy.limitBytes = limitBytes; 1355 1356 if (LOGD) { 1357 Slog.d(TAG, "Updated NetworkPolicy " + policy + " which matches subscriber " 1358 + NetworkIdentity.scrubSubscriberId(subscriberId) 1359 + " from CarrierConfigManager"); 1360 } 1361 } 1362 } 1363 1364 return policyUpdated; 1365 } 1366 1367 /** 1368 * Returns the cycle day that should be used for a mobile NetworkPolicy. 1369 * 1370 * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable 1371 * to do so, it returns the fallback value. 1372 * 1373 * @param config The CarrierConfig to read the value from. 1374 * @param fallbackCycleDay to return if the CarrierConfig can't be read. 1375 * @return cycleDay to use in the mobile NetworkPolicy. 1376 */ 1377 @VisibleForTesting getCycleDayFromCarrierConfig(@ullable PersistableBundle config, int fallbackCycleDay)1378 public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config, 1379 int fallbackCycleDay) { 1380 if (config == null) { 1381 return fallbackCycleDay; 1382 } 1383 int cycleDay = 1384 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT); 1385 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1386 return fallbackCycleDay; 1387 } 1388 // validate cycleDay value 1389 final Calendar cal = Calendar.getInstance(); 1390 if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) || 1391 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) { 1392 Slog.e(TAG, "Invalid date in " 1393 + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay); 1394 return fallbackCycleDay; 1395 } 1396 return cycleDay; 1397 } 1398 1399 /** 1400 * Returns the warning bytes that should be used for a mobile NetworkPolicy. 1401 * 1402 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable 1403 * to do so, it returns the fallback value. 1404 * 1405 * @param config The CarrierConfig to read the value from. 1406 * @param fallbackWarningBytes to return if the CarrierConfig can't be read. 1407 * @return warningBytes to use in the mobile NetworkPolicy. 1408 */ 1409 @VisibleForTesting getWarningBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackWarningBytes)1410 public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config, 1411 long fallbackWarningBytes) { 1412 if (config == null) { 1413 return fallbackWarningBytes; 1414 } 1415 long warningBytes = 1416 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG); 1417 1418 if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) { 1419 return WARNING_DISABLED; 1420 } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1421 return getPlatformDefaultWarningBytes(); 1422 } else if (warningBytes < 0) { 1423 Slog.e(TAG, "Invalid value in " 1424 + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a " 1425 + "non-negative value but got: " + warningBytes); 1426 return fallbackWarningBytes; 1427 } 1428 1429 return warningBytes; 1430 } 1431 1432 /** 1433 * Returns the limit bytes that should be used for a mobile NetworkPolicy. 1434 * 1435 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable 1436 * to do so, it returns the fallback value. 1437 * 1438 * @param config The CarrierConfig to read the value from. 1439 * @param fallbackLimitBytes to return if the CarrierConfig can't be read. 1440 * @return limitBytes to use in the mobile NetworkPolicy. 1441 */ 1442 @VisibleForTesting getLimitBytesFromCarrierConfig(@ullable PersistableBundle config, long fallbackLimitBytes)1443 public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config, 1444 long fallbackLimitBytes) { 1445 if (config == null) { 1446 return fallbackLimitBytes; 1447 } 1448 long limitBytes = 1449 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG); 1450 1451 if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) { 1452 return LIMIT_DISABLED; 1453 } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { 1454 return getPlatformDefaultLimitBytes(); 1455 } else if (limitBytes < 0) { 1456 Slog.e(TAG, "Invalid value in " 1457 + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a " 1458 + "non-negative value but got: " + limitBytes); 1459 return fallbackLimitBytes; 1460 } 1461 return limitBytes; 1462 } 1463 1464 /** 1465 * Receiver that watches for {@link CarrierConfigManager} to be changed. 1466 */ 1467 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() { 1468 @Override 1469 public void onReceive(Context context, Intent intent) { 1470 // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED 1471 // broadcast is protected and can't be spoofed. Runs on a background handler thread. 1472 1473 if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) { 1474 return; 1475 } 1476 final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1); 1477 final TelephonyManager tele = TelephonyManager.from(mContext); 1478 final String subscriberId = tele.getSubscriberId(subId); 1479 1480 maybeRefreshTrustedTime(); 1481 synchronized (mUidRulesFirstLock) { 1482 synchronized (mNetworkPoliciesSecondLock) { 1483 final boolean added = ensureActiveMobilePolicyAL(subId, subscriberId); 1484 if (added) return; 1485 final boolean updated = maybeUpdateMobilePolicyCycleNL(subId); 1486 if (!updated) return; 1487 // update network and notification rules, as the data cycle changed and it's 1488 // possible that we should be triggering warnings/limits now 1489 handleNetworkPoliciesUpdateAL(true); 1490 } 1491 } 1492 } 1493 }; 1494 1495 /** 1496 * Handles all tasks that need to be run after a new network policy has been set, or an existing 1497 * one has been updated. 1498 * 1499 * @param shouldNormalizePolicies true iff network policies need to be normalized after the 1500 * update. 1501 */ handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies)1502 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) { 1503 if (shouldNormalizePolicies) { 1504 normalizePoliciesNL(); 1505 } 1506 updateNetworkEnabledNL(); 1507 updateNetworkRulesNL(); 1508 updateNotificationsNL(); 1509 writePolicyAL(); 1510 } 1511 1512 /** 1513 * Proactively control network data connections when they exceed 1514 * {@link NetworkPolicy#limitBytes}. 1515 */ updateNetworkEnabledNL()1516 void updateNetworkEnabledNL() { 1517 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()"); 1518 1519 // TODO: reset any policy-disabled networks when any policy is removed 1520 // completely, which is currently rare case. 1521 1522 final long currentTime = currentTimeMillis(); 1523 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 1524 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1525 // shortcut when policy has no limit 1526 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 1527 setNetworkTemplateEnabled(policy.template, true); 1528 continue; 1529 } 1530 1531 final long start = computeLastCycleBoundary(currentTime, policy); 1532 final long end = currentTime; 1533 final long totalBytes = getTotalBytes(policy.template, start, end); 1534 1535 // disable data connection when over limit and not snoozed 1536 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 1537 && policy.lastLimitSnooze < start; 1538 final boolean networkEnabled = !overLimitWithoutSnooze; 1539 1540 setNetworkTemplateEnabled(policy.template, networkEnabled); 1541 } 1542 } 1543 1544 /** 1545 * Proactively disable networks that match the given 1546 * {@link NetworkTemplate}. 1547 */ 1548 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 1549 // TODO: reach into ConnectivityManager to proactively disable bringing 1550 // up this network, since we know that traffic will be blocked. 1551 1552 if (template.getMatchRule() == MATCH_MOBILE_ALL) { 1553 // If mobile data usage hits the limit or if the user resumes the data, we need to 1554 // notify telephony. 1555 final SubscriptionManager sm = SubscriptionManager.from(mContext); 1556 final TelephonyManager tm = TelephonyManager.from(mContext); 1557 1558 final int[] subIds = sm.getActiveSubscriptionIdList(); 1559 for (int subId : subIds) { 1560 final String subscriberId = tm.getSubscriberId(subId); 1561 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1562 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1563 // Template is matched when subscriber id matches. 1564 if (template.matches(probeIdent)) { 1565 tm.setPolicyDataEnabled(enabled, subId); 1566 } 1567 } 1568 } 1569 } 1570 1571 /** 1572 * Examine all connected {@link NetworkState}, looking for 1573 * {@link NetworkPolicy} that need to be enforced. When matches found, set 1574 * remaining quota based on usage cycle and historical stats. 1575 */ 1576 void updateNetworkRulesNL() { 1577 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()"); 1578 1579 final NetworkState[] states; 1580 try { 1581 states = mConnManager.getAllNetworkState(); 1582 } catch (RemoteException e) { 1583 // ignored; service lives in system_server 1584 return; 1585 } 1586 1587 // First, generate identities of all connected networks so we can 1588 // quickly compare them against all defined policies below. 1589 final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); 1590 final ArraySet<String> connIfaces = new ArraySet<String>(states.length); 1591 for (NetworkState state : states) { 1592 if (state.networkInfo != null && state.networkInfo.isConnected()) { 1593 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1594 1595 final String baseIface = state.linkProperties.getInterfaceName(); 1596 if (baseIface != null) { 1597 connIdents.add(Pair.create(baseIface, ident)); 1598 } 1599 1600 // Stacked interfaces are considered to have same identity as 1601 // their parent network. 1602 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); 1603 for (LinkProperties stackedLink : stackedLinks) { 1604 final String stackedIface = stackedLink.getInterfaceName(); 1605 if (stackedIface != null) { 1606 connIdents.add(Pair.create(stackedIface, ident)); 1607 } 1608 } 1609 } 1610 } 1611 1612 // Apply policies against all connected interfaces found above 1613 mNetworkRules.clear(); 1614 final ArrayList<String> ifaceList = Lists.newArrayList(); 1615 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1616 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 1617 1618 ifaceList.clear(); 1619 for (int j = connIdents.size() - 1; j >= 0; j--) { 1620 final Pair<String, NetworkIdentity> ident = connIdents.get(j); 1621 if (policy.template.matches(ident.second)) { 1622 ifaceList.add(ident.first); 1623 } 1624 } 1625 1626 if (ifaceList.size() > 0) { 1627 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 1628 mNetworkRules.put(policy, ifaces); 1629 } 1630 } 1631 1632 long lowestRule = Long.MAX_VALUE; 1633 final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length); 1634 1635 // apply each policy that we found ifaces for; compute remaining data 1636 // based on current cycle and historical stats, and push to kernel. 1637 final long currentTime = currentTimeMillis(); 1638 for (int i = mNetworkRules.size()-1; i >= 0; i--) { 1639 final NetworkPolicy policy = mNetworkRules.keyAt(i); 1640 final String[] ifaces = mNetworkRules.valueAt(i); 1641 1642 final long start; 1643 final long totalBytes; 1644 if (policy.hasCycle()) { 1645 start = computeLastCycleBoundary(currentTime, policy); 1646 totalBytes = getTotalBytes(policy.template, start, currentTime); 1647 } else { 1648 start = Long.MAX_VALUE; 1649 totalBytes = 0; 1650 } 1651 1652 if (LOGD) { 1653 Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces)); 1654 } 1655 1656 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 1657 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 1658 if (hasLimit || policy.metered) { 1659 final long quotaBytes; 1660 if (!hasLimit) { 1661 // metered network, but no policy limit; we still need to 1662 // restrict apps, so push really high quota. 1663 quotaBytes = Long.MAX_VALUE; 1664 } else if (policy.lastLimitSnooze >= start) { 1665 // snoozing past quota, but we still need to restrict apps, 1666 // so push really high quota. 1667 quotaBytes = Long.MAX_VALUE; 1668 } else { 1669 // remaining "quota" bytes are based on total usage in 1670 // current cycle. kernel doesn't like 0-byte rules, so we 1671 // set 1-byte quota and disable the radio later. 1672 quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 1673 } 1674 1675 if (ifaces.length > 1) { 1676 // TODO: switch to shared quota once NMS supports 1677 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 1678 } 1679 1680 for (String iface : ifaces) { 1681 // long quotaBytes split up into two ints to fit in message 1682 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1683 (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface) 1684 .sendToTarget(); 1685 newMeteredIfaces.add(iface); 1686 } 1687 } 1688 1689 // keep track of lowest warning or limit of active policies 1690 if (hasWarning && policy.warningBytes < lowestRule) { 1691 lowestRule = policy.warningBytes; 1692 } 1693 if (hasLimit && policy.limitBytes < lowestRule) { 1694 lowestRule = policy.limitBytes; 1695 } 1696 } 1697 1698 for (int i = connIfaces.size()-1; i >= 0; i--) { 1699 String iface = connIfaces.valueAt(i); 1700 // long quotaBytes split up into two ints to fit in message 1701 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, 1702 (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface) 1703 .sendToTarget(); 1704 newMeteredIfaces.add(iface); 1705 } 1706 1707 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 1708 1709 // remove quota on any trailing interfaces 1710 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) { 1711 final String iface = mMeteredIfaces.valueAt(i); 1712 if (!newMeteredIfaces.contains(iface)) { 1713 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface) 1714 .sendToTarget(); 1715 } 1716 } 1717 mMeteredIfaces = newMeteredIfaces; 1718 1719 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 1720 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 1721 } 1722 1723 /** 1724 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 1725 * have at least a default mobile policy defined. 1726 */ ensureActiveMobilePolicyAL()1727 private void ensureActiveMobilePolicyAL() { 1728 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()"); 1729 if (mSuppressDefaultPolicy) return; 1730 1731 final TelephonyManager tele = TelephonyManager.from(mContext); 1732 final SubscriptionManager sub = SubscriptionManager.from(mContext); 1733 1734 final int[] subIds = sub.getActiveSubscriptionIdList(); 1735 for (int subId : subIds) { 1736 final String subscriberId = tele.getSubscriberId(subId); 1737 ensureActiveMobilePolicyAL(subId, subscriberId); 1738 } 1739 } 1740 1741 /** 1742 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 1743 * have at least a default mobile policy defined. 1744 * 1745 * @param subId to build a default policy for 1746 * @param subscriberId that we check for an existing policy 1747 * @return true if a mobile network policy was added, or false one already existed. 1748 */ ensureActiveMobilePolicyAL(int subId, String subscriberId)1749 private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) { 1750 // Poke around to see if we already have a policy 1751 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, 1752 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); 1753 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { 1754 final NetworkTemplate template = mNetworkPolicy.keyAt(i); 1755 if (template.matches(probeIdent)) { 1756 if (LOGD) { 1757 Slog.d(TAG, "Found template " + template + " which matches subscriber " 1758 + NetworkIdentity.scrubSubscriberId(subscriberId)); 1759 } 1760 return false; 1761 } 1762 } 1763 1764 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId) 1765 + "; generating default policy"); 1766 final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId); 1767 addNetworkPolicyAL(policy); 1768 return true; 1769 } 1770 getPlatformDefaultWarningBytes()1771 private long getPlatformDefaultWarningBytes() { 1772 final int dataWarningConfig = mContext.getResources().getInteger( 1773 com.android.internal.R.integer.config_networkPolicyDefaultWarning); 1774 if (dataWarningConfig == WARNING_DISABLED) { 1775 return WARNING_DISABLED; 1776 } else { 1777 return dataWarningConfig * MB_IN_BYTES; 1778 } 1779 } 1780 getPlatformDefaultLimitBytes()1781 private long getPlatformDefaultLimitBytes() { 1782 return LIMIT_DISABLED; 1783 } 1784 1785 @VisibleForTesting buildDefaultMobilePolicy(int subId, String subscriberId)1786 public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) { 1787 PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); 1788 1789 // assume usage cycle starts today 1790 final Time time = new Time(); 1791 time.setToNow(); 1792 1793 final String cycleTimezone = time.timezone; 1794 1795 final int cycleDay = getCycleDayFromCarrierConfig(config, time.monthDay); 1796 final long warningBytes = getWarningBytesFromCarrierConfig(config, 1797 getPlatformDefaultWarningBytes()); 1798 final long limitBytes = getLimitBytesFromCarrierConfig(config, 1799 getPlatformDefaultLimitBytes()); 1800 1801 final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 1802 final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, 1803 warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, true); 1804 return policy; 1805 } 1806 readPolicyAL()1807 private void readPolicyAL() { 1808 if (LOGV) Slog.v(TAG, "readPolicyAL()"); 1809 1810 // clear any existing policy and read from disk 1811 mNetworkPolicy.clear(); 1812 mUidPolicy.clear(); 1813 1814 FileInputStream fis = null; 1815 try { 1816 fis = mPolicyFile.openRead(); 1817 final XmlPullParser in = Xml.newPullParser(); 1818 in.setInput(fis, StandardCharsets.UTF_8.name()); 1819 1820 // Must save the <restrict-background> tags and convert them to <uid-policy> later, 1821 // to skip UIDs that were explicitly blacklisted. 1822 final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray(); 1823 1824 int type; 1825 int version = VERSION_INIT; 1826 boolean insideWhitelist = false; 1827 while ((type = in.next()) != END_DOCUMENT) { 1828 final String tag = in.getName(); 1829 if (type == START_TAG) { 1830 if (TAG_POLICY_LIST.equals(tag)) { 1831 final boolean oldValue = mRestrictBackground; 1832 version = readIntAttribute(in, ATTR_VERSION); 1833 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 1834 mRestrictBackground = readBooleanAttribute( 1835 in, ATTR_RESTRICT_BACKGROUND); 1836 } else { 1837 mRestrictBackground = false; 1838 } 1839 if (mRestrictBackground != oldValue) { 1840 // Some early services may have read the default value, 1841 // so notify them that it's changed 1842 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, 1843 mRestrictBackground ? 1 : 0, 0).sendToTarget(); 1844 } 1845 1846 } else if (TAG_NETWORK_POLICY.equals(tag)) { 1847 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 1848 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 1849 final String networkId; 1850 if (version >= VERSION_ADDED_NETWORK_ID) { 1851 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 1852 } else { 1853 networkId = null; 1854 } 1855 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 1856 final String cycleTimezone; 1857 if (version >= VERSION_ADDED_TIMEZONE) { 1858 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 1859 } else { 1860 cycleTimezone = Time.TIMEZONE_UTC; 1861 } 1862 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 1863 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 1864 final long lastLimitSnooze; 1865 if (version >= VERSION_SPLIT_SNOOZE) { 1866 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 1867 } else if (version >= VERSION_ADDED_SNOOZE) { 1868 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 1869 } else { 1870 lastLimitSnooze = SNOOZE_NEVER; 1871 } 1872 final boolean metered; 1873 if (version >= VERSION_ADDED_METERED) { 1874 metered = readBooleanAttribute(in, ATTR_METERED); 1875 } else { 1876 switch (networkTemplate) { 1877 case MATCH_MOBILE_3G_LOWER: 1878 case MATCH_MOBILE_4G: 1879 case MATCH_MOBILE_ALL: 1880 metered = true; 1881 break; 1882 default: 1883 metered = false; 1884 } 1885 } 1886 final long lastWarningSnooze; 1887 if (version >= VERSION_SPLIT_SNOOZE) { 1888 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 1889 } else { 1890 lastWarningSnooze = SNOOZE_NEVER; 1891 } 1892 final boolean inferred; 1893 if (version >= VERSION_ADDED_INFERRED) { 1894 inferred = readBooleanAttribute(in, ATTR_INFERRED); 1895 } else { 1896 inferred = false; 1897 } 1898 1899 final NetworkTemplate template = new NetworkTemplate(networkTemplate, 1900 subscriberId, networkId); 1901 if (template.isPersistable()) { 1902 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, 1903 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, 1904 lastLimitSnooze, metered, inferred)); 1905 } 1906 1907 } else if (TAG_UID_POLICY.equals(tag)) { 1908 final int uid = readIntAttribute(in, ATTR_UID); 1909 final int policy = readIntAttribute(in, ATTR_POLICY); 1910 1911 if (UserHandle.isApp(uid)) { 1912 setUidPolicyUncheckedUL(uid, policy, false); 1913 } else { 1914 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1915 } 1916 } else if (TAG_APP_POLICY.equals(tag)) { 1917 final int appId = readIntAttribute(in, ATTR_APP_ID); 1918 final int policy = readIntAttribute(in, ATTR_POLICY); 1919 1920 // TODO: set for other users during upgrade 1921 // app policy is deprecated so this is only used in pre system user split. 1922 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId); 1923 if (UserHandle.isApp(uid)) { 1924 setUidPolicyUncheckedUL(uid, policy, false); 1925 } else { 1926 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1927 } 1928 } else if (TAG_WHITELIST.equals(tag)) { 1929 insideWhitelist = true; 1930 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1931 final int uid = readIntAttribute(in, ATTR_UID); 1932 whitelistedRestrictBackground.append(uid, true); 1933 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { 1934 final int uid = readIntAttribute(in, ATTR_UID); 1935 mRestrictBackgroundWhitelistRevokedUids.put(uid, true); 1936 } 1937 } else if (type == END_TAG) { 1938 if (TAG_WHITELIST.equals(tag)) { 1939 insideWhitelist = false; 1940 } 1941 1942 } 1943 } 1944 1945 final int size = whitelistedRestrictBackground.size(); 1946 for (int i = 0; i < size; i++) { 1947 final int uid = whitelistedRestrictBackground.keyAt(i); 1948 final int policy = mUidPolicy.get(uid, POLICY_NONE); 1949 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) { 1950 Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid 1951 + " because its policy is " + uidPoliciesToString(policy)); 1952 continue; 1953 } 1954 if (UserHandle.isApp(uid)) { 1955 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND; 1956 if (LOGV) 1957 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy)); 1958 setUidPolicyUncheckedUL(uid, newPolicy, false); 1959 } else { 1960 Slog.w(TAG, "unable to update policy on UID " + uid); 1961 } 1962 } 1963 1964 } catch (FileNotFoundException e) { 1965 // missing policy is okay, probably first boot 1966 upgradeLegacyBackgroundDataUL(); 1967 } catch (IOException e) { 1968 Log.wtf(TAG, "problem reading network policy", e); 1969 } catch (XmlPullParserException e) { 1970 Log.wtf(TAG, "problem reading network policy", e); 1971 } finally { 1972 IoUtils.closeQuietly(fis); 1973 } 1974 } 1975 1976 /** 1977 * Upgrade legacy background data flags, notifying listeners of one last 1978 * change to always-true. 1979 */ upgradeLegacyBackgroundDataUL()1980 private void upgradeLegacyBackgroundDataUL() { 1981 mRestrictBackground = Settings.Secure.getInt( 1982 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 1983 1984 // kick off one last broadcast if restricted 1985 if (mRestrictBackground) { 1986 final Intent broadcast = new Intent( 1987 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 1988 mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL); 1989 } 1990 } 1991 writePolicyAL()1992 void writePolicyAL() { 1993 if (LOGV) Slog.v(TAG, "writePolicyAL()"); 1994 1995 FileOutputStream fos = null; 1996 try { 1997 fos = mPolicyFile.startWrite(); 1998 1999 XmlSerializer out = new FastXmlSerializer(); 2000 out.setOutput(fos, StandardCharsets.UTF_8.name()); 2001 out.startDocument(null, true); 2002 2003 out.startTag(null, TAG_POLICY_LIST); 2004 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 2005 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 2006 2007 // write all known network policies 2008 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2009 final NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2010 final NetworkTemplate template = policy.template; 2011 if (!template.isPersistable()) continue; 2012 2013 out.startTag(null, TAG_NETWORK_POLICY); 2014 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 2015 final String subscriberId = template.getSubscriberId(); 2016 if (subscriberId != null) { 2017 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 2018 } 2019 final String networkId = template.getNetworkId(); 2020 if (networkId != null) { 2021 out.attribute(null, ATTR_NETWORK_ID, networkId); 2022 } 2023 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 2024 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone); 2025 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 2026 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 2027 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 2028 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 2029 writeBooleanAttribute(out, ATTR_METERED, policy.metered); 2030 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 2031 out.endTag(null, TAG_NETWORK_POLICY); 2032 } 2033 2034 // write all known uid policies 2035 for (int i = 0; i < mUidPolicy.size(); i++) { 2036 final int uid = mUidPolicy.keyAt(i); 2037 final int policy = mUidPolicy.valueAt(i); 2038 2039 // skip writing empty policies 2040 if (policy == POLICY_NONE) continue; 2041 2042 out.startTag(null, TAG_UID_POLICY); 2043 writeIntAttribute(out, ATTR_UID, uid); 2044 writeIntAttribute(out, ATTR_POLICY, policy); 2045 out.endTag(null, TAG_UID_POLICY); 2046 } 2047 2048 out.endTag(null, TAG_POLICY_LIST); 2049 2050 // write all whitelists 2051 out.startTag(null, TAG_WHITELIST); 2052 2053 // revoked restrict background whitelist 2054 int size = mRestrictBackgroundWhitelistRevokedUids.size(); 2055 for (int i = 0; i < size; i++) { 2056 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 2057 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 2058 writeIntAttribute(out, ATTR_UID, uid); 2059 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); 2060 } 2061 2062 out.endTag(null, TAG_WHITELIST); 2063 2064 out.endDocument(); 2065 2066 mPolicyFile.finishWrite(fos); 2067 } catch (IOException e) { 2068 if (fos != null) { 2069 mPolicyFile.failWrite(fos); 2070 } 2071 } 2072 } 2073 2074 @Override setUidPolicy(int uid, int policy)2075 public void setUidPolicy(int uid, int policy) { 2076 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2077 2078 if (!UserHandle.isApp(uid)) { 2079 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2080 } 2081 synchronized (mUidRulesFirstLock) { 2082 final long token = Binder.clearCallingIdentity(); 2083 try { 2084 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2085 if (oldPolicy != policy) { 2086 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2087 } 2088 } finally { 2089 Binder.restoreCallingIdentity(token); 2090 } 2091 } 2092 } 2093 2094 @Override addUidPolicy(int uid, int policy)2095 public void addUidPolicy(int uid, int policy) { 2096 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2097 2098 if (!UserHandle.isApp(uid)) { 2099 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2100 } 2101 2102 synchronized (mUidRulesFirstLock) { 2103 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2104 policy |= oldPolicy; 2105 if (oldPolicy != policy) { 2106 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2107 } 2108 } 2109 } 2110 2111 @Override removeUidPolicy(int uid, int policy)2112 public void removeUidPolicy(int uid, int policy) { 2113 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2114 2115 if (!UserHandle.isApp(uid)) { 2116 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 2117 } 2118 2119 synchronized (mUidRulesFirstLock) { 2120 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); 2121 policy = oldPolicy & ~policy; 2122 if (oldPolicy != policy) { 2123 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true); 2124 } 2125 } 2126 } 2127 setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist)2128 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) { 2129 setUidPolicyUncheckedUL(uid, policy, persist); 2130 2131 final boolean notifyApp; 2132 if (!isUidValidForWhitelistRules(uid)) { 2133 notifyApp = false; 2134 } else { 2135 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; 2136 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND; 2137 final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; 2138 final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND; 2139 final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted); 2140 final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted); 2141 if ((wasWhitelisted && (!isWhitelisted || isBlacklisted)) 2142 && mDefaultRestrictBackgroundWhitelistUids.get(uid) 2143 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { 2144 if (LOGD) 2145 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist"); 2146 mRestrictBackgroundWhitelistRevokedUids.append(uid, true); 2147 } 2148 notifyApp = wasBlocked != isBlocked; 2149 } 2150 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp)) 2151 .sendToTarget(); 2152 } 2153 setUidPolicyUncheckedUL(int uid, int policy, boolean persist)2154 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) { 2155 if (policy == POLICY_NONE) { 2156 mUidPolicy.delete(uid); 2157 } else { 2158 mUidPolicy.put(uid, policy); 2159 } 2160 2161 // uid policy changed, recompute rules and persist policy. 2162 updateRulesForDataUsageRestrictionsUL(uid); 2163 if (persist) { 2164 synchronized (mNetworkPoliciesSecondLock) { 2165 writePolicyAL(); 2166 } 2167 } 2168 } 2169 2170 @Override getUidPolicy(int uid)2171 public int getUidPolicy(int uid) { 2172 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2173 2174 synchronized (mUidRulesFirstLock) { 2175 return mUidPolicy.get(uid, POLICY_NONE); 2176 } 2177 } 2178 2179 @Override getUidsWithPolicy(int policy)2180 public int[] getUidsWithPolicy(int policy) { 2181 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2182 2183 int[] uids = new int[0]; 2184 synchronized (mUidRulesFirstLock) { 2185 for (int i = 0; i < mUidPolicy.size(); i++) { 2186 final int uid = mUidPolicy.keyAt(i); 2187 final int uidPolicy = mUidPolicy.valueAt(i); 2188 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) || 2189 (uidPolicy & policy) != 0) { 2190 uids = appendInt(uids, uid); 2191 } 2192 } 2193 } 2194 return uids; 2195 } 2196 2197 /** 2198 * Removes any persistable state associated with given {@link UserHandle}, persisting 2199 * if any changes that are made. 2200 */ removeUserStateUL(int userId, boolean writePolicy)2201 boolean removeUserStateUL(int userId, boolean writePolicy) { 2202 2203 if (LOGV) Slog.v(TAG, "removeUserStateUL()"); 2204 boolean changed = false; 2205 2206 // Remove entries from revoked default restricted background UID whitelist 2207 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) { 2208 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); 2209 if (UserHandle.getUserId(uid) == userId) { 2210 mRestrictBackgroundWhitelistRevokedUids.removeAt(i); 2211 changed = true; 2212 } 2213 } 2214 2215 // Remove associated UID policies 2216 int[] uids = new int[0]; 2217 for (int i = 0; i < mUidPolicy.size(); i++) { 2218 final int uid = mUidPolicy.keyAt(i); 2219 if (UserHandle.getUserId(uid) == userId) { 2220 uids = appendInt(uids, uid); 2221 } 2222 } 2223 2224 if (uids.length > 0) { 2225 for (int uid : uids) { 2226 mUidPolicy.delete(uid); 2227 } 2228 changed = true; 2229 } 2230 synchronized (mNetworkPoliciesSecondLock) { 2231 updateRulesForGlobalChangeAL(true); 2232 if (writePolicy && changed) { 2233 writePolicyAL(); 2234 } 2235 } 2236 return changed; 2237 } 2238 2239 @Override registerListener(INetworkPolicyListener listener)2240 public void registerListener(INetworkPolicyListener listener) { 2241 // TODO: create permission for observing network policy 2242 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2243 mListeners.register(listener); 2244 } 2245 2246 @Override unregisterListener(INetworkPolicyListener listener)2247 public void unregisterListener(INetworkPolicyListener listener) { 2248 // TODO: create permission for observing network policy 2249 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2250 mListeners.unregister(listener); 2251 } 2252 2253 @Override setNetworkPolicies(NetworkPolicy[] policies)2254 public void setNetworkPolicies(NetworkPolicy[] policies) { 2255 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2256 2257 final long token = Binder.clearCallingIdentity(); 2258 try { 2259 maybeRefreshTrustedTime(); 2260 synchronized (mUidRulesFirstLock) { 2261 synchronized (mNetworkPoliciesSecondLock) { 2262 normalizePoliciesNL(policies); 2263 handleNetworkPoliciesUpdateAL(false); 2264 } 2265 } 2266 } finally { 2267 Binder.restoreCallingIdentity(token); 2268 } 2269 } 2270 addNetworkPolicyAL(NetworkPolicy policy)2271 void addNetworkPolicyAL(NetworkPolicy policy) { 2272 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 2273 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy); 2274 setNetworkPolicies(policies); 2275 } 2276 2277 @Override getNetworkPolicies(String callingPackage)2278 public NetworkPolicy[] getNetworkPolicies(String callingPackage) { 2279 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2280 try { 2281 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); 2282 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED 2283 // permission 2284 } catch (SecurityException e) { 2285 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 2286 2287 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 2288 callingPackage) != AppOpsManager.MODE_ALLOWED) { 2289 return new NetworkPolicy[0]; 2290 } 2291 } 2292 2293 synchronized (mNetworkPoliciesSecondLock) { 2294 final int size = mNetworkPolicy.size(); 2295 final NetworkPolicy[] policies = new NetworkPolicy[size]; 2296 for (int i = 0; i < size; i++) { 2297 policies[i] = mNetworkPolicy.valueAt(i); 2298 } 2299 return policies; 2300 } 2301 } 2302 normalizePoliciesNL()2303 private void normalizePoliciesNL() { 2304 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName())); 2305 } 2306 normalizePoliciesNL(NetworkPolicy[] policies)2307 private void normalizePoliciesNL(NetworkPolicy[] policies) { 2308 final TelephonyManager tele = TelephonyManager.from(mContext); 2309 final String[] merged = tele.getMergedSubscriberIds(); 2310 2311 mNetworkPolicy.clear(); 2312 for (NetworkPolicy policy : policies) { 2313 // When two normalized templates conflict, prefer the most 2314 // restrictive policy 2315 policy.template = NetworkTemplate.normalize(policy.template, merged); 2316 final NetworkPolicy existing = mNetworkPolicy.get(policy.template); 2317 if (existing == null || existing.compareTo(policy) > 0) { 2318 if (existing != null) { 2319 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy); 2320 } 2321 mNetworkPolicy.put(policy.template, policy); 2322 } 2323 } 2324 } 2325 2326 @Override snoozeLimit(NetworkTemplate template)2327 public void snoozeLimit(NetworkTemplate template) { 2328 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2329 2330 final long token = Binder.clearCallingIdentity(); 2331 try { 2332 performSnooze(template, TYPE_LIMIT); 2333 } finally { 2334 Binder.restoreCallingIdentity(token); 2335 } 2336 } 2337 performSnooze(NetworkTemplate template, int type)2338 void performSnooze(NetworkTemplate template, int type) { 2339 maybeRefreshTrustedTime(); 2340 final long currentTime = currentTimeMillis(); 2341 synchronized (mUidRulesFirstLock) { 2342 synchronized (mNetworkPoliciesSecondLock) { 2343 // find and snooze local policy that matches 2344 final NetworkPolicy policy = mNetworkPolicy.get(template); 2345 if (policy == null) { 2346 throw new IllegalArgumentException("unable to find policy for " + template); 2347 } 2348 2349 switch (type) { 2350 case TYPE_WARNING: 2351 policy.lastWarningSnooze = currentTime; 2352 break; 2353 case TYPE_LIMIT: 2354 policy.lastLimitSnooze = currentTime; 2355 break; 2356 default: 2357 throw new IllegalArgumentException("unexpected type"); 2358 } 2359 2360 handleNetworkPoliciesUpdateAL(true); 2361 } 2362 } 2363 } 2364 2365 @Override onTetheringChanged(String iface, boolean tethering)2366 public void onTetheringChanged(String iface, boolean tethering) { 2367 // No need to enforce permission because setRestrictBackground() will do it. 2368 if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")"); 2369 synchronized (mUidRulesFirstLock) { 2370 if (mRestrictBackground && tethering) { 2371 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver"); 2372 setRestrictBackground(false); 2373 } 2374 } 2375 } 2376 2377 @Override setRestrictBackground(boolean restrictBackground)2378 public void setRestrictBackground(boolean restrictBackground) { 2379 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground"); 2380 try { 2381 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2382 final long token = Binder.clearCallingIdentity(); 2383 try { 2384 maybeRefreshTrustedTime(); 2385 synchronized (mUidRulesFirstLock) { 2386 if (restrictBackground == mRestrictBackground) { 2387 // Ideally, UI should never allow this scenario... 2388 Slog.w(TAG, "setRestrictBackground: already " + restrictBackground); 2389 return; 2390 } 2391 setRestrictBackgroundUL(restrictBackground); 2392 } 2393 2394 } finally { 2395 Binder.restoreCallingIdentity(token); 2396 } 2397 2398 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 2399 .sendToTarget(); 2400 } finally { 2401 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2402 } 2403 } 2404 setRestrictBackgroundUL(boolean restrictBackground)2405 private void setRestrictBackgroundUL(boolean restrictBackground) { 2406 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground); 2407 final boolean oldRestrictBackground = mRestrictBackground; 2408 mRestrictBackground = restrictBackground; 2409 // Must whitelist foreground apps before turning data saver mode on. 2410 // TODO: there is no need to iterate through all apps here, just those in the foreground, 2411 // so it could call AM to get the UIDs of such apps, and iterate through them instead. 2412 updateRulesForRestrictBackgroundUL(); 2413 try { 2414 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) { 2415 Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground); 2416 mRestrictBackground = oldRestrictBackground; 2417 // TODO: if it knew the foreground apps (see TODO above), it could call 2418 // updateRulesForRestrictBackgroundUL() again to restore state. 2419 return; 2420 } 2421 } catch (RemoteException e) { 2422 // ignored; service lives in system_server 2423 } 2424 2425 if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) { 2426 mRestrictBackgroundChangedInBsm = true; 2427 } 2428 synchronized (mNetworkPoliciesSecondLock) { 2429 updateNotificationsNL(); 2430 writePolicyAL(); 2431 } 2432 } 2433 2434 @Override getRestrictBackgroundByCaller()2435 public int getRestrictBackgroundByCaller() { 2436 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2437 final int uid = Binder.getCallingUid(); 2438 2439 synchronized (mUidRulesFirstLock) { 2440 // Must clear identity because getUidPolicy() is restricted to system. 2441 final long token = Binder.clearCallingIdentity(); 2442 final int policy; 2443 try { 2444 policy = getUidPolicy(uid); 2445 } finally { 2446 Binder.restoreCallingIdentity(token); 2447 } 2448 if (policy == POLICY_REJECT_METERED_BACKGROUND) { 2449 // App is blacklisted. 2450 return RESTRICT_BACKGROUND_STATUS_ENABLED; 2451 } 2452 if (!mRestrictBackground) { 2453 return RESTRICT_BACKGROUND_STATUS_DISABLED; 2454 } 2455 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0 2456 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED 2457 : RESTRICT_BACKGROUND_STATUS_ENABLED; 2458 } 2459 } 2460 2461 @Override getRestrictBackground()2462 public boolean getRestrictBackground() { 2463 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2464 2465 synchronized (mUidRulesFirstLock) { 2466 return mRestrictBackground; 2467 } 2468 } 2469 2470 @Override setDeviceIdleMode(boolean enabled)2471 public void setDeviceIdleMode(boolean enabled) { 2472 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2473 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode"); 2474 try { 2475 synchronized (mUidRulesFirstLock) { 2476 if (mDeviceIdleMode == enabled) { 2477 return; 2478 } 2479 mDeviceIdleMode = enabled; 2480 if (mSystemReady) { 2481 // Device idle change means we need to rebuild rules for all 2482 // known apps, so do a global refresh. 2483 updateRulesForRestrictPowerUL(); 2484 } 2485 } 2486 if (enabled) { 2487 EventLogTags.writeDeviceIdleOnPhase("net"); 2488 } else { 2489 EventLogTags.writeDeviceIdleOffPhase("net"); 2490 } 2491 } finally { 2492 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2493 } 2494 } 2495 findPolicyForNetworkNL(NetworkIdentity ident)2496 private NetworkPolicy findPolicyForNetworkNL(NetworkIdentity ident) { 2497 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2498 NetworkPolicy policy = mNetworkPolicy.valueAt(i); 2499 if (policy.template.matches(ident)) { 2500 return policy; 2501 } 2502 } 2503 return null; 2504 } 2505 2506 @Override getNetworkQuotaInfo(NetworkState state)2507 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 2508 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 2509 2510 // only returns usage summary, so we don't require caller to have 2511 // READ_NETWORK_USAGE_HISTORY. 2512 final long token = Binder.clearCallingIdentity(); 2513 try { 2514 return getNetworkQuotaInfoUnchecked(state); 2515 } finally { 2516 Binder.restoreCallingIdentity(token); 2517 } 2518 } 2519 getNetworkQuotaInfoUnchecked(NetworkState state)2520 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 2521 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2522 2523 final NetworkPolicy policy; 2524 synchronized (mNetworkPoliciesSecondLock) { 2525 policy = findPolicyForNetworkNL(ident); 2526 } 2527 2528 if (policy == null || !policy.hasCycle()) { 2529 // missing policy means we can't derive useful quota info 2530 return null; 2531 } 2532 2533 final long currentTime = currentTimeMillis(); 2534 2535 // find total bytes used under policy 2536 final long start = computeLastCycleBoundary(currentTime, policy); 2537 final long end = currentTime; 2538 final long totalBytes = getTotalBytes(policy.template, start, end); 2539 2540 // report soft and hard limits under policy 2541 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 2542 : NetworkQuotaInfo.NO_LIMIT; 2543 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 2544 : NetworkQuotaInfo.NO_LIMIT; 2545 2546 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 2547 } 2548 2549 @Override isNetworkMetered(NetworkState state)2550 public boolean isNetworkMetered(NetworkState state) { 2551 if (state.networkInfo == null) { 2552 return false; 2553 } 2554 2555 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 2556 2557 final NetworkPolicy policy; 2558 synchronized (mNetworkPoliciesSecondLock) { 2559 policy = findPolicyForNetworkNL(ident); 2560 } 2561 2562 if (policy != null) { 2563 return policy.metered; 2564 } else { 2565 final int type = state.networkInfo.getType(); 2566 if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) { 2567 return true; 2568 } 2569 return false; 2570 } 2571 } 2572 2573 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)2574 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2575 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return; 2576 2577 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 2578 2579 final ArraySet<String> argSet = new ArraySet<String>(args.length); 2580 for (String arg : args) { 2581 argSet.add(arg); 2582 } 2583 2584 synchronized (mUidRulesFirstLock) { 2585 synchronized (mNetworkPoliciesSecondLock) { 2586 if (argSet.contains("--unsnooze")) { 2587 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) { 2588 mNetworkPolicy.valueAt(i).clearSnooze(); 2589 } 2590 2591 handleNetworkPoliciesUpdateAL(true); 2592 2593 fout.println("Cleared snooze timestamps"); 2594 return; 2595 } 2596 2597 fout.print("System ready: "); fout.println(mSystemReady); 2598 fout.print("Restrict background: "); fout.println(mRestrictBackground); 2599 fout.print("Restrict power: "); fout.println(mRestrictPower); 2600 fout.print("Device idle: "); fout.println(mDeviceIdleMode); 2601 fout.println("Network policies:"); 2602 fout.increaseIndent(); 2603 for (int i = 0; i < mNetworkPolicy.size(); i++) { 2604 fout.println(mNetworkPolicy.valueAt(i).toString()); 2605 } 2606 fout.decreaseIndent(); 2607 2608 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); 2609 2610 fout.println("Policy for UIDs:"); 2611 fout.increaseIndent(); 2612 int size = mUidPolicy.size(); 2613 for (int i = 0; i < size; i++) { 2614 final int uid = mUidPolicy.keyAt(i); 2615 final int policy = mUidPolicy.valueAt(i); 2616 fout.print("UID="); 2617 fout.print(uid); 2618 fout.print(" policy="); 2619 fout.print(uidPoliciesToString(policy)); 2620 fout.println(); 2621 } 2622 fout.decreaseIndent(); 2623 2624 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2625 if (size > 0) { 2626 fout.println("Power save whitelist (except idle) app ids:"); 2627 fout.increaseIndent(); 2628 for (int i = 0; i < size; i++) { 2629 fout.print("UID="); 2630 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2631 fout.print(": "); 2632 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i)); 2633 fout.println(); 2634 } 2635 fout.decreaseIndent(); 2636 } 2637 2638 size = mPowerSaveWhitelistAppIds.size(); 2639 if (size > 0) { 2640 fout.println("Power save whitelist app ids:"); 2641 fout.increaseIndent(); 2642 for (int i = 0; i < size; i++) { 2643 fout.print("UID="); 2644 fout.print(mPowerSaveWhitelistAppIds.keyAt(i)); 2645 fout.print(": "); 2646 fout.print(mPowerSaveWhitelistAppIds.valueAt(i)); 2647 fout.println(); 2648 } 2649 fout.decreaseIndent(); 2650 } 2651 2652 size = mDefaultRestrictBackgroundWhitelistUids.size(); 2653 if (size > 0) { 2654 fout.println("Default restrict background whitelist uids:"); 2655 fout.increaseIndent(); 2656 for (int i = 0; i < size; i++) { 2657 fout.print("UID="); 2658 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); 2659 fout.println(); 2660 } 2661 fout.decreaseIndent(); 2662 } 2663 2664 size = mRestrictBackgroundWhitelistRevokedUids.size(); 2665 if (size > 0) { 2666 fout.println("Default restrict background whitelist uids revoked by users:"); 2667 fout.increaseIndent(); 2668 for (int i = 0; i < size; i++) { 2669 fout.print("UID="); 2670 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); 2671 fout.println(); 2672 } 2673 fout.decreaseIndent(); 2674 } 2675 2676 final SparseBooleanArray knownUids = new SparseBooleanArray(); 2677 collectKeys(mUidState, knownUids); 2678 collectKeys(mUidRules, knownUids); 2679 2680 fout.println("Status for all known UIDs:"); 2681 fout.increaseIndent(); 2682 size = knownUids.size(); 2683 for (int i = 0; i < size; i++) { 2684 final int uid = knownUids.keyAt(i); 2685 fout.print("UID="); 2686 fout.print(uid); 2687 2688 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2689 fout.print(" state="); 2690 fout.print(state); 2691 if (state <= ActivityManager.PROCESS_STATE_TOP) { 2692 fout.print(" (fg)"); 2693 } else { 2694 fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 2695 ? " (fg svc)" : " (bg)"); 2696 } 2697 2698 final int uidRules = mUidRules.get(uid, RULE_NONE); 2699 fout.print(" rules="); 2700 fout.print(uidRulesToString(uidRules)); 2701 fout.println(); 2702 } 2703 fout.decreaseIndent(); 2704 2705 fout.println("Status for just UIDs with rules:"); 2706 fout.increaseIndent(); 2707 size = mUidRules.size(); 2708 for (int i = 0; i < size; i++) { 2709 final int uid = mUidRules.keyAt(i); 2710 fout.print("UID="); 2711 fout.print(uid); 2712 final int uidRules = mUidRules.get(uid, RULE_NONE); 2713 fout.print(" rules="); 2714 fout.print(uidRulesToString(uidRules)); 2715 fout.println(); 2716 } 2717 fout.decreaseIndent(); 2718 2719 fout.println("Observed uid state changes:"); 2720 fout.increaseIndent(); 2721 mObservedHistory.dumpUL(fout); 2722 fout.decreaseIndent(); 2723 } 2724 } 2725 } 2726 2727 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2728 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2729 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 2730 (new NetworkPolicyManagerShellCommand(mContext, this)).exec( 2731 this, in, out, err, args, callback, resultReceiver); 2732 } 2733 2734 @Override isUidForeground(int uid)2735 public boolean isUidForeground(int uid) { 2736 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2737 2738 synchronized (mUidRulesFirstLock) { 2739 return isUidForegroundUL(uid); 2740 } 2741 } 2742 isUidForegroundUL(int uid)2743 private boolean isUidForegroundUL(int uid) { 2744 return isUidStateForegroundUL( 2745 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2746 } 2747 isUidForegroundOnRestrictBackgroundUL(int uid)2748 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) { 2749 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2750 return isProcStateAllowedWhileOnRestrictBackground(procState); 2751 } 2752 isUidForegroundOnRestrictPowerUL(int uid)2753 private boolean isUidForegroundOnRestrictPowerUL(int uid) { 2754 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2755 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState); 2756 } 2757 isUidStateForegroundUL(int state)2758 private boolean isUidStateForegroundUL(int state) { 2759 // only really in foreground when screen is also on 2760 return state <= ActivityManager.PROCESS_STATE_TOP; 2761 } 2762 2763 /** 2764 * Process state of UID changed; if needed, will trigger 2765 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and 2766 * {@link #updateRulesForPowerRestrictionsUL(int)} 2767 */ updateUidStateUL(int uid, int uidState)2768 private void updateUidStateUL(int uid, int uidState) { 2769 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL"); 2770 try { 2771 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2772 if (oldUidState != uidState) { 2773 // state changed, push updated rules 2774 mUidState.put(uid, uidState); 2775 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState); 2776 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) 2777 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) { 2778 if (isUidIdle(uid)) { 2779 updateRuleForAppIdleUL(uid); 2780 } 2781 if (mDeviceIdleMode) { 2782 updateRuleForDeviceIdleUL(uid); 2783 } 2784 if (mRestrictPower) { 2785 updateRuleForRestrictPowerUL(uid); 2786 } 2787 updateRulesForPowerRestrictionsUL(uid); 2788 } 2789 updateNetworkStats(uid, isUidStateForegroundUL(uidState)); 2790 } 2791 } finally { 2792 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2793 } 2794 } 2795 removeUidStateUL(int uid)2796 private void removeUidStateUL(int uid) { 2797 final int index = mUidState.indexOfKey(uid); 2798 if (index >= 0) { 2799 final int oldUidState = mUidState.valueAt(index); 2800 mUidState.removeAt(index); 2801 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2802 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, 2803 ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2804 if (mDeviceIdleMode) { 2805 updateRuleForDeviceIdleUL(uid); 2806 } 2807 if (mRestrictPower) { 2808 updateRuleForRestrictPowerUL(uid); 2809 } 2810 updateRulesForPowerRestrictionsUL(uid); 2811 updateNetworkStats(uid, false); 2812 } 2813 } 2814 } 2815 2816 // adjust stats accounting based on foreground status updateNetworkStats(int uid, boolean uidForeground)2817 private void updateNetworkStats(int uid, boolean uidForeground) { 2818 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 2819 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 2820 "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B")); 2821 } 2822 try { 2823 mNetworkStats.setUidForeground(uid, uidForeground); 2824 } catch (RemoteException e) { 2825 // ignored; service lives in system_server 2826 } finally { 2827 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2828 } 2829 } 2830 updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState, int newUidState)2831 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState, 2832 int newUidState) { 2833 final boolean oldForeground = 2834 isProcStateAllowedWhileOnRestrictBackground(oldUidState); 2835 final boolean newForeground = 2836 isProcStateAllowedWhileOnRestrictBackground(newUidState); 2837 if (oldForeground != newForeground) { 2838 updateRulesForDataUsageRestrictionsUL(uid); 2839 } 2840 } 2841 updateRulesForPowerSaveUL()2842 void updateRulesForPowerSaveUL() { 2843 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL"); 2844 try { 2845 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE, 2846 mUidFirewallPowerSaveRules); 2847 } finally { 2848 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2849 } 2850 } 2851 updateRuleForRestrictPowerUL(int uid)2852 void updateRuleForRestrictPowerUL(int uid) { 2853 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2854 } 2855 updateRulesForDeviceIdleUL()2856 void updateRulesForDeviceIdleUL() { 2857 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL"); 2858 try { 2859 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, 2860 mUidFirewallDozableRules); 2861 } finally { 2862 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2863 } 2864 } 2865 updateRuleForDeviceIdleUL(int uid)2866 void updateRuleForDeviceIdleUL(int uid) { 2867 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE); 2868 } 2869 2870 // NOTE: since both fw_dozable and fw_powersave uses the same map 2871 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain, SparseIntArray rules)2872 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain, 2873 SparseIntArray rules) { 2874 if (enabled) { 2875 // Sync the whitelists before enabling the chain. We don't care about the rules if 2876 // we are disabling the chain. 2877 final SparseIntArray uidRules = rules; 2878 uidRules.clear(); 2879 final List<UserInfo> users = mUserManager.getUsers(); 2880 for (int ui = users.size() - 1; ui >= 0; ui--) { 2881 UserInfo user = users.get(ui); 2882 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id); 2883 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id); 2884 if (chain == FIREWALL_CHAIN_POWERSAVE) { 2885 updateRulesForWhitelistedAppIds(uidRules, 2886 mPowerSaveWhitelistExceptIdleAppIds, user.id); 2887 } 2888 } 2889 for (int i = mUidState.size() - 1; i >= 0; i--) { 2890 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) { 2891 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 2892 } 2893 } 2894 setUidFirewallRulesAsync(chain, uidRules, CHAIN_TOGGLE_ENABLE); 2895 } else { 2896 setUidFirewallRulesAsync(chain, null, CHAIN_TOGGLE_DISABLE); 2897 } 2898 } 2899 updateRulesForWhitelistedAppIds(final SparseIntArray uidRules, final SparseBooleanArray whitelistedAppIds, int userId)2900 private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules, 2901 final SparseBooleanArray whitelistedAppIds, int userId) { 2902 for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) { 2903 if (whitelistedAppIds.valueAt(i)) { 2904 final int appId = whitelistedAppIds.keyAt(i); 2905 final int uid = UserHandle.getUid(userId, appId); 2906 uidRules.put(uid, FIREWALL_RULE_ALLOW); 2907 } 2908 } 2909 } 2910 2911 /** 2912 * @param deviceIdleMode if true then we don't consider 2913 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is 2914 * whitelisted. 2915 */ isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode)2916 private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) { 2917 final int appId = UserHandle.getAppId(uid); 2918 boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) 2919 || mPowerSaveWhitelistAppIds.get(appId); 2920 if (!deviceIdleMode) { 2921 isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId); 2922 } 2923 return isWhitelisted; 2924 } 2925 2926 // NOTE: since both fw_dozable and fw_powersave uses the same map 2927 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method. updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain)2928 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) { 2929 if (enabled) { 2930 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, 2931 chain == FIREWALL_CHAIN_DOZABLE); 2932 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) { 2933 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 2934 } else { 2935 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 2936 } 2937 } 2938 } 2939 updateRulesForAppIdleUL()2940 void updateRulesForAppIdleUL() { 2941 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL"); 2942 try { 2943 final SparseIntArray uidRules = mUidFirewallStandbyRules; 2944 uidRules.clear(); 2945 2946 // Fully update the app idle firewall chain. 2947 final List<UserInfo> users = mUserManager.getUsers(); 2948 for (int ui = users.size() - 1; ui >= 0; ui--) { 2949 UserInfo user = users.get(ui); 2950 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id); 2951 for (int uid : idleUids) { 2952 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) { 2953 // quick check: if this uid doesn't have INTERNET permission, it 2954 // doesn't have network access anyway, so it is a waste to mess 2955 // with it here. 2956 if (hasInternetPermissions(uid)) { 2957 uidRules.put(uid, FIREWALL_RULE_DENY); 2958 } 2959 } 2960 } 2961 } 2962 2963 setUidFirewallRulesAsync(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE); 2964 } finally { 2965 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2966 } 2967 } 2968 updateRuleForAppIdleUL(int uid)2969 void updateRuleForAppIdleUL(int uid) { 2970 if (!isUidValidForBlacklistRules(uid)) return; 2971 2972 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 2973 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid ); 2974 } 2975 try { 2976 int appId = UserHandle.getAppId(uid); 2977 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid) 2978 && !isUidForegroundOnRestrictPowerUL(uid)) { 2979 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY); 2980 } else { 2981 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 2982 } 2983 } finally { 2984 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 2985 } 2986 } 2987 2988 /** 2989 * Toggle the firewall standby chain and inform listeners if the uid rules have effectively 2990 * changed. 2991 */ updateRulesForAppIdleParoleUL()2992 void updateRulesForAppIdleParoleUL() { 2993 boolean paroled = mUsageStats.isAppIdleParoleOn(); 2994 boolean enableChain = !paroled; 2995 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain); 2996 2997 int ruleCount = mUidFirewallStandbyRules.size(); 2998 for (int i = 0; i < ruleCount; i++) { 2999 int uid = mUidFirewallStandbyRules.keyAt(i); 3000 int oldRules = mUidRules.get(uid); 3001 if (enableChain) { 3002 // Chain wasn't enabled before and the other power-related 3003 // chains are whitelists, so we can clear the 3004 // MASK_ALL_NETWORKS part of the rules and re-inform listeners if 3005 // the effective rules result in blocking network access. 3006 oldRules &= MASK_METERED_NETWORKS; 3007 } else { 3008 // Skip if it had no restrictions to begin with 3009 if ((oldRules & MASK_ALL_NETWORKS) == 0) continue; 3010 } 3011 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled); 3012 if (newUidRules == RULE_NONE) { 3013 mUidRules.delete(uid); 3014 } else { 3015 mUidRules.put(uid, newUidRules); 3016 } 3017 } 3018 } 3019 3020 /** 3021 * Update rules that might be changed by {@link #mRestrictBackground}, 3022 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. 3023 */ updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged)3024 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) { 3025 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 3026 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 3027 "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-")); 3028 } 3029 try { 3030 updateRulesForAppIdleUL(); 3031 updateRulesForRestrictPowerUL(); 3032 updateRulesForRestrictBackgroundUL(); 3033 3034 // If the set of restricted networks may have changed, re-evaluate those. 3035 if (restrictedNetworksChanged) { 3036 normalizePoliciesNL(); 3037 updateNetworkRulesNL(); 3038 } 3039 } finally { 3040 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3041 } 3042 } 3043 3044 // TODO: rename / document to make it clear these are global (not app-specific) rules updateRulesForRestrictPowerUL()3045 private void updateRulesForRestrictPowerUL() { 3046 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL"); 3047 try { 3048 updateRulesForDeviceIdleUL(); 3049 updateRulesForPowerSaveUL(); 3050 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER); 3051 } finally { 3052 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3053 } 3054 } 3055 updateRulesForRestrictBackgroundUL()3056 private void updateRulesForRestrictBackgroundUL() { 3057 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL"); 3058 try { 3059 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND); 3060 } finally { 3061 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3062 } 3063 } 3064 3065 private static final int TYPE_RESTRICT_BACKGROUND = 1; 3066 private static final int TYPE_RESTRICT_POWER = 2; 3067 @Retention(RetentionPolicy.SOURCE) 3068 @IntDef(flag = false, value = { 3069 TYPE_RESTRICT_BACKGROUND, 3070 TYPE_RESTRICT_POWER, 3071 }) 3072 public @interface RestrictType { 3073 } 3074 3075 // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them... updateRulesForAllAppsUL(@estrictType int type)3076 private void updateRulesForAllAppsUL(@RestrictType int type) { 3077 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 3078 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type); 3079 } 3080 try { 3081 // update rules for all installed applications 3082 3083 final PackageManager pm = mContext.getPackageManager(); 3084 final List<UserInfo> users; 3085 final List<ApplicationInfo> apps; 3086 3087 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users"); 3088 try { 3089 users = mUserManager.getUsers(); 3090 } finally { 3091 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3092 } 3093 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids"); 3094 try { 3095 apps = pm.getInstalledApplications( 3096 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS 3097 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3098 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 3099 } finally { 3100 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3101 } 3102 3103 final int usersSize = users.size(); 3104 final int appsSize = apps.size(); 3105 for (int i = 0; i < usersSize; i++) { 3106 final UserInfo user = users.get(i); 3107 for (int j = 0; j < appsSize; j++) { 3108 final ApplicationInfo app = apps.get(j); 3109 final int uid = UserHandle.getUid(user.id, app.uid); 3110 switch (type) { 3111 case TYPE_RESTRICT_BACKGROUND: 3112 updateRulesForDataUsageRestrictionsUL(uid); 3113 break; 3114 case TYPE_RESTRICT_POWER: 3115 updateRulesForPowerRestrictionsUL(uid); 3116 break; 3117 default: 3118 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type); 3119 } 3120 } 3121 } 3122 } finally { 3123 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3124 } 3125 } 3126 updateRulesForTempWhitelistChangeUL()3127 private void updateRulesForTempWhitelistChangeUL() { 3128 final List<UserInfo> users = mUserManager.getUsers(); 3129 for (int i = 0; i < users.size(); i++) { 3130 final UserInfo user = users.get(i); 3131 for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { 3132 int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); 3133 int uid = UserHandle.getUid(user.id, appId); 3134 // Update external firewall rules. 3135 updateRuleForAppIdleUL(uid); 3136 updateRuleForDeviceIdleUL(uid); 3137 updateRuleForRestrictPowerUL(uid); 3138 // Update internal rules. 3139 updateRulesForPowerRestrictionsUL(uid); 3140 } 3141 } 3142 } 3143 3144 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both 3145 // methods below could be merged into a isUidValidForRules() method. isUidValidForBlacklistRules(int uid)3146 private boolean isUidValidForBlacklistRules(int uid) { 3147 // allow rules on specific system services, and any apps 3148 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 3149 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) { 3150 return true; 3151 } 3152 3153 return false; 3154 } 3155 isUidValidForWhitelistRules(int uid)3156 private boolean isUidValidForWhitelistRules(int uid) { 3157 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 3158 } 3159 isUidIdle(int uid)3160 private boolean isUidIdle(int uid) { 3161 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); 3162 final int userId = UserHandle.getUserId(uid); 3163 3164 if (packages != null) { 3165 for (String packageName : packages) { 3166 if (!mUsageStats.isAppIdle(packageName, uid, userId)) { 3167 return false; 3168 } 3169 } 3170 } 3171 return true; 3172 } 3173 3174 /** 3175 * Checks if an uid has INTERNET permissions. 3176 * <p> 3177 * Useful for the cases where the lack of network access can simplify the rules. 3178 */ hasInternetPermissions(int uid)3179 private boolean hasInternetPermissions(int uid) { 3180 try { 3181 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) 3182 != PackageManager.PERMISSION_GRANTED) { 3183 return false; 3184 } 3185 } catch (RemoteException e) { 3186 } 3187 return true; 3188 } 3189 3190 /** 3191 * Clears all state - internal and external - associated with an UID. 3192 */ onUidDeletedUL(int uid)3193 private void onUidDeletedUL(int uid) { 3194 // First cleanup in-memory state synchronously... 3195 mUidRules.delete(uid); 3196 mUidPolicy.delete(uid); 3197 mUidFirewallStandbyRules.delete(uid); 3198 mUidFirewallDozableRules.delete(uid); 3199 mUidFirewallPowerSaveRules.delete(uid); 3200 mPowerSaveWhitelistExceptIdleAppIds.delete(uid); 3201 mPowerSaveWhitelistAppIds.delete(uid); 3202 mPowerSaveTempWhitelistAppIds.delete(uid); 3203 3204 // ...then update iptables asynchronously. 3205 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget(); 3206 } 3207 3208 /** 3209 * Applies network rules to bandwidth and firewall controllers based on uid policy. 3210 * 3211 * <p>There are currently 4 types of restriction rules: 3212 * <ul> 3213 * <li>Doze mode 3214 * <li>App idle mode 3215 * <li>Battery Saver Mode (also referred as power save). 3216 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data'). 3217 * </ul> 3218 * 3219 * <p>This method changes both the external firewall rules and the internal state. 3220 */ updateRestrictionRulesForUidUL(int uid)3221 private void updateRestrictionRulesForUidUL(int uid) { 3222 // Methods below only changes the firewall rules for the power-related modes. 3223 updateRuleForDeviceIdleUL(uid); 3224 updateRuleForAppIdleUL(uid); 3225 updateRuleForRestrictPowerUL(uid); 3226 3227 // Update internal state for power-related modes. 3228 updateRulesForPowerRestrictionsUL(uid); 3229 3230 // Update firewall and internal rules for Data Saver Mode. 3231 updateRulesForDataUsageRestrictionsUL(uid); 3232 } 3233 3234 /** 3235 * Applies network rules to bandwidth controllers based on process state and user-defined 3236 * restrictions (blacklist / whitelist). 3237 * 3238 * <p> 3239 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered 3240 * networks: 3241 * <ul> 3242 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). 3243 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're 3244 * also blacklisted. 3245 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), 3246 * no UIDs other those whitelisted will have access. 3247 * <ul> 3248 * 3249 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the 3250 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / 3251 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist 3252 * respectively): these methods set the proper internal state (blacklist / whitelist), then call 3253 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to 3254 * {@link INetworkManagementService}, but this method should also be called in events (like 3255 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the 3256 * following rules should also be applied: 3257 * 3258 * <ul> 3259 * <li>When Data Saver mode is on, the foreground app should be temporarily added to 3260 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. 3261 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from 3262 * {@code bw_penalty_box}. 3263 * <li>When the app leaves foreground state, the temporary changes above should be reverted. 3264 * </ul> 3265 * 3266 * <p>For optimization, the rules are only applied on user apps that have internet access 3267 * permission, since there is no need to change the {@code iptables} rule if the app does not 3268 * have permission to use the internet. 3269 * 3270 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID. 3271 * 3272 */ updateRulesForDataUsageRestrictionsUL(int uid)3273 private void updateRulesForDataUsageRestrictionsUL(int uid) { 3274 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 3275 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 3276 "updateRulesForDataUsageRestrictionsUL: " + uid); 3277 } 3278 try { 3279 updateRulesForDataUsageRestrictionsULInner(uid); 3280 } finally { 3281 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3282 } 3283 } 3284 updateRulesForDataUsageRestrictionsULInner(int uid)3285 private void updateRulesForDataUsageRestrictionsULInner(int uid) { 3286 if (!isUidValidForWhitelistRules(uid)) { 3287 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); 3288 return; 3289 } 3290 3291 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); 3292 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 3293 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid); 3294 3295 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; 3296 final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; 3297 final int oldRule = oldUidRules & MASK_METERED_NETWORKS; 3298 int newRule = RULE_NONE; 3299 3300 // First step: define the new rule based on user restrictions and foreground state. 3301 if (isForeground) { 3302 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { 3303 newRule = RULE_TEMPORARY_ALLOW_METERED; 3304 } else if (isWhitelisted) { 3305 newRule = RULE_ALLOW_METERED; 3306 } 3307 } else { 3308 if (isBlacklisted) { 3309 newRule = RULE_REJECT_METERED; 3310 } else if (mRestrictBackground && isWhitelisted) { 3311 newRule = RULE_ALLOW_METERED; 3312 } 3313 } 3314 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS); 3315 3316 if (LOGV) { 3317 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")" 3318 + ": isForeground=" +isForeground 3319 + ", isBlacklisted=" + isBlacklisted 3320 + ", isWhitelisted=" + isWhitelisted 3321 + ", oldRule=" + uidRulesToString(oldRule) 3322 + ", newRule=" + uidRulesToString(newRule) 3323 + ", newUidRules=" + uidRulesToString(newUidRules) 3324 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 3325 } 3326 3327 if (newUidRules == RULE_NONE) { 3328 mUidRules.delete(uid); 3329 } else { 3330 mUidRules.put(uid, newUidRules); 3331 } 3332 3333 // Second step: apply bw changes based on change of state. 3334 if (newRule != oldRule) { 3335 if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 3336 // Temporarily whitelist foreground app, removing from blacklist if necessary 3337 // (since bw_penalty_box prevails over bw_happy_box). 3338 3339 setMeteredNetworkWhitelist(uid, true); 3340 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, 3341 // but ideally it should be just: 3342 // setMeteredNetworkBlacklist(uid, isBlacklisted); 3343 if (isBlacklisted) { 3344 setMeteredNetworkBlacklist(uid, false); 3345 } 3346 } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) { 3347 // Remove temporary whitelist from app that is not on foreground anymore. 3348 3349 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, 3350 // but ideally they should be just: 3351 // setMeteredNetworkWhitelist(uid, isWhitelisted); 3352 // setMeteredNetworkBlacklist(uid, isBlacklisted); 3353 if (!isWhitelisted) { 3354 setMeteredNetworkWhitelist(uid, false); 3355 } 3356 if (isBlacklisted) { 3357 setMeteredNetworkBlacklist(uid, true); 3358 } 3359 } else if ((newRule & RULE_REJECT_METERED) != 0 3360 || (oldRule & RULE_REJECT_METERED) != 0) { 3361 // Flip state because app was explicitly added or removed to blacklist. 3362 setMeteredNetworkBlacklist(uid, isBlacklisted); 3363 if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) { 3364 // Since blacklist prevails over whitelist, we need to handle the special case 3365 // where app is whitelisted and blacklisted at the same time (although such 3366 // scenario should be blocked by the UI), then blacklist is removed. 3367 setMeteredNetworkWhitelist(uid, isWhitelisted); 3368 } 3369 } else if ((newRule & RULE_ALLOW_METERED) != 0 3370 || (oldRule & RULE_ALLOW_METERED) != 0) { 3371 // Flip state because app was explicitly added or removed to whitelist. 3372 setMeteredNetworkWhitelist(uid, isWhitelisted); 3373 } else { 3374 // All scenarios should have been covered above. 3375 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid 3376 + ": foreground=" + isForeground 3377 + ", whitelisted=" + isWhitelisted 3378 + ", blacklisted=" + isBlacklisted 3379 + ", newRule=" + uidRulesToString(newUidRules) 3380 + ", oldRule=" + uidRulesToString(oldUidRules)); 3381 } 3382 3383 // Dispatch changed rule to existing listeners. 3384 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 3385 } 3386 } 3387 3388 /** 3389 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external 3390 * listeners in case of change. 3391 * <p> 3392 * There are 3 power-related rules that affects whether an app has background access on 3393 * non-metered networks, and when the condition applies and the UID is not whitelisted for power 3394 * restriction, it's added to the equivalent firewall chain: 3395 * <ul> 3396 * <li>App is idle: {@code fw_standby} firewall chain. 3397 * <li>Device is idle: {@code fw_dozable} firewall chain. 3398 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain. 3399 * </ul> 3400 * <p> 3401 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on 3402 * these modes, the UID process state (foreground or not), and the UIDwhitelist state. 3403 * <p> 3404 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}. 3405 */ updateRulesForPowerRestrictionsUL(int uid)3406 private void updateRulesForPowerRestrictionsUL(int uid) { 3407 final int oldUidRules = mUidRules.get(uid, RULE_NONE); 3408 3409 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false); 3410 3411 if (newUidRules == RULE_NONE) { 3412 mUidRules.delete(uid); 3413 } else { 3414 mUidRules.put(uid, newUidRules); 3415 } 3416 } 3417 3418 /** 3419 * Similar to above but ignores idle state if app standby is currently disabled by parole. 3420 * 3421 * @param uid the uid of the app to update rules for 3422 * @param oldUidRules the current rules for the uid, in order to determine if there's a change 3423 * @param paroled whether to ignore idle state of apps and only look at other restrictions. 3424 * 3425 * @return the new computed rules for the uid 3426 */ updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled)3427 private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) { 3428 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 3429 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 3430 "updateRulesForPowerRestrictionsUL: " + uid + "/" + oldUidRules + "/" 3431 + (paroled ? "P" : "-")); 3432 } 3433 try { 3434 return updateRulesForPowerRestrictionsULInner(uid, oldUidRules, paroled); 3435 } finally { 3436 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3437 } 3438 } 3439 updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled)3440 private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled) { 3441 if (!isUidValidForBlacklistRules(uid)) { 3442 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); 3443 return RULE_NONE; 3444 } 3445 3446 final boolean isIdle = !paroled && isUidIdle(uid); 3447 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode; 3448 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid); 3449 3450 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode); 3451 final int oldRule = oldUidRules & MASK_ALL_NETWORKS; 3452 int newRule = RULE_NONE; 3453 3454 // First step: define the new rule based on user restrictions and foreground state. 3455 3456 // NOTE: if statements below could be inlined, but it's easier to understand the logic 3457 // by considering the foreground and non-foreground states. 3458 if (isForeground) { 3459 if (restrictMode) { 3460 newRule = RULE_ALLOW_ALL; 3461 } 3462 } else if (restrictMode) { 3463 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL; 3464 } 3465 3466 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule; 3467 3468 if (LOGV) { 3469 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")" 3470 + ", isIdle: " + isIdle 3471 + ", mRestrictPower: " + mRestrictPower 3472 + ", mDeviceIdleMode: " + mDeviceIdleMode 3473 + ", isForeground=" + isForeground 3474 + ", isWhitelisted=" + isWhitelisted 3475 + ", oldRule=" + uidRulesToString(oldRule) 3476 + ", newRule=" + uidRulesToString(newRule) 3477 + ", newUidRules=" + uidRulesToString(newUidRules) 3478 + ", oldUidRules=" + uidRulesToString(oldUidRules)); 3479 } 3480 3481 // Second step: notify listeners if state changed. 3482 if (newRule != oldRule) { 3483 if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) { 3484 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid); 3485 } else if ((newRule & RULE_REJECT_ALL) != 0) { 3486 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid); 3487 } else { 3488 // All scenarios should have been covered above 3489 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid 3490 + ": foreground=" + isForeground 3491 + ", whitelisted=" + isWhitelisted 3492 + ", newRule=" + uidRulesToString(newUidRules) 3493 + ", oldRule=" + uidRulesToString(oldUidRules)); 3494 } 3495 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget(); 3496 } 3497 3498 return newUidRules; 3499 } 3500 3501 private class AppIdleStateChangeListener 3502 extends UsageStatsManagerInternal.AppIdleStateChangeListener { 3503 3504 @Override onAppIdleStateChanged(String packageName, int userId, boolean idle)3505 public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { 3506 try { 3507 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 3508 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 3509 if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle); 3510 synchronized (mUidRulesFirstLock) { 3511 updateRuleForAppIdleUL(uid); 3512 updateRulesForPowerRestrictionsUL(uid); 3513 } 3514 } catch (NameNotFoundException nnfe) { 3515 } 3516 } 3517 3518 @Override onParoleStateChanged(boolean isParoleOn)3519 public void onParoleStateChanged(boolean isParoleOn) { 3520 synchronized (mUidRulesFirstLock) { 3521 updateRulesForAppIdleParoleUL(); 3522 } 3523 } 3524 } 3525 dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules)3526 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) { 3527 if (listener != null) { 3528 try { 3529 listener.onUidRulesChanged(uid, uidRules); 3530 } catch (RemoteException ignored) { 3531 } 3532 } 3533 } 3534 dispatchMeteredIfacesChanged(INetworkPolicyListener listener, String[] meteredIfaces)3535 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener, 3536 String[] meteredIfaces) { 3537 if (listener != null) { 3538 try { 3539 listener.onMeteredIfacesChanged(meteredIfaces); 3540 } catch (RemoteException ignored) { 3541 } 3542 } 3543 } 3544 dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, boolean restrictBackground)3545 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener, 3546 boolean restrictBackground) { 3547 if (listener != null) { 3548 try { 3549 listener.onRestrictBackgroundChanged(restrictBackground); 3550 } catch (RemoteException ignored) { 3551 } 3552 } 3553 } 3554 dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid, int uidPolicies)3555 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid, 3556 int uidPolicies) { 3557 if (listener != null) { 3558 try { 3559 listener.onUidPoliciesChanged(uid, uidPolicies); 3560 } catch (RemoteException ignored) { 3561 } 3562 } 3563 } 3564 3565 private final Handler.Callback mHandlerCallback = new Handler.Callback() { 3566 @Override 3567 public boolean handleMessage(Message msg) { 3568 switch (msg.what) { 3569 case MSG_RULES_CHANGED: { 3570 final int uid = msg.arg1; 3571 final int uidRules = msg.arg2; 3572 final int length = mListeners.beginBroadcast(); 3573 for (int i = 0; i < length; i++) { 3574 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3575 dispatchUidRulesChanged(listener, uid, uidRules); 3576 } 3577 mListeners.finishBroadcast(); 3578 return true; 3579 } 3580 case MSG_METERED_IFACES_CHANGED: { 3581 final String[] meteredIfaces = (String[]) msg.obj; 3582 final int length = mListeners.beginBroadcast(); 3583 for (int i = 0; i < length; i++) { 3584 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3585 dispatchMeteredIfacesChanged(listener, meteredIfaces); 3586 } 3587 mListeners.finishBroadcast(); 3588 return true; 3589 } 3590 case MSG_LIMIT_REACHED: { 3591 final String iface = (String) msg.obj; 3592 3593 maybeRefreshTrustedTime(); 3594 synchronized (mNetworkPoliciesSecondLock) { 3595 if (mMeteredIfaces.contains(iface)) { 3596 try { 3597 // force stats update to make sure we have 3598 // numbers that caused alert to trigger. 3599 mNetworkStats.forceUpdate(); 3600 } catch (RemoteException e) { 3601 // ignored; service lives in system_server 3602 } 3603 3604 updateNetworkEnabledNL(); 3605 updateNotificationsNL(); 3606 } 3607 } 3608 return true; 3609 } 3610 case MSG_RESTRICT_BACKGROUND_CHANGED: { 3611 final boolean restrictBackground = msg.arg1 != 0; 3612 final int length = mListeners.beginBroadcast(); 3613 for (int i = 0; i < length; i++) { 3614 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3615 dispatchRestrictBackgroundChanged(listener, restrictBackground); 3616 } 3617 mListeners.finishBroadcast(); 3618 final Intent intent = 3619 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3620 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3621 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3622 return true; 3623 } 3624 case MSG_POLICIES_CHANGED: { 3625 final int uid = msg.arg1; 3626 final int policy = msg.arg2; 3627 final Boolean notifyApp = (Boolean) msg.obj; 3628 // First notify internal listeners... 3629 final int length = mListeners.beginBroadcast(); 3630 for (int i = 0; i < length; i++) { 3631 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 3632 dispatchUidPoliciesChanged(listener, uid, policy); 3633 } 3634 mListeners.finishBroadcast(); 3635 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED 3636 if (notifyApp.booleanValue()) { 3637 broadcastRestrictBackgroundChanged(uid, notifyApp); 3638 } 3639 return true; 3640 } 3641 case MSG_ADVISE_PERSIST_THRESHOLD: { 3642 final long lowestRule = (Long) msg.obj; 3643 try { 3644 // make sure stats are recorded frequently enough; we aim 3645 // for 2MB threshold for 2GB/month rules. 3646 final long persistThreshold = lowestRule / 1000; 3647 mNetworkStats.advisePersistThreshold(persistThreshold); 3648 } catch (RemoteException e) { 3649 // ignored; service lives in system_server 3650 } 3651 return true; 3652 } 3653 case MSG_UPDATE_INTERFACE_QUOTA: { 3654 removeInterfaceQuota((String) msg.obj); 3655 // int params need to be stitched back into a long 3656 setInterfaceQuota((String) msg.obj, 3657 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); 3658 return true; 3659 } 3660 case MSG_REMOVE_INTERFACE_QUOTA: { 3661 removeInterfaceQuota((String) msg.obj); 3662 return true; 3663 } 3664 case MSG_SET_FIREWALL_RULES: { 3665 final int chain = msg.arg1; 3666 final int toggle = msg.arg2; 3667 final SparseIntArray uidRules = (SparseIntArray) msg.obj; 3668 if (uidRules != null) { 3669 setUidFirewallRules(chain, uidRules); 3670 } 3671 if (toggle != CHAIN_TOGGLE_NONE) { 3672 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE); 3673 } 3674 return true; 3675 } 3676 case MSG_RESET_FIREWALL_RULES_BY_UID: { 3677 resetUidFirewallRules(msg.arg1); 3678 return true; 3679 } 3680 default: { 3681 return false; 3682 } 3683 } 3684 } 3685 }; 3686 3687 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() { 3688 @Override 3689 public boolean handleMessage(Message msg) { 3690 switch (msg.what) { 3691 case UID_MSG_STATE_CHANGED: { 3692 final int uid = msg.arg1; 3693 final int procState = msg.arg2; 3694 final long procStateSeq = (Long) msg.obj; 3695 3696 handleUidChanged(uid, procState, procStateSeq); 3697 return true; 3698 } 3699 case UID_MSG_GONE: { 3700 final int uid = msg.arg1; 3701 handleUidGone(uid); 3702 return true; 3703 } 3704 default: { 3705 return false; 3706 } 3707 } 3708 } 3709 3710 }; 3711 handleUidChanged(int uid, int procState, long procStateSeq)3712 void handleUidChanged(int uid, int procState, long procStateSeq) { 3713 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); 3714 try { 3715 synchronized (mUidRulesFirstLock) { 3716 // We received a uid state change callback, add it to the history so that it 3717 // will be useful for debugging. 3718 mObservedHistory.addProcStateSeqUL(uid, procStateSeq); 3719 // Now update the network policy rules as per the updated uid state. 3720 updateUidStateUL(uid, procState); 3721 // Updating the network rules is done, so notify AMS about this. 3722 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); 3723 } 3724 } finally { 3725 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3726 } 3727 } 3728 handleUidGone(int uid)3729 void handleUidGone(int uid) { 3730 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); 3731 try { 3732 synchronized (mUidRulesFirstLock) { 3733 removeUidStateUL(uid); 3734 } 3735 } finally { 3736 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3737 } 3738 } 3739 broadcastRestrictBackgroundChanged(int uid, Boolean changed)3740 private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) { 3741 final PackageManager pm = mContext.getPackageManager(); 3742 final String[] packages = pm.getPackagesForUid(uid); 3743 if (packages != null) { 3744 final int userId = UserHandle.getUserId(uid); 3745 for (String packageName : packages) { 3746 final Intent intent = 3747 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 3748 intent.setPackage(packageName); 3749 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3750 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 3751 } 3752 } 3753 } 3754 setInterfaceQuota(String iface, long quotaBytes)3755 private void setInterfaceQuota(String iface, long quotaBytes) { 3756 try { 3757 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 3758 } catch (IllegalStateException e) { 3759 Log.wtf(TAG, "problem setting interface quota", e); 3760 } catch (RemoteException e) { 3761 // ignored; service lives in system_server 3762 } 3763 } 3764 removeInterfaceQuota(String iface)3765 private void removeInterfaceQuota(String iface) { 3766 try { 3767 mNetworkManager.removeInterfaceQuota(iface); 3768 } catch (IllegalStateException e) { 3769 Log.wtf(TAG, "problem removing interface quota", e); 3770 } catch (RemoteException e) { 3771 // ignored; service lives in system_server 3772 } 3773 } 3774 setMeteredNetworkBlacklist(int uid, boolean enable)3775 private void setMeteredNetworkBlacklist(int uid, boolean enable) { 3776 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); 3777 try { 3778 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); 3779 } catch (IllegalStateException e) { 3780 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); 3781 } catch (RemoteException e) { 3782 // ignored; service lives in system_server 3783 } 3784 } 3785 setMeteredNetworkWhitelist(int uid, boolean enable)3786 private void setMeteredNetworkWhitelist(int uid, boolean enable) { 3787 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); 3788 try { 3789 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); 3790 } catch (IllegalStateException e) { 3791 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); 3792 } catch (RemoteException e) { 3793 // ignored; service lives in system_server 3794 } 3795 } 3796 3797 private static final int CHAIN_TOGGLE_NONE = 0; 3798 private static final int CHAIN_TOGGLE_ENABLE = 1; 3799 private static final int CHAIN_TOGGLE_DISABLE = 2; 3800 @Retention(RetentionPolicy.SOURCE) 3801 @IntDef(flag = false, value = { 3802 CHAIN_TOGGLE_NONE, 3803 CHAIN_TOGGLE_ENABLE, 3804 CHAIN_TOGGLE_DISABLE 3805 }) 3806 public @interface ChainToggleType { 3807 } 3808 3809 /** 3810 * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and 3811 * {@link #enableFirewallChainUL(int, boolean)} asynchronously. 3812 * 3813 * @param chain firewall chain. 3814 * @param uidRules new UID rules; if {@code null}, only toggles chain state. 3815 * @param toggle whether the chain should be enabled, disabled, or not changed. 3816 */ setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules, @ChainToggleType int toggle)3817 private void setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules, 3818 @ChainToggleType int toggle) { 3819 mHandler.obtainMessage(MSG_SET_FIREWALL_RULES, chain, toggle, uidRules).sendToTarget(); 3820 } 3821 3822 /** 3823 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given 3824 * here to netd. It will clean up dead rules and make sure the target chain only contains rules 3825 * specified here. 3826 */ setUidFirewallRules(int chain, SparseIntArray uidRules)3827 private void setUidFirewallRules(int chain, SparseIntArray uidRules) { 3828 try { 3829 int size = uidRules.size(); 3830 int[] uids = new int[size]; 3831 int[] rules = new int[size]; 3832 for(int index = size - 1; index >= 0; --index) { 3833 uids[index] = uidRules.keyAt(index); 3834 rules[index] = uidRules.valueAt(index); 3835 } 3836 mNetworkManager.setFirewallUidRules(chain, uids, rules); 3837 } catch (IllegalStateException e) { 3838 Log.wtf(TAG, "problem setting firewall uid rules", e); 3839 } catch (RemoteException e) { 3840 // ignored; service lives in system_server 3841 } 3842 } 3843 3844 /** 3845 * Add or remove a uid to the firewall blacklist for all network ifaces. 3846 */ setUidFirewallRule(int chain, int uid, int rule)3847 private void setUidFirewallRule(int chain, int uid, int rule) { 3848 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { 3849 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, 3850 "setUidFirewallRule: " + chain + "/" + uid + "/" + rule); 3851 } 3852 try { 3853 if (chain == FIREWALL_CHAIN_DOZABLE) { 3854 mUidFirewallDozableRules.put(uid, rule); 3855 } else if (chain == FIREWALL_CHAIN_STANDBY) { 3856 mUidFirewallStandbyRules.put(uid, rule); 3857 } else if (chain == FIREWALL_CHAIN_POWERSAVE) { 3858 mUidFirewallPowerSaveRules.put(uid, rule); 3859 } 3860 3861 try { 3862 mNetworkManager.setFirewallUidRule(chain, uid, rule); 3863 } catch (IllegalStateException e) { 3864 Log.wtf(TAG, "problem setting firewall uid rules", e); 3865 } catch (RemoteException e) { 3866 // ignored; service lives in system_server 3867 } 3868 } finally { 3869 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 3870 } 3871 } 3872 3873 /** 3874 * Add or remove a uid to the firewall blacklist for all network ifaces. 3875 */ enableFirewallChainUL(int chain, boolean enable)3876 private void enableFirewallChainUL(int chain, boolean enable) { 3877 if (mFirewallChainStates.indexOfKey(chain) >= 0 && 3878 mFirewallChainStates.get(chain) == enable) { 3879 // All is the same, nothing to do. 3880 return; 3881 } 3882 mFirewallChainStates.put(chain, enable); 3883 try { 3884 mNetworkManager.setFirewallChainEnabled(chain, enable); 3885 } catch (IllegalStateException e) { 3886 Log.wtf(TAG, "problem enable firewall chain", e); 3887 } catch (RemoteException e) { 3888 // ignored; service lives in system_server 3889 } 3890 } 3891 3892 /** 3893 * Resets all firewall rules associated with an UID. 3894 */ resetUidFirewallRules(int uid)3895 private void resetUidFirewallRules(int uid) { 3896 try { 3897 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT); 3898 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); 3899 mNetworkManager 3900 .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT); 3901 mNetworkManager.setUidMeteredNetworkWhitelist(uid, false); 3902 mNetworkManager.setUidMeteredNetworkBlacklist(uid, false); 3903 } catch (IllegalStateException e) { 3904 Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e); 3905 } catch (RemoteException e) { 3906 // ignored; service lives in system_server 3907 } 3908 } 3909 getTotalBytes(NetworkTemplate template, long start, long end)3910 private long getTotalBytes(NetworkTemplate template, long start, long end) { 3911 try { 3912 return mNetworkStats.getNetworkTotalBytes(template, start, end); 3913 } catch (RuntimeException e) { 3914 Slog.w(TAG, "problem reading network stats: " + e); 3915 return 0; 3916 } catch (RemoteException e) { 3917 // ignored; service lives in system_server 3918 return 0; 3919 } 3920 } 3921 isBandwidthControlEnabled()3922 private boolean isBandwidthControlEnabled() { 3923 final long token = Binder.clearCallingIdentity(); 3924 try { 3925 return mNetworkManager.isBandwidthControlEnabled(); 3926 } catch (RemoteException e) { 3927 // ignored; service lives in system_server 3928 return false; 3929 } finally { 3930 Binder.restoreCallingIdentity(token); 3931 } 3932 } 3933 3934 /** 3935 * Try refreshing {@link #mTime} when stale. 3936 */ maybeRefreshTrustedTime()3937 void maybeRefreshTrustedTime() { 3938 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3939 mTime.forceRefresh(); 3940 } 3941 } 3942 currentTimeMillis()3943 private long currentTimeMillis() { 3944 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3945 } 3946 buildAllowBackgroundDataIntent()3947 private static Intent buildAllowBackgroundDataIntent() { 3948 return new Intent(ACTION_ALLOW_BACKGROUND); 3949 } 3950 buildSnoozeWarningIntent(NetworkTemplate template)3951 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 3952 final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 3953 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3954 return intent; 3955 } 3956 buildNetworkOverLimitIntent(Resources res, NetworkTemplate template)3957 private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) { 3958 final Intent intent = new Intent(); 3959 intent.setComponent(ComponentName.unflattenFromString( 3960 res.getString(R.string.config_networkOverLimitComponent))); 3961 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3962 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3963 return intent; 3964 } 3965 buildViewDataUsageIntent(Resources res, NetworkTemplate template)3966 private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) { 3967 final Intent intent = new Intent(); 3968 intent.setComponent(ComponentName.unflattenFromString( 3969 res.getString(R.string.config_dataUsageSummaryComponent))); 3970 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3971 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 3972 return intent; 3973 } 3974 3975 @VisibleForTesting addIdleHandler(IdleHandler handler)3976 public void addIdleHandler(IdleHandler handler) { 3977 mHandler.getLooper().getQueue().addIdleHandler(handler); 3978 } 3979 3980 @VisibleForTesting updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result)3981 public void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) { 3982 mRestrictBackgroundPowerState = result; 3983 3984 boolean restrictBackground = result.batterySaverEnabled; 3985 boolean shouldInvokeRestrictBackground; 3986 // store the temporary mRestrictBackgroundChangedInBsm and update it at last 3987 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm; 3988 3989 if (result.globalBatterySaverEnabled) { 3990 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to 3991 // turn it on. 3992 shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled; 3993 mRestrictBackgroundBeforeBsm = mRestrictBackground; 3994 localRestrictBgChangedInBsm = false; 3995 } else { 3996 // Try to restore the restrictBackground if it doesn't change in bsm 3997 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm; 3998 restrictBackground = mRestrictBackgroundBeforeBsm; 3999 } 4000 4001 if (shouldInvokeRestrictBackground) { 4002 setRestrictBackground(restrictBackground); 4003 } 4004 4005 // Change it at last so setRestrictBackground() won't affect this variable 4006 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm; 4007 } 4008 collectKeys(SparseIntArray source, SparseBooleanArray target)4009 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 4010 final int size = source.size(); 4011 for (int i = 0; i < size; i++) { 4012 target.put(source.keyAt(i), true); 4013 } 4014 } 4015 4016 @Override factoryReset(String subscriber)4017 public void factoryReset(String subscriber) { 4018 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 4019 4020 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 4021 return; 4022 } 4023 4024 // Turn mobile data limit off 4025 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); 4026 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); 4027 for (NetworkPolicy policy : policies) { 4028 if (policy.template.equals(template)) { 4029 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; 4030 policy.inferred = false; 4031 policy.clearSnooze(); 4032 } 4033 } 4034 setNetworkPolicies(policies); 4035 4036 // Turn restrict background data off 4037 setRestrictBackground(false); 4038 4039 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) { 4040 // Remove app's "restrict background data" flag 4041 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) { 4042 setUidPolicy(uid, POLICY_NONE); 4043 } 4044 } 4045 } 4046 4047 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal { 4048 4049 @Override resetUserState(int userId)4050 public void resetUserState(int userId) { 4051 synchronized (mUidRulesFirstLock) { 4052 boolean changed = removeUserStateUL(userId, false); 4053 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed; 4054 if (changed) { 4055 synchronized (mNetworkPoliciesSecondLock) { 4056 writePolicyAL(); 4057 } 4058 } 4059 } 4060 } 4061 4062 /** 4063 * @return true if the given uid is restricted from doing networking on metered networks. 4064 */ 4065 @Override isUidRestrictedOnMeteredNetworks(int uid)4066 public boolean isUidRestrictedOnMeteredNetworks(int uid) { 4067 final int uidRules; 4068 final boolean isBackgroundRestricted; 4069 synchronized (mUidRulesFirstLock) { 4070 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL); 4071 isBackgroundRestricted = mRestrictBackground; 4072 } 4073 return isBackgroundRestricted 4074 && !hasRule(uidRules, RULE_ALLOW_METERED) 4075 && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED); 4076 } 4077 4078 /** 4079 * @return true if networking is blocked on the given interface for the given uid according 4080 * to current networking policies. 4081 */ 4082 @Override isUidNetworkingBlocked(int uid, String ifname)4083 public boolean isUidNetworkingBlocked(int uid, String ifname) { 4084 final int uidRules; 4085 final boolean isBackgroundRestricted; 4086 final boolean isNetworkMetered; 4087 synchronized (mUidRulesFirstLock) { 4088 uidRules = mUidRules.get(uid, RULE_NONE); 4089 isBackgroundRestricted = mRestrictBackground; 4090 synchronized (mNetworkPoliciesSecondLock) { 4091 isNetworkMetered = mMeteredIfaces.contains(ifname); 4092 } 4093 } 4094 if (hasRule(uidRules, RULE_REJECT_ALL)) { 4095 if (LOGV) logUidStatus(uid, "blocked by power restrictions"); 4096 return true; 4097 } 4098 if (!isNetworkMetered) { 4099 if (LOGV) logUidStatus(uid, "allowed on unmetered network"); 4100 return false; 4101 } 4102 if (hasRule(uidRules, RULE_REJECT_METERED)) { 4103 if (LOGV) logUidStatus(uid, "blacklisted on metered network"); 4104 return true; 4105 } 4106 if (hasRule(uidRules, RULE_ALLOW_METERED)) { 4107 if (LOGV) logUidStatus(uid, "whitelisted on metered network"); 4108 return false; 4109 } 4110 if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) { 4111 if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network"); 4112 return false; 4113 } 4114 if (isBackgroundRestricted) { 4115 if (LOGV) logUidStatus(uid, "blocked when background is restricted"); 4116 return true; 4117 } 4118 if (LOGV) logUidStatus(uid, "allowed by default"); 4119 return false; 4120 } 4121 } 4122 hasRule(int uidRules, int rule)4123 private static boolean hasRule(int uidRules, int rule) { 4124 return (uidRules & rule) != 0; 4125 } 4126 logUidStatus(int uid, String descr)4127 private static void logUidStatus(int uid, String descr) { 4128 Slog.d(TAG, String.format("uid %d is %s", uid, descr)); 4129 } 4130 4131 /** 4132 * This class is used for storing and dumping the last {@link #MAX_PROC_STATE_SEQ_HISTORY} 4133 * (uid, procStateSeq) pairs. 4134 */ 4135 @VisibleForTesting 4136 public static final class ProcStateSeqHistory { 4137 private static final int INVALID_UID = -1; 4138 4139 /** 4140 * Denotes maximum number of items this history can hold. 4141 */ 4142 private final int mMaxCapacity; 4143 /** 4144 * Used for storing the uid information. 4145 */ 4146 private final int[] mUids; 4147 /** 4148 * Used for storing the sequence numbers associated with {@link #mUids}. 4149 */ 4150 private final long[] mProcStateSeqs; 4151 /** 4152 * Points to the next available slot for writing (uid, procStateSeq) pair. 4153 */ 4154 private int mHistoryNext; 4155 ProcStateSeqHistory(int maxCapacity)4156 public ProcStateSeqHistory(int maxCapacity) { 4157 mMaxCapacity = maxCapacity; 4158 mUids = new int[mMaxCapacity]; 4159 Arrays.fill(mUids, INVALID_UID); 4160 mProcStateSeqs = new long[mMaxCapacity]; 4161 } 4162 4163 @GuardedBy("mUidRulesFirstLock") addProcStateSeqUL(int uid, long procStateSeq)4164 public void addProcStateSeqUL(int uid, long procStateSeq) { 4165 mUids[mHistoryNext] = uid; 4166 mProcStateSeqs[mHistoryNext] = procStateSeq; 4167 mHistoryNext = increaseNext(mHistoryNext, 1); 4168 } 4169 4170 @GuardedBy("mUidRulesFirstLock") dumpUL(IndentingPrintWriter fout)4171 public void dumpUL(IndentingPrintWriter fout) { 4172 if (mUids[0] == INVALID_UID) { 4173 fout.println("NONE"); 4174 return; 4175 } 4176 int index = mHistoryNext; 4177 do { 4178 index = increaseNext(index, -1); 4179 if (mUids[index] == INVALID_UID) { 4180 break; 4181 } 4182 fout.println(getString(mUids[index], mProcStateSeqs[index])); 4183 } while (index != mHistoryNext); 4184 } 4185 getString(int uid, long procStateSeq)4186 public static String getString(int uid, long procStateSeq) { 4187 return "UID=" + uid + " procStateSeq=" + procStateSeq; 4188 } 4189 increaseNext(int next, int increment)4190 private int increaseNext(int next, int increment) { 4191 next += increment; 4192 if (next >= mMaxCapacity) { 4193 next = 0; 4194 } else if (next < 0) { 4195 next = mMaxCapacity - 1; 4196 } 4197 return next; 4198 } 4199 } 4200 4201 private class NotificationId { 4202 private final String mTag; 4203 private final int mId; 4204 NotificationId(NetworkPolicy policy, int type)4205 NotificationId(NetworkPolicy policy, int type) { 4206 mTag = buildNotificationTag(policy, type); 4207 mId = type; 4208 } 4209 4210 @Override equals(Object o)4211 public boolean equals(Object o) { 4212 if (this == o) return true; 4213 if (!(o instanceof NotificationId)) return false; 4214 NotificationId that = (NotificationId) o; 4215 return Objects.equals(mTag, that.mTag); 4216 } 4217 4218 @Override hashCode()4219 public int hashCode() { 4220 return Objects.hash(mTag); 4221 } 4222 4223 /** 4224 * Build unique tag that identifies an active {@link NetworkPolicy} 4225 * notification of a specific type, like {@link #TYPE_LIMIT}. 4226 */ buildNotificationTag(NetworkPolicy policy, int type)4227 private String buildNotificationTag(NetworkPolicy policy, int type) { 4228 return TAG + ":" + policy.template.hashCode() + ":" + type; 4229 } 4230 getTag()4231 public String getTag() { 4232 return mTag; 4233 } 4234 getId()4235 public int getId() { 4236 return mId; 4237 } 4238 } 4239 } 4240