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