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 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 469 private static File getSystemDir() { 470 return new File(Environment.getDataDirectory(), "system"); 471 } 472 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 508 public void bindConnectivityManager(IConnectivityManager connManager) { 509 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 510 } 511 512 public void bindNotificationManager(INotificationManager notifManager) { 513 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 514 } 515 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 */ 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 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 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 */ 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 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 784 public CountDownLatch networkScoreAndNetworkManagementServiceReady() { 785 final CountDownLatch initCompleteSignal = new CountDownLatch(1); 786 mHandler.post(() -> initService(initCompleteSignal)); 787 return initCompleteSignal; 788 } 789 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 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 */ 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 */ 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 */ 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 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 */ 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 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 */ 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 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 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 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 */ 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 */ 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 */ 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 */ 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 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 1781 private long getPlatformDefaultLimitBytes() { 1782 return LIMIT_DISABLED; 1783 } 1784 1785 @VisibleForTesting 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 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 */ 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 2303 private void normalizePoliciesNL() { 2304 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName())); 2305 } 2306 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 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 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 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 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 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 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 2462 public boolean getRestrictBackground() { 2463 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2464 2465 synchronized (mUidRulesFirstLock) { 2466 return mRestrictBackground; 2467 } 2468 } 2469 2470 @Override 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 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 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 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 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 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 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 2735 public boolean isUidForeground(int uid) { 2736 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 2737 2738 synchronized (mUidRulesFirstLock) { 2739 return isUidForegroundUL(uid); 2740 } 2741 } 2742 2743 private boolean isUidForegroundUL(int uid) { 2744 return isUidStateForegroundUL( 2745 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)); 2746 } 2747 2748 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) { 2749 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2750 return isProcStateAllowedWhileOnRestrictBackground(procState); 2751 } 2752 2753 private boolean isUidForegroundOnRestrictPowerUL(int uid) { 2754 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2755 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState); 2756 } 2757 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 */ 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 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 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 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 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 2852 void updateRuleForRestrictPowerUL(int uid) { 2853 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE); 2854 } 2855 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 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. 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 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 */ 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. 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 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 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 */ 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 */ 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 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 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... 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 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. 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 3156 private boolean isUidValidForWhitelistRules(int uid) { 3157 return UserHandle.isApp(uid) && hasInternetPermissions(uid); 3158 } 3159 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 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 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 3519 public void onParoleStateChanged(boolean isParoleOn) { 3520 synchronized (mUidRulesFirstLock) { 3521 updateRulesForAppIdleParoleUL(); 3522 } 3523 } 3524 } 3525 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 3937 void maybeRefreshTrustedTime() { 3938 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 3939 mTime.forceRefresh(); 3940 } 3941 } 3942 3943 private long currentTimeMillis() { 3944 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 3945 } 3946 3947 private static Intent buildAllowBackgroundDataIntent() { 3948 return new Intent(ACTION_ALLOW_BACKGROUND); 3949 } 3950 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 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 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 3976 public void addIdleHandler(IdleHandler handler) { 3977 mHandler.getLooper().getQueue().addIdleHandler(handler); 3978 } 3979 3980 @VisibleForTesting 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 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 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 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 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 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 4123 private static boolean hasRule(int uidRules, int rule) { 4124 return (uidRules & rule) != 0; 4125 } 4126 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 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") 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") 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 4186 public static String getString(int uid, long procStateSeq) { 4187 return "UID=" + uid + " procStateSeq=" + procStateSeq; 4188 } 4189 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 4205 NotificationId(NetworkPolicy policy, int type) { 4206 mTag = buildNotificationTag(policy, type); 4207 mId = type; 4208 } 4209 4210 @Override 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 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 */ 4227 private String buildNotificationTag(NetworkPolicy policy, int type) { 4228 return TAG + ":" + policy.template.hashCode() + ":" + type; 4229 } 4230 4231 public String getTag() { 4232 return mTag; 4233 } 4234 4235 public int getId() { 4236 return mId; 4237 } 4238 } 4239 } 4240