1 /* 2 * Copyright (C) 2008 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; 18 19 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; 20 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 22 import static android.net.ConnectivityManager.NETID_UNSET; 23 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 24 import static android.net.ConnectivityManager.TYPE_ETHERNET; 25 import static android.net.ConnectivityManager.TYPE_NONE; 26 import static android.net.ConnectivityManager.TYPE_VPN; 27 import static android.net.ConnectivityManager.getNetworkTypeName; 28 import static android.net.ConnectivityManager.isNetworkTypeValid; 29 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 30 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 31 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 32 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 33 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 34 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 35 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 36 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 37 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 38 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 39 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 40 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 41 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 42 import static android.net.NetworkPolicyManager.RULE_NONE; 43 import static android.net.NetworkPolicyManager.uidRulesToString; 44 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired; 45 import static android.os.Process.INVALID_UID; 46 import static android.system.OsConstants.IPPROTO_TCP; 47 import static android.system.OsConstants.IPPROTO_UDP; 48 49 import static com.android.internal.util.Preconditions.checkNotNull; 50 51 import android.annotation.NonNull; 52 import android.annotation.Nullable; 53 import android.app.BroadcastOptions; 54 import android.app.NotificationManager; 55 import android.app.PendingIntent; 56 import android.content.BroadcastReceiver; 57 import android.content.ContentResolver; 58 import android.content.Context; 59 import android.content.Intent; 60 import android.content.IntentFilter; 61 import android.content.res.Configuration; 62 import android.database.ContentObserver; 63 import android.net.CaptivePortal; 64 import android.net.ConnectionInfo; 65 import android.net.ConnectivityManager; 66 import android.net.ICaptivePortal; 67 import android.net.IConnectivityManager; 68 import android.net.IDnsResolver; 69 import android.net.IIpConnectivityMetrics; 70 import android.net.INetd; 71 import android.net.INetdEventCallback; 72 import android.net.INetworkManagementEventObserver; 73 import android.net.INetworkMonitor; 74 import android.net.INetworkMonitorCallbacks; 75 import android.net.INetworkPolicyListener; 76 import android.net.INetworkPolicyManager; 77 import android.net.INetworkStatsService; 78 import android.net.ISocketKeepaliveCallback; 79 import android.net.ITetheringEventCallback; 80 import android.net.InetAddresses; 81 import android.net.IpMemoryStore; 82 import android.net.IpPrefix; 83 import android.net.LinkProperties; 84 import android.net.LinkProperties.CompareResult; 85 import android.net.MatchAllNetworkSpecifier; 86 import android.net.NattSocketKeepalive; 87 import android.net.Network; 88 import android.net.NetworkAgent; 89 import android.net.NetworkCapabilities; 90 import android.net.NetworkConfig; 91 import android.net.NetworkFactory; 92 import android.net.NetworkInfo; 93 import android.net.NetworkInfo.DetailedState; 94 import android.net.NetworkMisc; 95 import android.net.NetworkMonitorManager; 96 import android.net.NetworkPolicyManager; 97 import android.net.NetworkQuotaInfo; 98 import android.net.NetworkRequest; 99 import android.net.NetworkSpecifier; 100 import android.net.NetworkStack; 101 import android.net.NetworkStackClient; 102 import android.net.NetworkState; 103 import android.net.NetworkUtils; 104 import android.net.NetworkWatchlistManager; 105 import android.net.PrivateDnsConfigParcel; 106 import android.net.ProxyInfo; 107 import android.net.RouteInfo; 108 import android.net.SocketKeepalive; 109 import android.net.UidRange; 110 import android.net.Uri; 111 import android.net.VpnService; 112 import android.net.metrics.IpConnectivityLog; 113 import android.net.metrics.NetworkEvent; 114 import android.net.netlink.InetDiagMessage; 115 import android.net.shared.PrivateDnsConfig; 116 import android.net.util.MultinetworkPolicyTracker; 117 import android.net.util.NetdService; 118 import android.os.Binder; 119 import android.os.Build; 120 import android.os.Bundle; 121 import android.os.Handler; 122 import android.os.HandlerThread; 123 import android.os.IBinder; 124 import android.os.INetworkManagementService; 125 import android.os.Looper; 126 import android.os.Message; 127 import android.os.Messenger; 128 import android.os.ParcelFileDescriptor; 129 import android.os.Parcelable; 130 import android.os.PowerManager; 131 import android.os.Process; 132 import android.os.RemoteException; 133 import android.os.ResultReceiver; 134 import android.os.ServiceManager; 135 import android.os.ServiceSpecificException; 136 import android.os.ShellCallback; 137 import android.os.ShellCommand; 138 import android.os.SystemClock; 139 import android.os.SystemProperties; 140 import android.os.UserHandle; 141 import android.os.UserManager; 142 import android.provider.Settings; 143 import android.security.Credentials; 144 import android.security.KeyStore; 145 import android.telephony.TelephonyManager; 146 import android.text.TextUtils; 147 import android.util.ArraySet; 148 import android.util.LocalLog; 149 import android.util.Log; 150 import android.util.Pair; 151 import android.util.Slog; 152 import android.util.SparseArray; 153 import android.util.SparseBooleanArray; 154 import android.util.SparseIntArray; 155 import android.util.Xml; 156 157 import com.android.internal.R; 158 import com.android.internal.annotations.GuardedBy; 159 import com.android.internal.annotations.VisibleForTesting; 160 import com.android.internal.app.IBatteryStats; 161 import com.android.internal.logging.MetricsLogger; 162 import com.android.internal.net.LegacyVpnInfo; 163 import com.android.internal.net.VpnConfig; 164 import com.android.internal.net.VpnInfo; 165 import com.android.internal.net.VpnProfile; 166 import com.android.internal.util.ArrayUtils; 167 import com.android.internal.util.AsyncChannel; 168 import com.android.internal.util.DumpUtils; 169 import com.android.internal.util.IndentingPrintWriter; 170 import com.android.internal.util.MessageUtils; 171 import com.android.internal.util.WakeupMessage; 172 import com.android.internal.util.XmlUtils; 173 import com.android.server.am.BatteryStatsService; 174 import com.android.server.connectivity.AutodestructReference; 175 import com.android.server.connectivity.DataConnectionStats; 176 import com.android.server.connectivity.DnsManager; 177 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; 178 import com.android.server.connectivity.IpConnectivityMetrics; 179 import com.android.server.connectivity.KeepaliveTracker; 180 import com.android.server.connectivity.LingerMonitor; 181 import com.android.server.connectivity.MockableSystemProperties; 182 import com.android.server.connectivity.MultipathPolicyTracker; 183 import com.android.server.connectivity.NetworkAgentInfo; 184 import com.android.server.connectivity.NetworkDiagnostics; 185 import com.android.server.connectivity.NetworkNotificationManager; 186 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 187 import com.android.server.connectivity.PermissionMonitor; 188 import com.android.server.connectivity.ProxyTracker; 189 import com.android.server.connectivity.Tethering; 190 import com.android.server.connectivity.Vpn; 191 import com.android.server.connectivity.tethering.TetheringDependencies; 192 import com.android.server.net.BaseNetdEventCallback; 193 import com.android.server.net.BaseNetworkObserver; 194 import com.android.server.net.LockdownVpnTracker; 195 import com.android.server.net.NetworkPolicyManagerInternal; 196 import com.android.server.utils.PriorityDump; 197 198 import com.google.android.collect.Lists; 199 200 import org.xmlpull.v1.XmlPullParser; 201 import org.xmlpull.v1.XmlPullParserException; 202 203 import java.io.File; 204 import java.io.FileDescriptor; 205 import java.io.FileNotFoundException; 206 import java.io.FileReader; 207 import java.io.IOException; 208 import java.io.PrintWriter; 209 import java.net.Inet4Address; 210 import java.net.InetAddress; 211 import java.net.UnknownHostException; 212 import java.util.ArrayList; 213 import java.util.Arrays; 214 import java.util.Collection; 215 import java.util.Comparator; 216 import java.util.ConcurrentModificationException; 217 import java.util.HashMap; 218 import java.util.HashSet; 219 import java.util.List; 220 import java.util.Map; 221 import java.util.Objects; 222 import java.util.Set; 223 import java.util.SortedSet; 224 import java.util.TreeSet; 225 226 /** 227 * @hide 228 */ 229 public class ConnectivityService extends IConnectivityManager.Stub 230 implements PendingIntent.OnFinished { 231 private static final String TAG = ConnectivityService.class.getSimpleName(); 232 233 private static final String DIAG_ARG = "--diag"; 234 public static final String SHORT_ARG = "--short"; 235 private static final String TETHERING_ARG = "tethering"; 236 private static final String NETWORK_ARG = "networks"; 237 private static final String REQUEST_ARG = "requests"; 238 239 private static final boolean DBG = true; 240 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); 241 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 242 243 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 244 245 /** 246 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed 247 * by OEMs for configuration purposes, as this value is overridden by 248 * Settings.Global.CAPTIVE_PORTAL_HTTP_URL. 249 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose 250 * (preferably via runtime resource overlays). 251 */ 252 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL = 253 "http://connectivitycheck.gstatic.com/generate_204"; 254 255 // TODO: create better separation between radio types and network types 256 257 // how long to wait before switching back to a radio's default network 258 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 259 // system property that can override the above value 260 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 261 "android.telephony.apn-restore"; 262 263 // How long to wait before putting up a "This network doesn't have an Internet connection, 264 // connect anyway?" dialog after the user selects a network that doesn't validate. 265 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 266 267 // How long to dismiss network notification. 268 private static final int TIMEOUT_NOTIFICATION_DELAY_MS = 20 * 1000; 269 270 // Default to 30s linger time-out. Modifiable only for testing. 271 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 272 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 273 @VisibleForTesting 274 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 275 276 // How long to delay to removal of a pending intent based request. 277 // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 278 private final int mReleasePendingIntentDelayMs; 279 280 private MockableSystemProperties mSystemProperties; 281 282 private Tethering mTethering; 283 284 @VisibleForTesting 285 protected final PermissionMonitor mPermissionMonitor; 286 287 private KeyStore mKeyStore; 288 289 @VisibleForTesting 290 @GuardedBy("mVpns") 291 protected final SparseArray<Vpn> mVpns = new SparseArray<>(); 292 293 // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by 294 // a direct call to LockdownVpnTracker.isEnabled(). 295 @GuardedBy("mVpns") 296 private boolean mLockdownEnabled; 297 @GuardedBy("mVpns") 298 private LockdownVpnTracker mLockdownTracker; 299 300 /** 301 * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal 302 * handler thread, they don't need a lock. 303 */ 304 private SparseIntArray mUidRules = new SparseIntArray(); 305 /** Flag indicating if background data is restricted. */ 306 private boolean mRestrictBackground; 307 308 final private Context mContext; 309 // 0 is full bad, 100 is full good 310 private int mDefaultInetConditionPublished = 0; 311 312 private INetworkManagementService mNMS; 313 @VisibleForTesting 314 protected IDnsResolver mDnsResolver; 315 @VisibleForTesting 316 protected INetd mNetd; 317 private INetworkStatsService mStatsService; 318 private INetworkPolicyManager mPolicyManager; 319 private NetworkPolicyManagerInternal mPolicyManagerInternal; 320 321 /** 322 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple 323 * instances. 324 */ 325 @GuardedBy("mTNSLock") 326 private TestNetworkService mTNS; 327 328 private final Object mTNSLock = new Object(); 329 330 private String mCurrentTcpBufferSizes; 331 332 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 333 new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class, 334 NetworkAgentInfo.class }); 335 336 private enum ReapUnvalidatedNetworks { 337 // Tear down networks that have no chance (e.g. even if validated) of becoming 338 // the highest scoring network satisfying a NetworkRequest. This should be passed when 339 // all networks have been rematched against all NetworkRequests. 340 REAP, 341 // Don't reap networks. This should be passed when some networks have not yet been 342 // rematched against all NetworkRequests. 343 DONT_REAP 344 } 345 346 private enum UnneededFor { 347 LINGER, // Determine whether this network is unneeded and should be lingered. 348 TEARDOWN, // Determine whether this network is unneeded and should be torn down. 349 } 350 351 /** 352 * used internally to clear a wakelock when transitioning 353 * from one net to another. Clear happens when we get a new 354 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 355 * after a timeout if no network is found (typically 1 min). 356 */ 357 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 358 359 /** 360 * used internally to reload global proxy settings 361 */ 362 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 363 364 /** 365 * PAC manager has received new port. 366 */ 367 private static final int EVENT_PROXY_HAS_CHANGED = 16; 368 369 /** 370 * used internally when registering NetworkFactories 371 * obj = NetworkFactoryInfo 372 */ 373 private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; 374 375 /** 376 * used internally when registering NetworkAgents 377 * obj = Messenger 378 */ 379 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 380 381 /** 382 * used to add a network request 383 * includes a NetworkRequestInfo 384 */ 385 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 386 387 /** 388 * indicates a timeout period is over - check if we had a network yet or not 389 * and if not, call the timeout callback (but leave the request live until they 390 * cancel it. 391 * includes a NetworkRequestInfo 392 */ 393 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 394 395 /** 396 * used to add a network listener - no request 397 * includes a NetworkRequestInfo 398 */ 399 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 400 401 /** 402 * used to remove a network request, either a listener or a real request 403 * arg1 = UID of caller 404 * obj = NetworkRequest 405 */ 406 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 407 408 /** 409 * used internally when registering NetworkFactories 410 * obj = Messenger 411 */ 412 private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23; 413 414 /** 415 * used internally to expire a wakelock when transitioning 416 * from one net to another. Expire happens when we fail to find 417 * a new network (typically after 1 minute) - 418 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 419 * a replacement network. 420 */ 421 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 422 423 /** 424 * Used internally to indicate the system is ready. 425 */ 426 private static final int EVENT_SYSTEM_READY = 25; 427 428 /** 429 * used to add a network request with a pending intent 430 * obj = NetworkRequestInfo 431 */ 432 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 433 434 /** 435 * used to remove a pending intent and its associated network request. 436 * arg1 = UID of caller 437 * obj = PendingIntent 438 */ 439 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 440 441 /** 442 * used to specify whether a network should be used even if unvalidated. 443 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 444 * arg2 = whether to remember this choice in the future (1 or 0) 445 * obj = network 446 */ 447 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 448 449 /** 450 * used to ask the user to confirm a connection to an unvalidated network. 451 * obj = network 452 */ 453 private static final int EVENT_PROMPT_UNVALIDATED = 29; 454 455 /** 456 * used internally to (re)configure always-on networks. 457 */ 458 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; 459 460 /** 461 * used to add a network listener with a pending intent 462 * obj = NetworkRequestInfo 463 */ 464 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 465 466 /** 467 * used to specify whether a network should not be penalized when it becomes unvalidated. 468 */ 469 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 470 471 /** 472 * used to trigger revalidation of a network. 473 */ 474 private static final int EVENT_REVALIDATE_NETWORK = 36; 475 476 // Handle changes in Private DNS settings. 477 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; 478 479 // Handle private DNS validation status updates. 480 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; 481 482 /** 483 * Used to handle onUidRulesChanged event from NetworkPolicyManagerService. 484 */ 485 private static final int EVENT_UID_RULES_CHANGED = 39; 486 487 /** 488 * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService. 489 */ 490 private static final int EVENT_DATA_SAVER_CHANGED = 40; 491 492 /** 493 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has 494 * been tested. 495 * obj = String representing URL that Internet probe was redirect to, if it was redirected. 496 * arg1 = One of the NETWORK_TESTED_RESULT_* constants. 497 * arg2 = NetID. 498 */ 499 public static final int EVENT_NETWORK_TESTED = 41; 500 501 /** 502 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS 503 * config was resolved. 504 * obj = PrivateDnsConfig 505 * arg2 = netid 506 */ 507 public static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; 508 509 /** 510 * Request ConnectivityService display provisioning notification. 511 * arg1 = Whether to make the notification visible. 512 * arg2 = NetID. 513 * obj = Intent to be launched when notification selected by user, null if !arg1. 514 */ 515 public static final int EVENT_PROVISIONING_NOTIFICATION = 43; 516 517 /** 518 * This event can handle dismissing notification by given network id. 519 */ 520 public static final int EVENT_TIMEOUT_NOTIFICATION = 44; 521 522 /** 523 * Used to specify whether a network should be used even if connectivity is partial. 524 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for 525 * false) 526 * arg2 = whether to remember this choice in the future (1 for true or 0 for false) 527 * obj = network 528 */ 529 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 45; 530 531 /** 532 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 533 * should be shown. 534 */ 535 public static final int PROVISIONING_NOTIFICATION_SHOW = 1; 536 537 /** 538 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 539 * should be hidden. 540 */ 541 public static final int PROVISIONING_NOTIFICATION_HIDE = 0; 542 eventName(int what)543 private static String eventName(int what) { 544 return sMagicDecoderRing.get(what, Integer.toString(what)); 545 } 546 getDnsResolver()547 private static IDnsResolver getDnsResolver() { 548 return IDnsResolver.Stub 549 .asInterface(ServiceManager.getService("dnsresolver")); 550 } 551 552 /** Handler thread used for both of the handlers below. */ 553 @VisibleForTesting 554 protected final HandlerThread mHandlerThread; 555 /** Handler used for internal events. */ 556 final private InternalHandler mHandler; 557 /** Handler used for incoming {@link NetworkStateTracker} events. */ 558 final private NetworkStateTrackerHandler mTrackerHandler; 559 private final DnsManager mDnsManager; 560 561 private boolean mSystemReady; 562 private Intent mInitialBroadcast; 563 564 private PowerManager.WakeLock mNetTransitionWakeLock; 565 private int mNetTransitionWakeLockTimeout; 566 private final PowerManager.WakeLock mPendingIntentWakeLock; 567 568 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell 569 // the world when it changes. 570 @VisibleForTesting 571 protected final ProxyTracker mProxyTracker; 572 573 final private SettingsObserver mSettingsObserver; 574 575 private UserManager mUserManager; 576 577 private NetworkConfig[] mNetConfigs; 578 private int mNetworksDefined; 579 580 // the set of network types that can only be enabled by system/sig apps 581 private List mProtectedNetworks; 582 583 private TelephonyManager mTelephonyManager; 584 585 private KeepaliveTracker mKeepaliveTracker; 586 private NetworkNotificationManager mNotifier; 587 private LingerMonitor mLingerMonitor; 588 589 // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp 590 private static final int MIN_NET_ID = 100; // some reserved marks 591 private static final int MAX_NET_ID = 65535 - 0x0400; // Top 1024 bits reserved by IpSecService 592 private int mNextNetId = MIN_NET_ID; 593 594 // sequence number of NetworkRequests 595 private int mNextNetworkRequestId = 1; 596 597 // NetworkRequest activity String log entries. 598 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 599 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 600 601 // NetworkInfo blocked and unblocked String log entries 602 private static final int MAX_NETWORK_INFO_LOGS = 40; 603 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 604 605 private static final int MAX_WAKELOCK_LOGS = 20; 606 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS); 607 private int mTotalWakelockAcquisitions = 0; 608 private int mTotalWakelockReleases = 0; 609 private long mTotalWakelockDurationMs = 0; 610 private long mMaxWakelockDurationMs = 0; 611 private long mLastWakeLockAcquireTimestamp = 0; 612 613 private final IpConnectivityLog mMetricsLog; 614 615 @GuardedBy("mBandwidthRequests") 616 private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10); 617 618 @VisibleForTesting 619 final MultinetworkPolicyTracker mMultinetworkPolicyTracker; 620 621 @VisibleForTesting 622 final MultipathPolicyTracker mMultipathPolicyTracker; 623 624 /** 625 * Implements support for the legacy "one network per network type" model. 626 * 627 * We used to have a static array of NetworkStateTrackers, one for each 628 * network type, but that doesn't work any more now that we can have, 629 * for example, more that one wifi network. This class stores all the 630 * NetworkAgentInfo objects that support a given type, but the legacy 631 * API will only see the first one. 632 * 633 * It serves two main purposes: 634 * 635 * 1. Provide information about "the network for a given type" (since this 636 * API only supports one). 637 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 638 * the first network for a given type changes, or if the default network 639 * changes. 640 */ 641 @VisibleForTesting 642 static class LegacyTypeTracker { 643 644 private static final boolean DBG = true; 645 private static final boolean VDBG = false; 646 647 /** 648 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 649 * Each list holds references to all NetworkAgentInfos that are used to 650 * satisfy requests for that network type. 651 * 652 * This array is built out at startup such that an unsupported network 653 * doesn't get an ArrayList instance, making this a tristate: 654 * unsupported, supported but not active and active. 655 * 656 * The actual lists are populated when we scan the network types that 657 * are supported on this device. 658 * 659 * Threading model: 660 * - addSupportedType() is only called in the constructor 661 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 662 * They are therefore not thread-safe with respect to each other. 663 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 664 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 665 * - dump is thread-safe with respect to concurrent add and remove calls. 666 */ 667 private final ArrayList<NetworkAgentInfo> mTypeLists[]; 668 @NonNull 669 private final ConnectivityService mService; 670 LegacyTypeTracker(@onNull ConnectivityService service)671 LegacyTypeTracker(@NonNull ConnectivityService service) { 672 mService = service; 673 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 674 } 675 addSupportedType(int type)676 public void addSupportedType(int type) { 677 if (mTypeLists[type] != null) { 678 throw new IllegalStateException( 679 "legacy list for type " + type + "already initialized"); 680 } 681 mTypeLists[type] = new ArrayList<>(); 682 } 683 isTypeSupported(int type)684 public boolean isTypeSupported(int type) { 685 return isNetworkTypeValid(type) && mTypeLists[type] != null; 686 } 687 getNetworkForType(int type)688 public NetworkAgentInfo getNetworkForType(int type) { 689 synchronized (mTypeLists) { 690 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 691 return mTypeLists[type].get(0); 692 } 693 } 694 return null; 695 } 696 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)697 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 698 boolean isDefaultNetwork) { 699 if (DBG) { 700 log("Sending " + state + 701 " broadcast for type " + type + " " + nai.name() + 702 " isDefaultNetwork=" + isDefaultNetwork); 703 } 704 } 705 706 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)707 public void add(int type, NetworkAgentInfo nai) { 708 if (!isTypeSupported(type)) { 709 return; // Invalid network type. 710 } 711 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 712 713 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 714 if (list.contains(nai)) { 715 return; 716 } 717 synchronized (mTypeLists) { 718 list.add(nai); 719 } 720 721 // Send a broadcast if this is the first network of its type or if it's the default. 722 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); 723 if ((list.size() == 1) || isDefaultNetwork) { 724 maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork); 725 mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type); 726 } 727 } 728 729 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)730 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 731 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 732 if (list == null || list.isEmpty()) { 733 return; 734 } 735 final boolean wasFirstNetwork = list.get(0).equals(nai); 736 737 synchronized (mTypeLists) { 738 if (!list.remove(nai)) { 739 return; 740 } 741 } 742 743 if (wasFirstNetwork || wasDefault) { 744 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault); 745 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type); 746 } 747 748 if (!list.isEmpty() && wasFirstNetwork) { 749 if (DBG) log("Other network available for type " + type + 750 ", sending connected broadcast"); 751 final NetworkAgentInfo replacement = list.get(0); 752 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type, 753 mService.isDefaultNetwork(replacement)); 754 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type); 755 } 756 } 757 758 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)759 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 760 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 761 for (int type = 0; type < mTypeLists.length; type++) { 762 remove(type, nai, wasDefault); 763 } 764 } 765 766 // send out another legacy broadcast - currently only used for suspend/unsuspend 767 // toggle update(NetworkAgentInfo nai)768 public void update(NetworkAgentInfo nai) { 769 final boolean isDefault = mService.isDefaultNetwork(nai); 770 final DetailedState state = nai.networkInfo.getDetailedState(); 771 for (int type = 0; type < mTypeLists.length; type++) { 772 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 773 final boolean contains = (list != null && list.contains(nai)); 774 final boolean isFirst = contains && (nai == list.get(0)); 775 if (isFirst || contains && isDefault) { 776 maybeLogBroadcast(nai, state, type, isDefault); 777 mService.sendLegacyNetworkBroadcast(nai, state, type); 778 } 779 } 780 } 781 naiToString(NetworkAgentInfo nai)782 private String naiToString(NetworkAgentInfo nai) { 783 String name = nai.name(); 784 String state = (nai.networkInfo != null) ? 785 nai.networkInfo.getState() + "/" + nai.networkInfo.getDetailedState() : 786 "???/???"; 787 return name + " " + state; 788 } 789 dump(IndentingPrintWriter pw)790 public void dump(IndentingPrintWriter pw) { 791 pw.println("mLegacyTypeTracker:"); 792 pw.increaseIndent(); 793 pw.print("Supported types:"); 794 for (int type = 0; type < mTypeLists.length; type++) { 795 if (mTypeLists[type] != null) pw.print(" " + type); 796 } 797 pw.println(); 798 pw.println("Current state:"); 799 pw.increaseIndent(); 800 synchronized (mTypeLists) { 801 for (int type = 0; type < mTypeLists.length; type++) { 802 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 803 for (NetworkAgentInfo nai : mTypeLists[type]) { 804 pw.println(type + " " + naiToString(nai)); 805 } 806 } 807 } 808 pw.decreaseIndent(); 809 pw.decreaseIndent(); 810 pw.println(); 811 } 812 } 813 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this); 814 815 /** 816 * Helper class which parses out priority arguments and dumps sections according to their 817 * priority. If priority arguments are omitted, function calls the legacy dump command. 818 */ 819 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { 820 @Override 821 public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { 822 doDump(fd, pw, new String[] {DIAG_ARG}, asProto); 823 doDump(fd, pw, new String[] {SHORT_ARG}, asProto); 824 } 825 826 @Override 827 public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { 828 doDump(fd, pw, args, asProto); 829 } 830 831 @Override 832 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { 833 doDump(fd, pw, args, asProto); 834 } 835 }; 836 ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager)837 public ConnectivityService(Context context, INetworkManagementService netManager, 838 INetworkStatsService statsService, INetworkPolicyManager policyManager) { 839 this(context, netManager, statsService, policyManager, 840 getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance()); 841 } 842 843 @VisibleForTesting ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd)844 protected ConnectivityService(Context context, INetworkManagementService netManager, 845 INetworkStatsService statsService, INetworkPolicyManager policyManager, 846 IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd) { 847 if (DBG) log("ConnectivityService starting up"); 848 849 mSystemProperties = getSystemProperties(); 850 851 mMetricsLog = logger; 852 mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); 853 NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder()); 854 mNetworkRequests.put(mDefaultRequest, defaultNRI); 855 mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI); 856 857 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( 858 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); 859 860 // The default WiFi request is a background request so that apps using WiFi are 861 // migrated to a better network (typically ethernet) when one comes up, instead 862 // of staying on WiFi forever. 863 mDefaultWifiRequest = createDefaultInternetRequestForTransport( 864 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); 865 866 mHandlerThread = new HandlerThread("ConnectivityServiceThread"); 867 mHandlerThread.start(); 868 mHandler = new InternalHandler(mHandlerThread.getLooper()); 869 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 870 871 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 872 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 873 874 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 875 876 mContext = checkNotNull(context, "missing Context"); 877 mNMS = checkNotNull(netManager, "missing INetworkManagementService"); 878 mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); 879 mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); 880 mPolicyManagerInternal = checkNotNull( 881 LocalServices.getService(NetworkPolicyManagerInternal.class), 882 "missing NetworkPolicyManagerInternal"); 883 mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver"); 884 mProxyTracker = makeProxyTracker(); 885 886 mNetd = netd; 887 mKeyStore = KeyStore.getInstance(); 888 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 889 890 // To ensure uid rules are synchronized with Network Policy, register for 891 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService 892 // reading existing policy from disk. 893 try { 894 mPolicyManager.registerListener(mPolicyListener); 895 } catch (RemoteException e) { 896 // ouch, no rules updates means some processes may never get network 897 loge("unable to register INetworkPolicyListener" + e); 898 } 899 900 final PowerManager powerManager = (PowerManager) context.getSystemService( 901 Context.POWER_SERVICE); 902 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 903 mNetTransitionWakeLockTimeout = mContext.getResources().getInteger( 904 com.android.internal.R.integer.config_networkTransitionTimeout); 905 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 906 907 mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1]; 908 909 // TODO: What is the "correct" way to do determine if this is a wifi only device? 910 boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false); 911 log("wifiOnly=" + wifiOnly); 912 String[] naStrings = context.getResources().getStringArray( 913 com.android.internal.R.array.networkAttributes); 914 for (String naString : naStrings) { 915 try { 916 NetworkConfig n = new NetworkConfig(naString); 917 if (VDBG) log("naString=" + naString + " config=" + n); 918 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) { 919 loge("Error in networkAttributes - ignoring attempt to define type " + 920 n.type); 921 continue; 922 } 923 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) { 924 log("networkAttributes - ignoring mobile as this dev is wifiOnly " + 925 n.type); 926 continue; 927 } 928 if (mNetConfigs[n.type] != null) { 929 loge("Error in networkAttributes - ignoring attempt to redefine type " + 930 n.type); 931 continue; 932 } 933 mLegacyTypeTracker.addSupportedType(n.type); 934 935 mNetConfigs[n.type] = n; 936 mNetworksDefined++; 937 } catch(Exception e) { 938 // ignore it - leave the entry null 939 } 940 } 941 942 // Forcibly add TYPE_VPN as a supported type, if it has not already been added via config. 943 if (mNetConfigs[TYPE_VPN] == null) { 944 // mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we 945 // don't need to add TYPE_VPN to mNetConfigs. 946 mLegacyTypeTracker.addSupportedType(TYPE_VPN); 947 mNetworksDefined++; // used only in the log() statement below. 948 } 949 950 // Do the same for Ethernet, since it's often not specified in the configs, although many 951 // devices can use it via USB host adapters. 952 if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) { 953 mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET); 954 mNetworksDefined++; 955 } 956 957 if (VDBG) log("mNetworksDefined=" + mNetworksDefined); 958 959 mProtectedNetworks = new ArrayList<Integer>(); 960 int[] protectedNetworks = context.getResources().getIntArray( 961 com.android.internal.R.array.config_protectedNetworks); 962 for (int p : protectedNetworks) { 963 if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) { 964 mProtectedNetworks.add(p); 965 } else { 966 if (DBG) loge("Ignoring protectedNetwork " + p); 967 } 968 } 969 970 mTethering = makeTethering(); 971 972 mPermissionMonitor = new PermissionMonitor(mContext, mNetd); 973 974 // Set up the listener for user state for creating user VPNs. 975 // Should run on mHandler to avoid any races. 976 IntentFilter intentFilter = new IntentFilter(); 977 intentFilter.addAction(Intent.ACTION_USER_STARTED); 978 intentFilter.addAction(Intent.ACTION_USER_STOPPED); 979 intentFilter.addAction(Intent.ACTION_USER_ADDED); 980 intentFilter.addAction(Intent.ACTION_USER_REMOVED); 981 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); 982 mContext.registerReceiverAsUser( 983 mIntentReceiver, 984 UserHandle.ALL, 985 intentFilter, 986 null /* broadcastPermission */, 987 mHandler); 988 mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM, 989 new IntentFilter(Intent.ACTION_USER_PRESENT), null, null); 990 991 // Listen to package add and removal events for all users. 992 intentFilter = new IntentFilter(); 993 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 994 intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 995 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 996 intentFilter.addDataScheme("package"); 997 mContext.registerReceiverAsUser( 998 mIntentReceiver, 999 UserHandle.ALL, 1000 intentFilter, 1001 null /* broadcastPermission */, 1002 mHandler); 1003 1004 try { 1005 mNMS.registerObserver(mTethering); 1006 mNMS.registerObserver(mDataActivityObserver); 1007 } catch (RemoteException e) { 1008 loge("Error registering observer :" + e); 1009 } 1010 1011 mSettingsObserver = new SettingsObserver(mContext, mHandler); 1012 registerSettingsCallbacks(); 1013 1014 final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext); 1015 dataConnectionStats.startMonitoring(); 1016 1017 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 1018 1019 mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler); 1020 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager, 1021 mContext.getSystemService(NotificationManager.class)); 1022 1023 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 1024 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 1025 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 1026 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 1027 Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 1028 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 1029 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 1030 1031 mMultinetworkPolicyTracker = createMultinetworkPolicyTracker( 1032 mContext, mHandler, () -> rematchForAvoidBadWifiUpdate()); 1033 mMultinetworkPolicyTracker.start(); 1034 1035 mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler); 1036 1037 mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties); 1038 registerPrivateDnsSettingsCallbacks(); 1039 } 1040 1041 @VisibleForTesting makeTethering()1042 protected Tethering makeTethering() { 1043 // TODO: Move other elements into @Overridden getters. 1044 final TetheringDependencies deps = new TetheringDependencies() { 1045 @Override 1046 public boolean isTetheringSupported() { 1047 return ConnectivityService.this.isTetheringSupported(); 1048 } 1049 @Override 1050 public NetworkRequest getDefaultNetworkRequest() { 1051 return mDefaultRequest; 1052 } 1053 }; 1054 return new Tethering(mContext, mNMS, mStatsService, mPolicyManager, 1055 IoThread.get().getLooper(), new MockableSystemProperties(), 1056 deps); 1057 } 1058 1059 @VisibleForTesting makeProxyTracker()1060 protected ProxyTracker makeProxyTracker() { 1061 return new ProxyTracker(mContext, mHandler, EVENT_PROXY_HAS_CHANGED); 1062 } 1063 createDefaultNetworkCapabilitiesForUid(int uid)1064 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { 1065 final NetworkCapabilities netCap = new NetworkCapabilities(); 1066 netCap.addCapability(NET_CAPABILITY_INTERNET); 1067 netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED); 1068 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 1069 netCap.setSingleUid(uid); 1070 return netCap; 1071 } 1072 createDefaultInternetRequestForTransport( int transportType, NetworkRequest.Type type)1073 private NetworkRequest createDefaultInternetRequestForTransport( 1074 int transportType, NetworkRequest.Type type) { 1075 final NetworkCapabilities netCap = new NetworkCapabilities(); 1076 netCap.addCapability(NET_CAPABILITY_INTERNET); 1077 netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED); 1078 if (transportType > -1) { 1079 netCap.addTransportType(transportType); 1080 } 1081 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 1082 } 1083 1084 // Used only for testing. 1085 // TODO: Delete this and either: 1086 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires 1087 // changing ContentResolver to make registerContentObserver non-final). 1088 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 1089 // by subclassing SettingsObserver. 1090 @VisibleForTesting updateAlwaysOnNetworks()1091 void updateAlwaysOnNetworks() { 1092 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1093 } 1094 1095 // See FakeSettingsProvider comment above. 1096 @VisibleForTesting updatePrivateDnsSettings()1097 void updatePrivateDnsSettings() { 1098 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1099 } 1100 handleAlwaysOnNetworkRequest( NetworkRequest networkRequest, String settingName, boolean defaultValue)1101 private void handleAlwaysOnNetworkRequest( 1102 NetworkRequest networkRequest, String settingName, boolean defaultValue) { 1103 final boolean enable = toBool(Settings.Global.getInt( 1104 mContext.getContentResolver(), settingName, encodeBool(defaultValue))); 1105 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); 1106 if (enable == isEnabled) { 1107 return; // Nothing to do. 1108 } 1109 1110 if (enable) { 1111 handleRegisterNetworkRequest(new NetworkRequestInfo( 1112 null, networkRequest, new Binder())); 1113 } else { 1114 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, 1115 /* callOnUnavailable */ false); 1116 } 1117 } 1118 handleConfigureAlwaysOnNetworks()1119 private void handleConfigureAlwaysOnNetworks() { 1120 handleAlwaysOnNetworkRequest( 1121 mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true); 1122 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED, 1123 false); 1124 } 1125 registerSettingsCallbacks()1126 private void registerSettingsCallbacks() { 1127 // Watch for global HTTP proxy changes. 1128 mSettingsObserver.observe( 1129 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 1130 EVENT_APPLY_GLOBAL_HTTP_PROXY); 1131 1132 // Watch for whether or not to keep mobile data always on. 1133 mSettingsObserver.observe( 1134 Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON), 1135 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1136 1137 // Watch for whether or not to keep wifi always on. 1138 mSettingsObserver.observe( 1139 Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED), 1140 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1141 } 1142 registerPrivateDnsSettingsCallbacks()1143 private void registerPrivateDnsSettingsCallbacks() { 1144 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { 1145 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1146 } 1147 } 1148 nextNetworkRequestId()1149 private synchronized int nextNetworkRequestId() { 1150 return mNextNetworkRequestId++; 1151 } 1152 1153 @VisibleForTesting reserveNetId()1154 protected int reserveNetId() { 1155 synchronized (mNetworkForNetId) { 1156 for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { 1157 int netId = mNextNetId; 1158 if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID; 1159 // Make sure NetID unused. http://b/16815182 1160 if (!mNetIdInUse.get(netId)) { 1161 mNetIdInUse.put(netId, true); 1162 return netId; 1163 } 1164 } 1165 } 1166 throw new IllegalStateException("No free netIds"); 1167 } 1168 getFilteredNetworkState(int networkType, int uid)1169 private NetworkState getFilteredNetworkState(int networkType, int uid) { 1170 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 1171 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1172 final NetworkState state; 1173 if (nai != null) { 1174 state = nai.getNetworkState(); 1175 state.networkInfo.setType(networkType); 1176 } else { 1177 final NetworkInfo info = new NetworkInfo(networkType, 0, 1178 getNetworkTypeName(networkType), ""); 1179 info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); 1180 info.setIsAvailable(true); 1181 final NetworkCapabilities capabilities = new NetworkCapabilities(); 1182 capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, 1183 !info.isRoaming()); 1184 state = new NetworkState(info, new LinkProperties(), capabilities, 1185 null, null, null); 1186 } 1187 filterNetworkStateForUid(state, uid, false); 1188 return state; 1189 } else { 1190 return NetworkState.EMPTY; 1191 } 1192 } 1193 1194 @VisibleForTesting getNetworkAgentInfoForNetwork(Network network)1195 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 1196 if (network == null) { 1197 return null; 1198 } 1199 return getNetworkAgentInfoForNetId(network.netId); 1200 } 1201 getNetworkAgentInfoForNetId(int netId)1202 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { 1203 synchronized (mNetworkForNetId) { 1204 return mNetworkForNetId.get(netId); 1205 } 1206 } 1207 getVpnUnderlyingNetworks(int uid)1208 private Network[] getVpnUnderlyingNetworks(int uid) { 1209 synchronized (mVpns) { 1210 if (!mLockdownEnabled) { 1211 int user = UserHandle.getUserId(uid); 1212 Vpn vpn = mVpns.get(user); 1213 if (vpn != null && vpn.appliesToUid(uid)) { 1214 return vpn.getUnderlyingNetworks(); 1215 } 1216 } 1217 } 1218 return null; 1219 } 1220 getUnfilteredActiveNetworkState(int uid)1221 private NetworkState getUnfilteredActiveNetworkState(int uid) { 1222 NetworkAgentInfo nai = getDefaultNetwork(); 1223 1224 final Network[] networks = getVpnUnderlyingNetworks(uid); 1225 if (networks != null) { 1226 // getUnderlyingNetworks() returns: 1227 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 1228 // empty array => the VPN explicitly said "no default network". 1229 // non-empty array => the VPN specified one or more default networks; we use the 1230 // first one. 1231 if (networks.length > 0) { 1232 nai = getNetworkAgentInfoForNetwork(networks[0]); 1233 } else { 1234 nai = null; 1235 } 1236 } 1237 1238 if (nai != null) { 1239 return nai.getNetworkState(); 1240 } else { 1241 return NetworkState.EMPTY; 1242 } 1243 } 1244 1245 /** 1246 * Check if UID should be blocked from using the network with the given LinkProperties. 1247 */ isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid, boolean ignoreBlocked)1248 private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid, 1249 boolean ignoreBlocked) { 1250 // Networks aren't blocked when ignoring blocked status 1251 if (ignoreBlocked) { 1252 return false; 1253 } 1254 synchronized (mVpns) { 1255 final Vpn vpn = mVpns.get(UserHandle.getUserId(uid)); 1256 if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) { 1257 return true; 1258 } 1259 } 1260 final String iface = (lp == null ? "" : lp.getInterfaceName()); 1261 return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface); 1262 } 1263 maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid)1264 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 1265 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 1266 return; 1267 } 1268 final boolean blocked; 1269 synchronized (mBlockedAppUids) { 1270 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 1271 blocked = true; 1272 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 1273 blocked = false; 1274 } else { 1275 return; 1276 } 1277 } 1278 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 1279 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid)); 1280 mNetworkInfoBlockingLogs.log(action + " " + uid); 1281 } 1282 maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, boolean blocked)1283 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, 1284 boolean blocked) { 1285 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { 1286 return; 1287 } 1288 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 1289 log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked, 1290 nri.mUid, nri.request.requestId, net.netId)); 1291 mNetworkInfoBlockingLogs.log(action + " " + nri.mUid); 1292 } 1293 1294 /** 1295 * Apply any relevant filters to {@link NetworkState} for the given UID. For 1296 * example, this may mark the network as {@link DetailedState#BLOCKED} based 1297 * on {@link #isNetworkWithLinkPropertiesBlocked}. 1298 */ filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked)1299 private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) { 1300 if (state == null || state.networkInfo == null || state.linkProperties == null) return; 1301 1302 if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) { 1303 state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null); 1304 } 1305 synchronized (mVpns) { 1306 if (mLockdownTracker != null) { 1307 mLockdownTracker.augmentNetworkInfo(state.networkInfo); 1308 } 1309 } 1310 } 1311 1312 /** 1313 * Return NetworkInfo for the active (i.e., connected) network interface. 1314 * It is assumed that at most one network is active at a time. If more 1315 * than one is active, it is indeterminate which will be returned. 1316 * @return the info for the active network, or {@code null} if none is 1317 * active 1318 */ 1319 @Override getActiveNetworkInfo()1320 public NetworkInfo getActiveNetworkInfo() { 1321 enforceAccessPermission(); 1322 final int uid = Binder.getCallingUid(); 1323 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1324 filterNetworkStateForUid(state, uid, false); 1325 maybeLogBlockedNetworkInfo(state.networkInfo, uid); 1326 return state.networkInfo; 1327 } 1328 1329 @Override getActiveNetwork()1330 public Network getActiveNetwork() { 1331 enforceAccessPermission(); 1332 return getActiveNetworkForUidInternal(Binder.getCallingUid(), false); 1333 } 1334 1335 @Override getActiveNetworkForUid(int uid, boolean ignoreBlocked)1336 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 1337 enforceConnectivityInternalPermission(); 1338 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 1339 } 1340 getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked)1341 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 1342 final int user = UserHandle.getUserId(uid); 1343 int vpnNetId = NETID_UNSET; 1344 synchronized (mVpns) { 1345 final Vpn vpn = mVpns.get(user); 1346 // TODO : now that capabilities contain the UID, the appliesToUid test should 1347 // be removed as the satisfying test below should be enough. 1348 if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId(); 1349 } 1350 NetworkAgentInfo nai; 1351 if (vpnNetId != NETID_UNSET) { 1352 nai = getNetworkAgentInfoForNetId(vpnNetId); 1353 if (nai != null) { 1354 final NetworkCapabilities requiredCaps = 1355 createDefaultNetworkCapabilitiesForUid(uid); 1356 if (requiredCaps.satisfiedByNetworkCapabilities(nai.networkCapabilities)) { 1357 return nai.network; 1358 } 1359 } 1360 } 1361 nai = getDefaultNetwork(); 1362 if (nai != null 1363 && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) { 1364 nai = null; 1365 } 1366 return nai != null ? nai.network : null; 1367 } 1368 1369 // Public because it's used by mLockdownTracker. getActiveNetworkInfoUnfiltered()1370 public NetworkInfo getActiveNetworkInfoUnfiltered() { 1371 enforceAccessPermission(); 1372 final int uid = Binder.getCallingUid(); 1373 NetworkState state = getUnfilteredActiveNetworkState(uid); 1374 return state.networkInfo; 1375 } 1376 1377 @Override getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked)1378 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 1379 enforceConnectivityInternalPermission(); 1380 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1381 filterNetworkStateForUid(state, uid, ignoreBlocked); 1382 return state.networkInfo; 1383 } 1384 1385 @Override getNetworkInfo(int networkType)1386 public NetworkInfo getNetworkInfo(int networkType) { 1387 enforceAccessPermission(); 1388 final int uid = Binder.getCallingUid(); 1389 if (getVpnUnderlyingNetworks(uid) != null) { 1390 // A VPN is active, so we may need to return one of its underlying networks. This 1391 // information is not available in LegacyTypeTracker, so we have to get it from 1392 // getUnfilteredActiveNetworkState. 1393 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1394 if (state.networkInfo != null && state.networkInfo.getType() == networkType) { 1395 filterNetworkStateForUid(state, uid, false); 1396 return state.networkInfo; 1397 } 1398 } 1399 final NetworkState state = getFilteredNetworkState(networkType, uid); 1400 return state.networkInfo; 1401 } 1402 1403 @Override getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked)1404 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 1405 enforceAccessPermission(); 1406 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1407 if (nai != null) { 1408 final NetworkState state = nai.getNetworkState(); 1409 filterNetworkStateForUid(state, uid, ignoreBlocked); 1410 return state.networkInfo; 1411 } else { 1412 return null; 1413 } 1414 } 1415 1416 @Override getAllNetworkInfo()1417 public NetworkInfo[] getAllNetworkInfo() { 1418 enforceAccessPermission(); 1419 final ArrayList<NetworkInfo> result = Lists.newArrayList(); 1420 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 1421 networkType++) { 1422 NetworkInfo info = getNetworkInfo(networkType); 1423 if (info != null) { 1424 result.add(info); 1425 } 1426 } 1427 return result.toArray(new NetworkInfo[result.size()]); 1428 } 1429 1430 @Override getNetworkForType(int networkType)1431 public Network getNetworkForType(int networkType) { 1432 enforceAccessPermission(); 1433 final int uid = Binder.getCallingUid(); 1434 NetworkState state = getFilteredNetworkState(networkType, uid); 1435 if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) { 1436 return state.network; 1437 } 1438 return null; 1439 } 1440 1441 @Override getAllNetworks()1442 public Network[] getAllNetworks() { 1443 enforceAccessPermission(); 1444 synchronized (mNetworkForNetId) { 1445 final Network[] result = new Network[mNetworkForNetId.size()]; 1446 for (int i = 0; i < mNetworkForNetId.size(); i++) { 1447 result[i] = mNetworkForNetId.valueAt(i).network; 1448 } 1449 return result; 1450 } 1451 } 1452 1453 @Override getDefaultNetworkCapabilitiesForUser(int userId)1454 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) { 1455 // The basic principle is: if an app's traffic could possibly go over a 1456 // network, without the app doing anything multinetwork-specific, 1457 // (hence, by "default"), then include that network's capabilities in 1458 // the array. 1459 // 1460 // In the normal case, app traffic only goes over the system's default 1461 // network connection, so that's the only network returned. 1462 // 1463 // With a VPN in force, some app traffic may go into the VPN, and thus 1464 // over whatever underlying networks the VPN specifies, while other app 1465 // traffic may go over the system default network (e.g.: a split-tunnel 1466 // VPN, or an app disallowed by the VPN), so the set of networks 1467 // returned includes the VPN's underlying networks and the system 1468 // default. 1469 enforceAccessPermission(); 1470 1471 HashMap<Network, NetworkCapabilities> result = new HashMap<>(); 1472 1473 NetworkAgentInfo nai = getDefaultNetwork(); 1474 NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 1475 if (nc != null) { 1476 result.put(nai.network, nc); 1477 } 1478 1479 synchronized (mVpns) { 1480 if (!mLockdownEnabled) { 1481 Vpn vpn = mVpns.get(userId); 1482 if (vpn != null) { 1483 Network[] networks = vpn.getUnderlyingNetworks(); 1484 if (networks != null) { 1485 for (Network network : networks) { 1486 nai = getNetworkAgentInfoForNetwork(network); 1487 nc = getNetworkCapabilitiesInternal(nai); 1488 if (nc != null) { 1489 result.put(network, nc); 1490 } 1491 } 1492 } 1493 } 1494 } 1495 } 1496 1497 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 1498 out = result.values().toArray(out); 1499 return out; 1500 } 1501 1502 @Override isNetworkSupported(int networkType)1503 public boolean isNetworkSupported(int networkType) { 1504 enforceAccessPermission(); 1505 return mLegacyTypeTracker.isTypeSupported(networkType); 1506 } 1507 1508 /** 1509 * Return LinkProperties for the active (i.e., connected) default 1510 * network interface. It is assumed that at most one default network 1511 * is active at a time. If more than one is active, it is indeterminate 1512 * which will be returned. 1513 * @return the ip properties for the active network, or {@code null} if 1514 * none is active 1515 */ 1516 @Override getActiveLinkProperties()1517 public LinkProperties getActiveLinkProperties() { 1518 enforceAccessPermission(); 1519 final int uid = Binder.getCallingUid(); 1520 NetworkState state = getUnfilteredActiveNetworkState(uid); 1521 return state.linkProperties; 1522 } 1523 1524 @Override getLinkPropertiesForType(int networkType)1525 public LinkProperties getLinkPropertiesForType(int networkType) { 1526 enforceAccessPermission(); 1527 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1528 if (nai != null) { 1529 synchronized (nai) { 1530 return new LinkProperties(nai.linkProperties); 1531 } 1532 } 1533 return null; 1534 } 1535 1536 // TODO - this should be ALL networks 1537 @Override getLinkProperties(Network network)1538 public LinkProperties getLinkProperties(Network network) { 1539 enforceAccessPermission(); 1540 return getLinkProperties(getNetworkAgentInfoForNetwork(network)); 1541 } 1542 getLinkProperties(NetworkAgentInfo nai)1543 private LinkProperties getLinkProperties(NetworkAgentInfo nai) { 1544 if (nai == null) { 1545 return null; 1546 } 1547 synchronized (nai) { 1548 return new LinkProperties(nai.linkProperties); 1549 } 1550 } 1551 getNetworkCapabilitiesInternal(NetworkAgentInfo nai)1552 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 1553 if (nai != null) { 1554 synchronized (nai) { 1555 if (nai.networkCapabilities != null) { 1556 return networkCapabilitiesRestrictedForCallerPermissions( 1557 nai.networkCapabilities, 1558 Binder.getCallingPid(), Binder.getCallingUid()); 1559 } 1560 } 1561 } 1562 return null; 1563 } 1564 1565 @Override getNetworkCapabilities(Network network)1566 public NetworkCapabilities getNetworkCapabilities(Network network) { 1567 enforceAccessPermission(); 1568 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 1569 } 1570 networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid)1571 private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( 1572 NetworkCapabilities nc, int callerPid, int callerUid) { 1573 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 1574 if (!checkSettingsPermission(callerPid, callerUid)) { 1575 newNc.setUids(null); 1576 newNc.setSSID(null); 1577 } 1578 if (newNc.getNetworkSpecifier() != null) { 1579 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); 1580 } 1581 return newNc; 1582 } 1583 restrictRequestUidsForCaller(NetworkCapabilities nc)1584 private void restrictRequestUidsForCaller(NetworkCapabilities nc) { 1585 if (!checkSettingsPermission()) { 1586 nc.setSingleUid(Binder.getCallingUid()); 1587 } 1588 } 1589 restrictBackgroundRequestForCaller(NetworkCapabilities nc)1590 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) { 1591 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(Binder.getCallingUid())) { 1592 nc.addCapability(NET_CAPABILITY_FOREGROUND); 1593 } 1594 } 1595 1596 @Override getAllNetworkState()1597 public NetworkState[] getAllNetworkState() { 1598 // Require internal since we're handing out IMSI details 1599 enforceConnectivityInternalPermission(); 1600 1601 final ArrayList<NetworkState> result = Lists.newArrayList(); 1602 for (Network network : getAllNetworks()) { 1603 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1604 if (nai != null) { 1605 // TODO (b/73321673) : NetworkState contains a copy of the 1606 // NetworkCapabilities, which may contain UIDs of apps to which the 1607 // network applies. Should the UIDs be cleared so as not to leak or 1608 // interfere ? 1609 result.add(nai.getNetworkState()); 1610 } 1611 } 1612 return result.toArray(new NetworkState[result.size()]); 1613 } 1614 1615 @Override 1616 @Deprecated getActiveNetworkQuotaInfo()1617 public NetworkQuotaInfo getActiveNetworkQuotaInfo() { 1618 Log.w(TAG, "Shame on UID " + Binder.getCallingUid() 1619 + " for calling the hidden API getNetworkQuotaInfo(). Shame!"); 1620 return new NetworkQuotaInfo(); 1621 } 1622 1623 @Override isActiveNetworkMetered()1624 public boolean isActiveNetworkMetered() { 1625 enforceAccessPermission(); 1626 1627 final NetworkCapabilities caps = getNetworkCapabilities(getActiveNetwork()); 1628 if (caps != null) { 1629 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1630 } else { 1631 // Always return the most conservative value 1632 return true; 1633 } 1634 } 1635 1636 private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() { 1637 @Override 1638 public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) { 1639 int deviceType = Integer.parseInt(label); 1640 sendDataActivityBroadcast(deviceType, active, tsNanos); 1641 } 1642 }; 1643 1644 /** 1645 * Ensures that the system cannot call a particular method. 1646 */ disallowedBecauseSystemCaller()1647 private boolean disallowedBecauseSystemCaller() { 1648 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling 1649 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost 1650 // for devices launched with Q and above. However, existing devices upgrading to Q and 1651 // above must continued to be supported for few more releases. 1652 if (isSystem(Binder.getCallingUid()) && SystemProperties.getInt( 1653 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) { 1654 log("This method exists only for app backwards compatibility" 1655 + " and must not be called by system services."); 1656 return true; 1657 } 1658 return false; 1659 } 1660 1661 /** 1662 * Ensure that a network route exists to deliver traffic to the specified 1663 * host via the specified network interface. 1664 * @param networkType the type of the network over which traffic to the 1665 * specified host is to be routed 1666 * @param hostAddress the IP address of the host to which the route is 1667 * desired 1668 * @return {@code true} on success, {@code false} on failure 1669 */ 1670 @Override requestRouteToHostAddress(int networkType, byte[] hostAddress)1671 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { 1672 if (disallowedBecauseSystemCaller()) { 1673 return false; 1674 } 1675 enforceChangePermission(); 1676 if (mProtectedNetworks.contains(networkType)) { 1677 enforceConnectivityInternalPermission(); 1678 } 1679 1680 InetAddress addr; 1681 try { 1682 addr = InetAddress.getByAddress(hostAddress); 1683 } catch (UnknownHostException e) { 1684 if (DBG) log("requestRouteToHostAddress got " + e.toString()); 1685 return false; 1686 } 1687 1688 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 1689 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 1690 return false; 1691 } 1692 1693 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1694 if (nai == null) { 1695 if (mLegacyTypeTracker.isTypeSupported(networkType) == false) { 1696 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 1697 } else { 1698 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 1699 } 1700 return false; 1701 } 1702 1703 DetailedState netState; 1704 synchronized (nai) { 1705 netState = nai.networkInfo.getDetailedState(); 1706 } 1707 1708 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 1709 if (VDBG) { 1710 log("requestRouteToHostAddress on down network " 1711 + "(" + networkType + ") - dropped" 1712 + " netState=" + netState); 1713 } 1714 return false; 1715 } 1716 1717 final int uid = Binder.getCallingUid(); 1718 final long token = Binder.clearCallingIdentity(); 1719 try { 1720 LinkProperties lp; 1721 int netId; 1722 synchronized (nai) { 1723 lp = nai.linkProperties; 1724 netId = nai.network.netId; 1725 } 1726 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 1727 if (DBG) log("requestRouteToHostAddress ok=" + ok); 1728 return ok; 1729 } finally { 1730 Binder.restoreCallingIdentity(token); 1731 } 1732 } 1733 addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid)1734 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 1735 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 1736 if (bestRoute == null) { 1737 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 1738 } else { 1739 String iface = bestRoute.getInterface(); 1740 if (bestRoute.getGateway().equals(addr)) { 1741 // if there is no better route, add the implied hostroute for our gateway 1742 bestRoute = RouteInfo.makeHostRoute(addr, iface); 1743 } else { 1744 // if we will connect to this through another route, add a direct route 1745 // to it's gateway 1746 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 1747 } 1748 } 1749 if (DBG) log("Adding legacy route " + bestRoute + 1750 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 1751 try { 1752 mNMS.addLegacyRouteForNetId(netId, bestRoute, uid); 1753 } catch (Exception e) { 1754 // never crash - catch them all 1755 if (DBG) loge("Exception trying to add a route: " + e); 1756 return false; 1757 } 1758 return true; 1759 } 1760 1761 @VisibleForTesting 1762 protected final INetdEventCallback mNetdEventCallback = new BaseNetdEventCallback() { 1763 @Override 1764 public void onPrivateDnsValidationEvent(int netId, String ipAddress, 1765 String hostname, boolean validated) { 1766 try { 1767 mHandler.sendMessage(mHandler.obtainMessage( 1768 EVENT_PRIVATE_DNS_VALIDATION_UPDATE, 1769 new PrivateDnsValidationUpdate(netId, 1770 InetAddress.parseNumericAddress(ipAddress), 1771 hostname, validated))); 1772 } catch (IllegalArgumentException e) { 1773 loge("Error parsing ip address in validation event"); 1774 } 1775 } 1776 1777 @Override 1778 public void onDnsEvent(int netId, int eventType, int returnCode, String hostname, 1779 String[] ipAddresses, int ipAddressesCount, long timestamp, int uid) { 1780 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 1781 // Netd event only allow registrants from system. Each NetworkMonitor thread is under 1782 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd 1783 // event callback for certain nai. e.g. cellular. Register here to pass to 1784 // NetworkMonitor instead. 1785 // TODO: Move the Dns Event to NetworkMonitor. Use Binder.clearCallingIdentity() in 1786 // registerNetworkAgent to have NetworkMonitor created with system process as design 1787 // expectation. Also, NetdEventListenerService only allow one callback from each 1788 // caller type. Need to re-factor NetdEventListenerService to allow multiple 1789 // NetworkMonitor registrants. 1790 if (nai != null && nai.satisfies(mDefaultRequest)) { 1791 nai.networkMonitor().notifyDnsResponse(returnCode); 1792 } 1793 } 1794 1795 @Override 1796 public void onNat64PrefixEvent(int netId, boolean added, 1797 String prefixString, int prefixLength) { 1798 mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength)); 1799 } 1800 }; 1801 1802 @VisibleForTesting registerNetdEventCallback()1803 protected void registerNetdEventCallback() { 1804 final IIpConnectivityMetrics ipConnectivityMetrics = 1805 IIpConnectivityMetrics.Stub.asInterface( 1806 ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); 1807 if (ipConnectivityMetrics == null) { 1808 Slog.wtf(TAG, "Missing IIpConnectivityMetrics"); 1809 return; 1810 } 1811 1812 try { 1813 ipConnectivityMetrics.addNetdEventCallback( 1814 INetdEventCallback.CALLBACK_CALLER_CONNECTIVITY_SERVICE, 1815 mNetdEventCallback); 1816 } catch (Exception e) { 1817 loge("Error registering netd callback: " + e); 1818 } 1819 } 1820 1821 private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() { 1822 @Override 1823 public void onUidRulesChanged(int uid, int uidRules) { 1824 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules)); 1825 } 1826 @Override 1827 public void onRestrictBackgroundChanged(boolean restrictBackground) { 1828 // caller is NPMS, since we only register with them 1829 if (LOGD_BLOCKED_NETWORKINFO) { 1830 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")"); 1831 } 1832 mHandler.sendMessage(mHandler.obtainMessage( 1833 EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0)); 1834 1835 // TODO: relocate this specific callback in Tethering. 1836 if (restrictBackground) { 1837 log("onRestrictBackgroundChanged(true): disabling tethering"); 1838 mTethering.untetherAll(); 1839 } 1840 } 1841 }; 1842 handleUidRulesChanged(int uid, int newRules)1843 void handleUidRulesChanged(int uid, int newRules) { 1844 // skip update when we've already applied rules 1845 final int oldRules = mUidRules.get(uid, RULE_NONE); 1846 if (oldRules == newRules) return; 1847 1848 maybeNotifyNetworkBlockedForNewUidRules(uid, newRules); 1849 1850 if (newRules == RULE_NONE) { 1851 mUidRules.delete(uid); 1852 } else { 1853 mUidRules.put(uid, newRules); 1854 } 1855 } 1856 handleRestrictBackgroundChanged(boolean restrictBackground)1857 void handleRestrictBackgroundChanged(boolean restrictBackground) { 1858 if (mRestrictBackground == restrictBackground) return; 1859 1860 for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 1861 final boolean curMetered = nai.networkCapabilities.isMetered(); 1862 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground, 1863 restrictBackground); 1864 } 1865 1866 mRestrictBackground = restrictBackground; 1867 } 1868 isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered, boolean isBackgroundRestricted)1869 private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered, 1870 boolean isBackgroundRestricted) { 1871 synchronized (mVpns) { 1872 final Vpn vpn = mVpns.get(UserHandle.getUserId(uid)); 1873 // Because the return value of this function depends on the list of UIDs the 1874 // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that 1875 // list all state depending on the return value of this function has to be recomputed. 1876 // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and 1877 // send the necessary onBlockedStatusChanged callbacks. 1878 if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) { 1879 return true; 1880 } 1881 } 1882 1883 return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules, 1884 isNetworkMetered, isBackgroundRestricted); 1885 } 1886 1887 /** 1888 * Require that the caller is either in the same user or has appropriate permission to interact 1889 * across users. 1890 * 1891 * @param userId Target user for whatever operation the current IPC is supposed to perform. 1892 */ enforceCrossUserPermission(int userId)1893 private void enforceCrossUserPermission(int userId) { 1894 if (userId == UserHandle.getCallingUserId()) { 1895 // Not a cross-user call. 1896 return; 1897 } 1898 mContext.enforceCallingOrSelfPermission( 1899 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1900 "ConnectivityService"); 1901 } 1902 checkAnyPermissionOf(String... permissions)1903 private boolean checkAnyPermissionOf(String... permissions) { 1904 for (String permission : permissions) { 1905 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { 1906 return true; 1907 } 1908 } 1909 return false; 1910 } 1911 checkAnyPermissionOf(int pid, int uid, String... permissions)1912 private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) { 1913 for (String permission : permissions) { 1914 if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) { 1915 return true; 1916 } 1917 } 1918 return false; 1919 } 1920 enforceAnyPermissionOf(String... permissions)1921 private void enforceAnyPermissionOf(String... permissions) { 1922 if (!checkAnyPermissionOf(permissions)) { 1923 throw new SecurityException("Requires one of the following permissions: " 1924 + String.join(", ", permissions) + "."); 1925 } 1926 } 1927 enforceInternetPermission()1928 private void enforceInternetPermission() { 1929 mContext.enforceCallingOrSelfPermission( 1930 android.Manifest.permission.INTERNET, 1931 "ConnectivityService"); 1932 } 1933 enforceAccessPermission()1934 private void enforceAccessPermission() { 1935 mContext.enforceCallingOrSelfPermission( 1936 android.Manifest.permission.ACCESS_NETWORK_STATE, 1937 "ConnectivityService"); 1938 } 1939 enforceChangePermission()1940 private void enforceChangePermission() { 1941 ConnectivityManager.enforceChangePermission(mContext); 1942 } 1943 enforceSettingsPermission()1944 private void enforceSettingsPermission() { 1945 enforceAnyPermissionOf( 1946 android.Manifest.permission.NETWORK_SETTINGS, 1947 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1948 } 1949 checkSettingsPermission()1950 private boolean checkSettingsPermission() { 1951 return checkAnyPermissionOf( 1952 android.Manifest.permission.NETWORK_SETTINGS, 1953 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1954 } 1955 checkSettingsPermission(int pid, int uid)1956 private boolean checkSettingsPermission(int pid, int uid) { 1957 return PERMISSION_GRANTED == mContext.checkPermission( 1958 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 1959 || PERMISSION_GRANTED == mContext.checkPermission( 1960 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid); 1961 } 1962 enforceTetherAccessPermission()1963 private void enforceTetherAccessPermission() { 1964 mContext.enforceCallingOrSelfPermission( 1965 android.Manifest.permission.ACCESS_NETWORK_STATE, 1966 "ConnectivityService"); 1967 } 1968 enforceConnectivityInternalPermission()1969 private void enforceConnectivityInternalPermission() { 1970 enforceAnyPermissionOf( 1971 android.Manifest.permission.CONNECTIVITY_INTERNAL, 1972 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1973 } 1974 enforceControlAlwaysOnVpnPermission()1975 private void enforceControlAlwaysOnVpnPermission() { 1976 mContext.enforceCallingOrSelfPermission( 1977 android.Manifest.permission.CONTROL_ALWAYS_ON_VPN, 1978 "ConnectivityService"); 1979 } 1980 enforceNetworkStackSettingsOrSetup()1981 private void enforceNetworkStackSettingsOrSetup() { 1982 enforceAnyPermissionOf( 1983 android.Manifest.permission.NETWORK_SETTINGS, 1984 android.Manifest.permission.NETWORK_SETUP_WIZARD, 1985 android.Manifest.permission.NETWORK_STACK, 1986 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1987 } 1988 checkNetworkStackPermission()1989 private boolean checkNetworkStackPermission() { 1990 return checkAnyPermissionOf( 1991 android.Manifest.permission.NETWORK_STACK, 1992 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1993 } 1994 checkNetworkSignalStrengthWakeupPermission(int pid, int uid)1995 private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { 1996 return checkAnyPermissionOf(pid, uid, 1997 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, 1998 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 1999 } 2000 enforceConnectivityRestrictedNetworksPermission()2001 private void enforceConnectivityRestrictedNetworksPermission() { 2002 try { 2003 mContext.enforceCallingOrSelfPermission( 2004 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS, 2005 "ConnectivityService"); 2006 return; 2007 } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ } 2008 enforceConnectivityInternalPermission(); 2009 } 2010 enforceKeepalivePermission()2011 private void enforceKeepalivePermission() { 2012 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 2013 } 2014 2015 // Public because it's used by mLockdownTracker. sendConnectedBroadcast(NetworkInfo info)2016 public void sendConnectedBroadcast(NetworkInfo info) { 2017 enforceConnectivityInternalPermission(); 2018 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 2019 } 2020 sendInetConditionBroadcast(NetworkInfo info)2021 private void sendInetConditionBroadcast(NetworkInfo info) { 2022 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 2023 } 2024 makeGeneralIntent(NetworkInfo info, String bcastType)2025 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 2026 synchronized (mVpns) { 2027 if (mLockdownTracker != null) { 2028 info = new NetworkInfo(info); 2029 mLockdownTracker.augmentNetworkInfo(info); 2030 } 2031 } 2032 2033 Intent intent = new Intent(bcastType); 2034 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 2035 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 2036 if (info.isFailover()) { 2037 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 2038 info.setFailover(false); 2039 } 2040 if (info.getReason() != null) { 2041 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 2042 } 2043 if (info.getExtraInfo() != null) { 2044 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 2045 info.getExtraInfo()); 2046 } 2047 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 2048 return intent; 2049 } 2050 sendGeneralBroadcast(NetworkInfo info, String bcastType)2051 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 2052 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 2053 } 2054 sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos)2055 private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 2056 Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 2057 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 2058 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 2059 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 2060 final long ident = Binder.clearCallingIdentity(); 2061 try { 2062 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 2063 RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null); 2064 } finally { 2065 Binder.restoreCallingIdentity(ident); 2066 } 2067 } 2068 sendStickyBroadcast(Intent intent)2069 private void sendStickyBroadcast(Intent intent) { 2070 synchronized (this) { 2071 if (!mSystemReady 2072 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 2073 mInitialBroadcast = new Intent(intent); 2074 } 2075 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2076 if (VDBG) { 2077 log("sendStickyBroadcast: action=" + intent.getAction()); 2078 } 2079 2080 Bundle options = null; 2081 final long ident = Binder.clearCallingIdentity(); 2082 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 2083 final NetworkInfo ni = intent.getParcelableExtra( 2084 ConnectivityManager.EXTRA_NETWORK_INFO); 2085 if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) { 2086 intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL); 2087 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2088 } else { 2089 BroadcastOptions opts = BroadcastOptions.makeBasic(); 2090 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 2091 options = opts.toBundle(); 2092 } 2093 final IBatteryStats bs = BatteryStatsService.getService(); 2094 try { 2095 bs.noteConnectivityChanged(intent.getIntExtra( 2096 ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE), 2097 ni.getState().toString()); 2098 } catch (RemoteException e) { 2099 } 2100 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 2101 } 2102 try { 2103 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL, options); 2104 } finally { 2105 Binder.restoreCallingIdentity(ident); 2106 } 2107 } 2108 } 2109 systemReady()2110 void systemReady() { 2111 mProxyTracker.loadGlobalProxy(); 2112 registerNetdEventCallback(); 2113 mTethering.systemReady(); 2114 2115 synchronized (this) { 2116 mSystemReady = true; 2117 if (mInitialBroadcast != null) { 2118 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 2119 mInitialBroadcast = null; 2120 } 2121 } 2122 2123 // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait 2124 // for user to unlock device too. 2125 updateLockdownVpn(); 2126 2127 // Create network requests for always-on networks. 2128 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); 2129 2130 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY)); 2131 2132 mPermissionMonitor.startMonitoring(); 2133 } 2134 2135 /** 2136 * Setup data activity tracking for the given network. 2137 * 2138 * Every {@code setupDataActivityTracking} should be paired with a 2139 * {@link #removeDataActivityTracking} for cleanup. 2140 */ setupDataActivityTracking(NetworkAgentInfo networkAgent)2141 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) { 2142 final String iface = networkAgent.linkProperties.getInterfaceName(); 2143 2144 final int timeout; 2145 int type = ConnectivityManager.TYPE_NONE; 2146 2147 if (networkAgent.networkCapabilities.hasTransport( 2148 NetworkCapabilities.TRANSPORT_CELLULAR)) { 2149 timeout = Settings.Global.getInt(mContext.getContentResolver(), 2150 Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE, 2151 10); 2152 type = ConnectivityManager.TYPE_MOBILE; 2153 } else if (networkAgent.networkCapabilities.hasTransport( 2154 NetworkCapabilities.TRANSPORT_WIFI)) { 2155 timeout = Settings.Global.getInt(mContext.getContentResolver(), 2156 Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI, 2157 15); 2158 type = ConnectivityManager.TYPE_WIFI; 2159 } else { 2160 // do not track any other networks 2161 timeout = 0; 2162 } 2163 2164 if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) { 2165 try { 2166 mNMS.addIdleTimer(iface, timeout, type); 2167 } catch (Exception e) { 2168 // You shall not crash! 2169 loge("Exception in setupDataActivityTracking " + e); 2170 } 2171 } 2172 } 2173 2174 /** 2175 * Remove data activity tracking when network disconnects. 2176 */ removeDataActivityTracking(NetworkAgentInfo networkAgent)2177 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 2178 final String iface = networkAgent.linkProperties.getInterfaceName(); 2179 final NetworkCapabilities caps = networkAgent.networkCapabilities; 2180 2181 if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || 2182 caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) { 2183 try { 2184 // the call fails silently if no idle timer setup for this interface 2185 mNMS.removeIdleTimer(iface); 2186 } catch (Exception e) { 2187 loge("Exception in removeDataActivityTracking " + e); 2188 } 2189 } 2190 } 2191 2192 /** 2193 * Update data activity tracking when network state is updated. 2194 */ updateDataActivityTracking(NetworkAgentInfo newNetwork, NetworkAgentInfo oldNetwork)2195 private void updateDataActivityTracking(NetworkAgentInfo newNetwork, 2196 NetworkAgentInfo oldNetwork) { 2197 if (newNetwork != null) { 2198 setupDataActivityTracking(newNetwork); 2199 } 2200 if (oldNetwork != null) { 2201 removeDataActivityTracking(oldNetwork); 2202 } 2203 } 2204 /** 2205 * Reads the network specific MTU size from resources. 2206 * and set it on it's iface. 2207 */ updateMtu(LinkProperties newLp, LinkProperties oldLp)2208 private void updateMtu(LinkProperties newLp, LinkProperties oldLp) { 2209 final String iface = newLp.getInterfaceName(); 2210 final int mtu = newLp.getMtu(); 2211 if (oldLp == null && mtu == 0) { 2212 // Silently ignore unset MTU value. 2213 return; 2214 } 2215 if (oldLp != null && newLp.isIdenticalMtu(oldLp)) { 2216 if (VDBG) log("identical MTU - not setting"); 2217 return; 2218 } 2219 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) { 2220 if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface); 2221 return; 2222 } 2223 2224 // Cannot set MTU without interface name 2225 if (TextUtils.isEmpty(iface)) { 2226 loge("Setting MTU size with null iface."); 2227 return; 2228 } 2229 2230 try { 2231 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); 2232 mNMS.setMtu(iface, mtu); 2233 } catch (Exception e) { 2234 Slog.e(TAG, "exception in setMtu()" + e); 2235 } 2236 } 2237 2238 @VisibleForTesting 2239 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 2240 private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; 2241 2242 // Overridden for testing purposes to avoid writing to SystemProperties. 2243 @VisibleForTesting getSystemProperties()2244 protected MockableSystemProperties getSystemProperties() { 2245 return new MockableSystemProperties(); 2246 } 2247 updateTcpBufferSizes(String tcpBufferSizes)2248 private void updateTcpBufferSizes(String tcpBufferSizes) { 2249 String[] values = null; 2250 if (tcpBufferSizes != null) { 2251 values = tcpBufferSizes.split(","); 2252 } 2253 2254 if (values == null || values.length != 6) { 2255 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 2256 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 2257 values = tcpBufferSizes.split(","); 2258 } 2259 2260 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 2261 2262 try { 2263 if (VDBG || DDBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes); 2264 2265 String rmemValues = String.join(" ", values[0], values[1], values[2]); 2266 String wmemValues = String.join(" ", values[3], values[4], values[5]); 2267 mNetd.setTcpRWmemorySize(rmemValues, wmemValues); 2268 mCurrentTcpBufferSizes = tcpBufferSizes; 2269 } catch (RemoteException | ServiceSpecificException e) { 2270 loge("Can't set TCP buffer sizes:" + e); 2271 } 2272 2273 Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(), 2274 Settings.Global.TCP_DEFAULT_INIT_RWND, 2275 mSystemProperties.getInt("net.tcp.default_init_rwnd", 0)); 2276 final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd"; 2277 if (rwndValue != 0) { 2278 mSystemProperties.set(sysctlKey, rwndValue.toString()); 2279 } 2280 } 2281 2282 @Override getRestoreDefaultNetworkDelay(int networkType)2283 public int getRestoreDefaultNetworkDelay(int networkType) { 2284 String restoreDefaultNetworkDelayStr = mSystemProperties.get( 2285 NETWORK_RESTORE_DELAY_PROP_NAME); 2286 if(restoreDefaultNetworkDelayStr != null && 2287 restoreDefaultNetworkDelayStr.length() != 0) { 2288 try { 2289 return Integer.parseInt(restoreDefaultNetworkDelayStr); 2290 } catch (NumberFormatException e) { 2291 } 2292 } 2293 // if the system property isn't set, use the value for the apn type 2294 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 2295 2296 if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) && 2297 (mNetConfigs[networkType] != null)) { 2298 ret = mNetConfigs[networkType].restoreTime; 2299 } 2300 return ret; 2301 } 2302 dumpNetworkDiagnostics(IndentingPrintWriter pw)2303 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 2304 final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>(); 2305 final long DIAG_TIME_MS = 5000; 2306 for (NetworkAgentInfo nai : networksSortedById()) { 2307 // Start gathering diagnostic information. 2308 netDiags.add(new NetworkDiagnostics( 2309 nai.network, 2310 new LinkProperties(nai.linkProperties), // Must be a copy. 2311 DIAG_TIME_MS)); 2312 } 2313 2314 for (NetworkDiagnostics netDiag : netDiags) { 2315 pw.println(); 2316 netDiag.waitForMeasurements(); 2317 netDiag.dump(pw); 2318 } 2319 } 2320 2321 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)2322 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2323 PriorityDump.dump(mPriorityDumper, fd, writer, args); 2324 } 2325 doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto)2326 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) { 2327 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 2328 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2329 if (asProto) return; 2330 2331 if (ArrayUtils.contains(args, DIAG_ARG)) { 2332 dumpNetworkDiagnostics(pw); 2333 return; 2334 } else if (ArrayUtils.contains(args, TETHERING_ARG)) { 2335 mTethering.dump(fd, pw, args); 2336 return; 2337 } else if (ArrayUtils.contains(args, NETWORK_ARG)) { 2338 dumpNetworks(pw); 2339 return; 2340 } else if (ArrayUtils.contains(args, REQUEST_ARG)) { 2341 dumpNetworkRequests(pw); 2342 return; 2343 } 2344 2345 pw.print("NetworkFactories for:"); 2346 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 2347 pw.print(" " + nfi.name); 2348 } 2349 pw.println(); 2350 pw.println(); 2351 2352 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 2353 pw.print("Active default network: "); 2354 if (defaultNai == null) { 2355 pw.println("none"); 2356 } else { 2357 pw.println(defaultNai.network.netId); 2358 } 2359 pw.println(); 2360 2361 pw.println("Current Networks:"); 2362 pw.increaseIndent(); 2363 dumpNetworks(pw); 2364 pw.decreaseIndent(); 2365 pw.println(); 2366 2367 pw.print("Restrict background: "); 2368 pw.println(mRestrictBackground); 2369 pw.println(); 2370 2371 pw.println("Status for known UIDs:"); 2372 pw.increaseIndent(); 2373 final int size = mUidRules.size(); 2374 for (int i = 0; i < size; i++) { 2375 // Don't crash if the array is modified while dumping in bugreports. 2376 try { 2377 final int uid = mUidRules.keyAt(i); 2378 final int uidRules = mUidRules.get(uid, RULE_NONE); 2379 pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules)); 2380 } catch (ArrayIndexOutOfBoundsException e) { 2381 pw.println(" ArrayIndexOutOfBoundsException"); 2382 } catch (ConcurrentModificationException e) { 2383 pw.println(" ConcurrentModificationException"); 2384 } 2385 } 2386 pw.println(); 2387 pw.decreaseIndent(); 2388 2389 pw.println("Network Requests:"); 2390 pw.increaseIndent(); 2391 dumpNetworkRequests(pw); 2392 pw.decreaseIndent(); 2393 pw.println(); 2394 2395 mLegacyTypeTracker.dump(pw); 2396 2397 pw.println(); 2398 mTethering.dump(fd, pw, args); 2399 2400 pw.println(); 2401 mKeepaliveTracker.dump(pw); 2402 2403 pw.println(); 2404 dumpAvoidBadWifiSettings(pw); 2405 2406 pw.println(); 2407 mMultipathPolicyTracker.dump(pw); 2408 2409 if (ArrayUtils.contains(args, SHORT_ARG) == false) { 2410 pw.println(); 2411 pw.println("mNetworkRequestInfoLogs (most recent first):"); 2412 pw.increaseIndent(); 2413 mNetworkRequestInfoLogs.reverseDump(fd, pw, args); 2414 pw.decreaseIndent(); 2415 2416 pw.println(); 2417 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 2418 pw.increaseIndent(); 2419 mNetworkInfoBlockingLogs.reverseDump(fd, pw, args); 2420 pw.decreaseIndent(); 2421 2422 pw.println(); 2423 pw.println("NetTransition WakeLock activity (most recent first):"); 2424 pw.increaseIndent(); 2425 pw.println("total acquisitions: " + mTotalWakelockAcquisitions); 2426 pw.println("total releases: " + mTotalWakelockReleases); 2427 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s"); 2428 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s"); 2429 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) { 2430 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 2431 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); 2432 } 2433 mWakelockLogs.reverseDump(fd, pw, args); 2434 2435 pw.println(); 2436 pw.println("bandwidth update requests (by uid):"); 2437 pw.increaseIndent(); 2438 synchronized (mBandwidthRequests) { 2439 for (int i = 0; i < mBandwidthRequests.size(); i++) { 2440 pw.println("[" + mBandwidthRequests.keyAt(i) 2441 + "]: " + mBandwidthRequests.valueAt(i)); 2442 } 2443 } 2444 pw.decreaseIndent(); 2445 2446 pw.decreaseIndent(); 2447 } 2448 2449 pw.println(); 2450 pw.println("NetworkStackClient logs:"); 2451 pw.increaseIndent(); 2452 NetworkStackClient.getInstance().dump(pw); 2453 pw.decreaseIndent(); 2454 2455 pw.println(); 2456 pw.println("Permission Monitor:"); 2457 pw.increaseIndent(); 2458 mPermissionMonitor.dump(pw); 2459 pw.decreaseIndent(); 2460 } 2461 dumpNetworks(IndentingPrintWriter pw)2462 private void dumpNetworks(IndentingPrintWriter pw) { 2463 for (NetworkAgentInfo nai : networksSortedById()) { 2464 pw.println(nai.toString()); 2465 pw.increaseIndent(); 2466 pw.println(String.format( 2467 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d", 2468 nai.numForegroundNetworkRequests(), 2469 nai.numNetworkRequests() - nai.numRequestNetworkRequests(), 2470 nai.numBackgroundNetworkRequests(), 2471 nai.numNetworkRequests())); 2472 pw.increaseIndent(); 2473 for (int i = 0; i < nai.numNetworkRequests(); i++) { 2474 pw.println(nai.requestAt(i).toString()); 2475 } 2476 pw.decreaseIndent(); 2477 pw.println("Lingered:"); 2478 pw.increaseIndent(); 2479 nai.dumpLingerTimers(pw); 2480 pw.decreaseIndent(); 2481 pw.decreaseIndent(); 2482 } 2483 } 2484 dumpNetworkRequests(IndentingPrintWriter pw)2485 private void dumpNetworkRequests(IndentingPrintWriter pw) { 2486 for (NetworkRequestInfo nri : requestsSortedById()) { 2487 pw.println(nri.toString()); 2488 } 2489 } 2490 2491 /** 2492 * Return an array of all current NetworkAgentInfos sorted by network id. 2493 */ networksSortedById()2494 private NetworkAgentInfo[] networksSortedById() { 2495 NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; 2496 networks = mNetworkAgentInfos.values().toArray(networks); 2497 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.netId)); 2498 return networks; 2499 } 2500 2501 /** 2502 * Return an array of all current NetworkRequest sorted by request id. 2503 */ requestsSortedById()2504 private NetworkRequestInfo[] requestsSortedById() { 2505 NetworkRequestInfo[] requests = new NetworkRequestInfo[0]; 2506 requests = mNetworkRequests.values().toArray(requests); 2507 Arrays.sort(requests, Comparator.comparingInt(nri -> nri.request.requestId)); 2508 return requests; 2509 } 2510 isLiveNetworkAgent(NetworkAgentInfo nai, int what)2511 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 2512 if (nai.network == null) return false; 2513 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 2514 if (officialNai != null && officialNai.equals(nai)) return true; 2515 if (officialNai != null || VDBG) { 2516 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 2517 " - " + nai); 2518 } 2519 return false; 2520 } 2521 2522 // must be stateless - things change under us. 2523 private class NetworkStateTrackerHandler extends Handler { NetworkStateTrackerHandler(Looper looper)2524 public NetworkStateTrackerHandler(Looper looper) { 2525 super(looper); 2526 } 2527 maybeHandleAsyncChannelMessage(Message msg)2528 private boolean maybeHandleAsyncChannelMessage(Message msg) { 2529 switch (msg.what) { 2530 default: 2531 return false; 2532 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { 2533 handleAsyncChannelHalfConnect(msg); 2534 break; 2535 } 2536 case AsyncChannel.CMD_CHANNEL_DISCONNECT: { 2537 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2538 if (nai != null) nai.asyncChannel.disconnect(); 2539 break; 2540 } 2541 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 2542 handleAsyncChannelDisconnected(msg); 2543 break; 2544 } 2545 } 2546 return true; 2547 } 2548 maybeHandleNetworkAgentMessage(Message msg)2549 private void maybeHandleNetworkAgentMessage(Message msg) { 2550 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2551 if (nai == null) { 2552 if (VDBG) { 2553 log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); 2554 } 2555 return; 2556 } 2557 2558 switch (msg.what) { 2559 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 2560 final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj; 2561 if (networkCapabilities.hasConnectivityManagedCapability()) { 2562 Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); 2563 } 2564 updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities); 2565 break; 2566 } 2567 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 2568 handleUpdateLinkProperties(nai, (LinkProperties) msg.obj); 2569 break; 2570 } 2571 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 2572 NetworkInfo info = (NetworkInfo) msg.obj; 2573 updateNetworkInfo(nai, info); 2574 break; 2575 } 2576 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 2577 updateNetworkScore(nai, msg.arg1); 2578 break; 2579 } 2580 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 2581 if (nai.everConnected) { 2582 loge("ERROR: cannot call explicitlySelected on already-connected network"); 2583 } 2584 nai.networkMisc.explicitlySelected = (msg.arg1 == 1); 2585 nai.networkMisc.acceptUnvalidated = (msg.arg1 == 1) && (msg.arg2 == 1); 2586 // Mark the network as temporarily accepting partial connectivity so that it 2587 // will be validated (and possibly become default) even if it only provides 2588 // partial internet access. Note that if user connects to partial connectivity 2589 // and choose "don't ask again", then wifi disconnected by some reasons(maybe 2590 // out of wifi coverage) and if the same wifi is available again, the device 2591 // will auto connect to this wifi even though the wifi has "no internet". 2592 // TODO: Evaluate using a separate setting in IpMemoryStore. 2593 nai.networkMisc.acceptPartialConnectivity = (msg.arg2 == 1); 2594 break; 2595 } 2596 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { 2597 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg); 2598 break; 2599 } 2600 } 2601 } 2602 maybeHandleNetworkMonitorMessage(Message msg)2603 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 2604 switch (msg.what) { 2605 default: 2606 return false; 2607 case EVENT_NETWORK_TESTED: { 2608 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 2609 if (nai == null) break; 2610 2611 final boolean wasPartial = nai.partialConnectivity; 2612 nai.partialConnectivity = ((msg.arg1 & NETWORK_VALIDATION_RESULT_PARTIAL) != 0); 2613 final boolean partialConnectivityChanged = 2614 (wasPartial != nai.partialConnectivity); 2615 2616 final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0); 2617 final boolean wasValidated = nai.lastValidated; 2618 final boolean wasDefault = isDefaultNetwork(nai); 2619 // Only show a connected notification if the network is pending validation 2620 // after the captive portal app was open, and it has now validated. 2621 if (nai.captivePortalValidationPending && valid) { 2622 // User is now logged in, network validated. 2623 nai.captivePortalValidationPending = false; 2624 showNetworkNotification(nai, NotificationType.LOGGED_IN); 2625 } 2626 2627 final String redirectUrl = (msg.obj instanceof String) ? (String) msg.obj : ""; 2628 2629 if (DBG) { 2630 final String logMsg = !TextUtils.isEmpty(redirectUrl) 2631 ? " with redirect to " + redirectUrl 2632 : ""; 2633 log(nai.name() + " validation " + (valid ? "passed" : "failed") + logMsg); 2634 } 2635 if (valid != nai.lastValidated) { 2636 if (wasDefault) { 2637 metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity( 2638 SystemClock.elapsedRealtime(), valid); 2639 } 2640 final int oldScore = nai.getCurrentScore(); 2641 nai.lastValidated = valid; 2642 nai.everValidated |= valid; 2643 updateCapabilities(oldScore, nai, nai.networkCapabilities); 2644 // If score has changed, rebroadcast to NetworkFactories. b/17726566 2645 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); 2646 if (valid) { 2647 handleFreshlyValidatedNetwork(nai); 2648 // Clear NO_INTERNET, PARTIAL_CONNECTIVITY and LOST_INTERNET 2649 // notifications if network becomes valid. 2650 mNotifier.clearNotification(nai.network.netId, 2651 NotificationType.NO_INTERNET); 2652 mNotifier.clearNotification(nai.network.netId, 2653 NotificationType.LOST_INTERNET); 2654 mNotifier.clearNotification(nai.network.netId, 2655 NotificationType.PARTIAL_CONNECTIVITY); 2656 } 2657 } else if (partialConnectivityChanged) { 2658 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); 2659 } 2660 updateInetCondition(nai); 2661 // Let the NetworkAgent know the state of its network 2662 Bundle redirectUrlBundle = new Bundle(); 2663 redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl); 2664 // TODO: Evaluate to update partial connectivity to status to NetworkAgent. 2665 nai.asyncChannel.sendMessage( 2666 NetworkAgent.CMD_REPORT_NETWORK_STATUS, 2667 (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), 2668 0, redirectUrlBundle); 2669 2670 // If NetworkMonitor detects partial connectivity before 2671 // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification 2672 // immediately. Re-notify partial connectivity silently if no internet 2673 // notification already there. 2674 if (!wasPartial && nai.partialConnectivity) { 2675 // Remove delayed message if there is a pending message. 2676 mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network); 2677 handlePromptUnvalidated(nai.network); 2678 } 2679 2680 if (wasValidated && !nai.lastValidated) { 2681 handleNetworkUnvalidated(nai); 2682 } 2683 break; 2684 } 2685 case EVENT_PROVISIONING_NOTIFICATION: { 2686 final int netId = msg.arg2; 2687 final boolean visible = toBool(msg.arg1); 2688 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 2689 // If captive portal status has changed, update capabilities or disconnect. 2690 if (nai != null && (visible != nai.lastCaptivePortalDetected)) { 2691 final int oldScore = nai.getCurrentScore(); 2692 nai.lastCaptivePortalDetected = visible; 2693 nai.everCaptivePortalDetected |= visible; 2694 if (nai.lastCaptivePortalDetected && 2695 Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) { 2696 if (DBG) log("Avoiding captive portal network: " + nai.name()); 2697 nai.asyncChannel.sendMessage( 2698 NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 2699 teardownUnneededNetwork(nai); 2700 break; 2701 } 2702 updateCapabilities(oldScore, nai, nai.networkCapabilities); 2703 } 2704 if (!visible) { 2705 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other 2706 // notifications belong to the same network may be cleared unexpectedly. 2707 mNotifier.clearNotification(netId, NotificationType.SIGN_IN); 2708 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH); 2709 } else { 2710 if (nai == null) { 2711 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 2712 break; 2713 } 2714 if (!nai.networkMisc.provisioningNotificationDisabled) { 2715 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 2716 (PendingIntent) msg.obj, nai.networkMisc.explicitlySelected); 2717 } 2718 } 2719 break; 2720 } 2721 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { 2722 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 2723 if (nai == null) break; 2724 2725 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); 2726 break; 2727 } 2728 } 2729 return true; 2730 } 2731 getCaptivePortalMode()2732 private int getCaptivePortalMode() { 2733 return Settings.Global.getInt(mContext.getContentResolver(), 2734 Settings.Global.CAPTIVE_PORTAL_MODE, 2735 Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT); 2736 } 2737 maybeHandleNetworkAgentInfoMessage(Message msg)2738 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 2739 switch (msg.what) { 2740 default: 2741 return false; 2742 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 2743 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 2744 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 2745 handleLingerComplete(nai); 2746 } 2747 break; 2748 } 2749 } 2750 return true; 2751 } 2752 maybeHandleNetworkFactoryMessage(Message msg)2753 private boolean maybeHandleNetworkFactoryMessage(Message msg) { 2754 switch (msg.what) { 2755 default: 2756 return false; 2757 case NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: { 2758 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.sendingUid, 2759 /* callOnUnavailable */ true); 2760 break; 2761 } 2762 } 2763 return true; 2764 } 2765 2766 @Override handleMessage(Message msg)2767 public void handleMessage(Message msg) { 2768 if (!maybeHandleAsyncChannelMessage(msg) 2769 && !maybeHandleNetworkMonitorMessage(msg) 2770 && !maybeHandleNetworkAgentInfoMessage(msg) 2771 && !maybeHandleNetworkFactoryMessage(msg)) { 2772 maybeHandleNetworkAgentMessage(msg); 2773 } 2774 } 2775 } 2776 2777 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub { 2778 private final int mNetId; 2779 private final AutodestructReference<NetworkAgentInfo> mNai; 2780 NetworkMonitorCallbacks(NetworkAgentInfo nai)2781 private NetworkMonitorCallbacks(NetworkAgentInfo nai) { 2782 mNetId = nai.network.netId; 2783 mNai = new AutodestructReference(nai); 2784 } 2785 2786 @Override onNetworkMonitorCreated(INetworkMonitor networkMonitor)2787 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 2788 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, 2789 new Pair<>(mNai.getAndDestroy(), networkMonitor))); 2790 } 2791 2792 @Override notifyNetworkTested(int testResult, @Nullable String redirectUrl)2793 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { 2794 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(EVENT_NETWORK_TESTED, 2795 testResult, mNetId, redirectUrl)); 2796 } 2797 2798 @Override notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config)2799 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) { 2800 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 2801 EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 2802 0, mNetId, PrivateDnsConfig.fromParcel(config))); 2803 } 2804 2805 @Override showProvisioningNotification(String action, String packageName)2806 public void showProvisioningNotification(String action, String packageName) { 2807 final Intent intent = new Intent(action); 2808 intent.setPackage(packageName); 2809 2810 final PendingIntent pendingIntent; 2811 // Only the system server can register notifications with package "android" 2812 final long token = Binder.clearCallingIdentity(); 2813 try { 2814 pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 2815 } finally { 2816 Binder.restoreCallingIdentity(token); 2817 } 2818 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 2819 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW, 2820 mNetId, pendingIntent)); 2821 } 2822 2823 @Override hideProvisioningNotification()2824 public void hideProvisioningNotification() { 2825 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 2826 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); 2827 } 2828 2829 @Override getInterfaceVersion()2830 public int getInterfaceVersion() { 2831 return this.VERSION; 2832 } 2833 } 2834 networkRequiresPrivateDnsValidation(NetworkAgentInfo nai)2835 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { 2836 return isPrivateDnsValidationRequired(nai.networkCapabilities); 2837 } 2838 handleFreshlyValidatedNetwork(NetworkAgentInfo nai)2839 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { 2840 if (nai == null) return; 2841 // If the Private DNS mode is opportunistic, reprogram the DNS servers 2842 // in order to restart a validation pass from within netd. 2843 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 2844 if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) { 2845 updateDnses(nai.linkProperties, null, nai.network.netId); 2846 } 2847 } 2848 handlePrivateDnsSettingsChanged()2849 private void handlePrivateDnsSettingsChanged() { 2850 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 2851 2852 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2853 handlePerNetworkPrivateDnsConfig(nai, cfg); 2854 if (networkRequiresPrivateDnsValidation(nai)) { 2855 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 2856 } 2857 } 2858 } 2859 handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)2860 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 2861 // Private DNS only ever applies to networks that might provide 2862 // Internet access and therefore also require validation. 2863 if (!networkRequiresPrivateDnsValidation(nai)) return; 2864 2865 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or 2866 // schedule DNS resolutions. If a DNS resolution is required the 2867 // result will be sent back to us. 2868 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel()); 2869 2870 // With Private DNS bypass support, we can proceed to update the 2871 // Private DNS config immediately, even if we're in strict mode 2872 // and have not yet resolved the provider name into a set of IPs. 2873 updatePrivateDns(nai, cfg); 2874 } 2875 updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)2876 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 2877 mDnsManager.updatePrivateDns(nai.network, newCfg); 2878 updateDnses(nai.linkProperties, null, nai.network.netId); 2879 } 2880 handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)2881 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 2882 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 2883 if (nai == null) { 2884 return; 2885 } 2886 mDnsManager.updatePrivateDnsValidation(update); 2887 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 2888 } 2889 handleNat64PrefixEvent(int netId, boolean added, String prefixString, int prefixLength)2890 private void handleNat64PrefixEvent(int netId, boolean added, String prefixString, 2891 int prefixLength) { 2892 NetworkAgentInfo nai = mNetworkForNetId.get(netId); 2893 if (nai == null) return; 2894 2895 log(String.format("NAT64 prefix %s on netId %d: %s/%d", 2896 (added ? "added" : "removed"), netId, prefixString, prefixLength)); 2897 2898 IpPrefix prefix = null; 2899 if (added) { 2900 try { 2901 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString), 2902 prefixLength); 2903 } catch (IllegalArgumentException e) { 2904 loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength); 2905 return; 2906 } 2907 } 2908 2909 nai.clatd.setNat64Prefix(prefix); 2910 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 2911 } 2912 updateLingerState(NetworkAgentInfo nai, long now)2913 private void updateLingerState(NetworkAgentInfo nai, long now) { 2914 // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm. 2915 // 2. If the network was lingering and there are now requests, unlinger it. 2916 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 2917 // one lingered request, start lingering. 2918 nai.updateLingerTimer(); 2919 if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) { 2920 if (DBG) log("Unlingering " + nai.name()); 2921 nai.unlinger(); 2922 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 2923 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) { 2924 int lingerTime = (int) (nai.getLingerExpiry() - now); 2925 if (DBG) log("Lingering " + nai.name() + " for " + lingerTime + "ms"); 2926 nai.linger(); 2927 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 2928 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 2929 } 2930 } 2931 handleAsyncChannelHalfConnect(Message msg)2932 private void handleAsyncChannelHalfConnect(Message msg) { 2933 AsyncChannel ac = (AsyncChannel) msg.obj; 2934 if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { 2935 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2936 if (VDBG) log("NetworkFactory connected"); 2937 // Finish setting up the full connection 2938 mNetworkFactoryInfos.get(msg.replyTo).asyncChannel.sendMessage( 2939 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 2940 // A network factory has connected. Send it all current NetworkRequests. 2941 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2942 if (nri.request.isListen()) continue; 2943 NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); 2944 final int score; 2945 final int serial; 2946 if (nai != null) { 2947 score = nai.getCurrentScore(); 2948 serial = nai.factorySerialNumber; 2949 } else { 2950 score = 0; 2951 serial = NetworkFactory.SerialNumber.NONE; 2952 } 2953 ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, serial, 2954 nri.request); 2955 } 2956 } else { 2957 loge("Error connecting NetworkFactory"); 2958 mNetworkFactoryInfos.remove(msg.obj); 2959 } 2960 } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { 2961 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2962 if (VDBG) log("NetworkAgent connected"); 2963 // A network agent has requested a connection. Establish the connection. 2964 mNetworkAgentInfos.get(msg.replyTo).asyncChannel. 2965 sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 2966 } else { 2967 loge("Error connecting NetworkAgent"); 2968 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); 2969 if (nai != null) { 2970 final boolean wasDefault = isDefaultNetwork(nai); 2971 synchronized (mNetworkForNetId) { 2972 mNetworkForNetId.remove(nai.network.netId); 2973 mNetIdInUse.delete(nai.network.netId); 2974 } 2975 // Just in case. 2976 mLegacyTypeTracker.remove(nai, wasDefault); 2977 } 2978 } 2979 } 2980 } 2981 2982 // This is a no-op if it's called with a message designating a network that has 2983 // already been destroyed, because its reference will not be found in the relevant 2984 // maps. handleAsyncChannelDisconnected(Message msg)2985 private void handleAsyncChannelDisconnected(Message msg) { 2986 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2987 if (nai != null) { 2988 disconnectAndDestroyNetwork(nai); 2989 } else { 2990 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); 2991 if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); 2992 } 2993 } 2994 2995 // Destroys a network, remove references to it from the internal state managed by 2996 // ConnectivityService, free its interfaces and clean up. 2997 // Must be called on the Handler thread. disconnectAndDestroyNetwork(NetworkAgentInfo nai)2998 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 2999 if (DBG) { 3000 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); 3001 } 3002 // Clear all notifications of this network. 3003 mNotifier.clearNotification(nai.network.netId); 3004 // A network agent has disconnected. 3005 // TODO - if we move the logic to the network agent (have them disconnect 3006 // because they lost all their requests or because their score isn't good) 3007 // then they would disconnect organically, report their new state and then 3008 // disconnect the channel. 3009 if (nai.networkInfo.isConnected()) { 3010 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 3011 null, null); 3012 } 3013 final boolean wasDefault = isDefaultNetwork(nai); 3014 if (wasDefault) { 3015 mDefaultInetConditionPublished = 0; 3016 // Log default network disconnection before required book-keeping. 3017 // Let rematchAllNetworksAndRequests() below record a new default network event 3018 // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence 3019 // whose timestamps tell how long it takes to recover a default network. 3020 long now = SystemClock.elapsedRealtime(); 3021 metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); 3022 } 3023 notifyIfacesChangedForNetworkStats(); 3024 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 3025 // by other networks that are already connected. Perhaps that can be done by 3026 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 3027 // of rematchAllNetworksAndRequests 3028 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 3029 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK); 3030 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 3031 // Disable wakeup packet monitoring for each interface. 3032 wakeupModifyInterface(iface, nai.networkCapabilities, false); 3033 } 3034 nai.networkMonitor().notifyNetworkDisconnected(); 3035 mNetworkAgentInfos.remove(nai.messenger); 3036 nai.clatd.update(); 3037 synchronized (mNetworkForNetId) { 3038 // Remove the NetworkAgent, but don't mark the netId as 3039 // available until we've told netd to delete it below. 3040 mNetworkForNetId.remove(nai.network.netId); 3041 } 3042 // Remove all previously satisfied requests. 3043 for (int i = 0; i < nai.numNetworkRequests(); i++) { 3044 NetworkRequest request = nai.requestAt(i); 3045 NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId); 3046 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { 3047 clearNetworkForRequest(request.requestId); 3048 sendUpdatedScoreToFactories(request, null); 3049 } 3050 } 3051 nai.clearLingerState(); 3052 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 3053 updateDataActivityTracking(null /* newNetwork */, nai); 3054 notifyLockdownVpn(nai); 3055 ensureNetworkTransitionWakelock(nai.name()); 3056 } 3057 mLegacyTypeTracker.remove(nai, wasDefault); 3058 if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) { 3059 updateAllVpnsCapabilities(); 3060 } 3061 rematchAllNetworksAndRequests(null, 0); 3062 mLingerMonitor.noteDisconnect(nai); 3063 if (nai.created) { 3064 // Tell netd to clean up the configuration for this network 3065 // (routing rules, DNS, etc). 3066 // This may be slow as it requires a lot of netd shelling out to ip and 3067 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 3068 // after we've rematched networks with requests which should make a potential 3069 // fallback network the default or requested a new network from the 3070 // NetworkFactories, so network traffic isn't interrupted for an unnecessarily 3071 // long time. 3072 destroyNativeNetwork(nai); 3073 mDnsManager.removeNetwork(nai.network); 3074 } 3075 synchronized (mNetworkForNetId) { 3076 mNetIdInUse.delete(nai.network.netId); 3077 } 3078 } 3079 createNativeNetwork(@onNull NetworkAgentInfo networkAgent)3080 private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { 3081 try { 3082 // This should never fail. Specifying an already in use NetID will cause failure. 3083 if (networkAgent.isVPN()) { 3084 mNetd.networkCreateVpn(networkAgent.network.netId, 3085 (networkAgent.networkMisc == null 3086 || !networkAgent.networkMisc.allowBypass)); 3087 } else { 3088 mNetd.networkCreatePhysical(networkAgent.network.netId, 3089 getNetworkPermission(networkAgent.networkCapabilities)); 3090 } 3091 mDnsResolver.createNetworkCache(networkAgent.network.netId); 3092 return true; 3093 } catch (RemoteException | ServiceSpecificException e) { 3094 loge("Error creating network " + networkAgent.network.netId + ": " 3095 + e.getMessage()); 3096 return false; 3097 } 3098 } 3099 destroyNativeNetwork(@onNull NetworkAgentInfo networkAgent)3100 private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { 3101 try { 3102 mNetd.networkDestroy(networkAgent.network.netId); 3103 mDnsResolver.destroyNetworkCache(networkAgent.network.netId); 3104 } catch (RemoteException | ServiceSpecificException e) { 3105 loge("Exception destroying network: " + e); 3106 } 3107 } 3108 3109 // If this method proves to be too slow then we can maintain a separate 3110 // pendingIntent => NetworkRequestInfo map. 3111 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. findExistingNetworkRequestInfo(PendingIntent pendingIntent)3112 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 3113 Intent intent = pendingIntent.getIntent(); 3114 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 3115 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 3116 if (existingPendingIntent != null && 3117 existingPendingIntent.getIntent().filterEquals(intent)) { 3118 return entry.getValue(); 3119 } 3120 } 3121 return null; 3122 } 3123 handleRegisterNetworkRequestWithIntent(Message msg)3124 private void handleRegisterNetworkRequestWithIntent(Message msg) { 3125 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 3126 3127 NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent); 3128 if (existingRequest != null) { // remove the existing request. 3129 if (DBG) log("Replacing " + existingRequest.request + " with " 3130 + nri.request + " because their intents matched."); 3131 handleReleaseNetworkRequest(existingRequest.request, getCallingUid(), 3132 /* callOnUnavailable */ false); 3133 } 3134 handleRegisterNetworkRequest(nri); 3135 } 3136 handleRegisterNetworkRequest(NetworkRequestInfo nri)3137 private void handleRegisterNetworkRequest(NetworkRequestInfo nri) { 3138 mNetworkRequests.put(nri.request, nri); 3139 mNetworkRequestInfoLogs.log("REGISTER " + nri); 3140 if (nri.request.isListen()) { 3141 for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { 3142 if (nri.request.networkCapabilities.hasSignalStrength() && 3143 network.satisfiesImmutableCapabilitiesOf(nri.request)) { 3144 updateSignalStrengthThresholds(network, "REGISTER", nri.request); 3145 } 3146 } 3147 } 3148 rematchAllNetworksAndRequests(null, 0); 3149 if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) { 3150 sendUpdatedScoreToFactories(nri.request, null); 3151 } 3152 } 3153 handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, int callingUid)3154 private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, 3155 int callingUid) { 3156 NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 3157 if (nri != null) { 3158 handleReleaseNetworkRequest(nri.request, callingUid, /* callOnUnavailable */ false); 3159 } 3160 } 3161 3162 // Determines whether the network is the best (or could become the best, if it validated), for 3163 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 3164 // on the value of reason: 3165 // 3166 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 3167 // then it should be torn down. 3168 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 3169 // then it should be lingered. unneeded(NetworkAgentInfo nai, UnneededFor reason)3170 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 3171 final int numRequests; 3172 switch (reason) { 3173 case TEARDOWN: 3174 numRequests = nai.numRequestNetworkRequests(); 3175 break; 3176 case LINGER: 3177 numRequests = nai.numForegroundNetworkRequests(); 3178 break; 3179 default: 3180 Slog.wtf(TAG, "Invalid reason. Cannot happen."); 3181 return true; 3182 } 3183 3184 if (!nai.everConnected || nai.isVPN() || nai.isLingering() || numRequests > 0) { 3185 return false; 3186 } 3187 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 3188 if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) { 3189 // Background requests don't affect lingering. 3190 continue; 3191 } 3192 3193 // If this Network is already the highest scoring Network for a request, or if 3194 // there is hope for it to become one if it validated, then it is needed. 3195 if (nri.request.isRequest() && nai.satisfies(nri.request) && 3196 (nai.isSatisfyingRequest(nri.request.requestId) || 3197 // Note that this catches two important cases: 3198 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 3199 // is currently satisfying the request. This is desirable when 3200 // cellular ends up validating but WiFi does not. 3201 // 2. Unvalidated WiFi will not be reaped when validated cellular 3202 // is currently satisfying the request. This is desirable when 3203 // WiFi ends up validating and out scoring cellular. 3204 getNetworkForRequest(nri.request.requestId).getCurrentScore() < 3205 nai.getCurrentScoreAsValidated())) { 3206 return false; 3207 } 3208 } 3209 return true; 3210 } 3211 getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)3212 private NetworkRequestInfo getNriForAppRequest( 3213 NetworkRequest request, int callingUid, String requestedOperation) { 3214 final NetworkRequestInfo nri = mNetworkRequests.get(request); 3215 3216 if (nri != null) { 3217 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 3218 log(String.format("UID %d attempted to %s for unowned request %s", 3219 callingUid, requestedOperation, nri)); 3220 return null; 3221 } 3222 } 3223 3224 return nri; 3225 } 3226 handleTimedOutNetworkRequest(final NetworkRequestInfo nri)3227 private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) { 3228 if (mNetworkRequests.get(nri.request) == null) { 3229 return; 3230 } 3231 if (getNetworkForRequest(nri.request.requestId) != null) { 3232 return; 3233 } 3234 if (VDBG || (DBG && nri.request.isRequest())) { 3235 log("releasing " + nri.request + " (timeout)"); 3236 } 3237 handleRemoveNetworkRequest(nri); 3238 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 3239 } 3240 handleReleaseNetworkRequest(NetworkRequest request, int callingUid, boolean callOnUnavailable)3241 private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid, 3242 boolean callOnUnavailable) { 3243 final NetworkRequestInfo nri = 3244 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 3245 if (nri == null) { 3246 return; 3247 } 3248 if (VDBG || (DBG && nri.request.isRequest())) { 3249 log("releasing " + nri.request + " (release request)"); 3250 } 3251 handleRemoveNetworkRequest(nri); 3252 if (callOnUnavailable) { 3253 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 3254 } 3255 } 3256 handleRemoveNetworkRequest(final NetworkRequestInfo nri)3257 private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) { 3258 nri.unlinkDeathRecipient(); 3259 mNetworkRequests.remove(nri.request); 3260 3261 synchronized (mUidToNetworkRequestCount) { 3262 int requests = mUidToNetworkRequestCount.get(nri.mUid, 0); 3263 if (requests < 1) { 3264 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + 3265 nri.mUid); 3266 } else if (requests == 1) { 3267 mUidToNetworkRequestCount.removeAt( 3268 mUidToNetworkRequestCount.indexOfKey(nri.mUid)); 3269 } else { 3270 mUidToNetworkRequestCount.put(nri.mUid, requests - 1); 3271 } 3272 } 3273 3274 mNetworkRequestInfoLogs.log("RELEASE " + nri); 3275 if (nri.request.isRequest()) { 3276 boolean wasKept = false; 3277 NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); 3278 if (nai != null) { 3279 boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 3280 nai.removeRequest(nri.request.requestId); 3281 if (VDBG || DDBG) { 3282 log(" Removing from current network " + nai.name() + 3283 ", leaving " + nai.numNetworkRequests() + " requests."); 3284 } 3285 // If there are still lingered requests on this network, don't tear it down, 3286 // but resume lingering instead. 3287 updateLingerState(nai, SystemClock.elapsedRealtime()); 3288 if (unneeded(nai, UnneededFor.TEARDOWN)) { 3289 if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); 3290 teardownUnneededNetwork(nai); 3291 } else { 3292 wasKept = true; 3293 } 3294 clearNetworkForRequest(nri.request.requestId); 3295 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 3296 // Went from foreground to background. 3297 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); 3298 } 3299 } 3300 3301 // Maintain the illusion. When this request arrived, we might have pretended 3302 // that a network connected to serve it, even though the network was already 3303 // connected. Now that this request has gone away, we might have to pretend 3304 // that the network disconnected. LegacyTypeTracker will generate that 3305 // phantom disconnect for this type. 3306 if (nri.request.legacyType != TYPE_NONE && nai != null) { 3307 boolean doRemove = true; 3308 if (wasKept) { 3309 // check if any of the remaining requests for this network are for the 3310 // same legacy type - if so, don't remove the nai 3311 for (int i = 0; i < nai.numNetworkRequests(); i++) { 3312 NetworkRequest otherRequest = nai.requestAt(i); 3313 if (otherRequest.legacyType == nri.request.legacyType && 3314 otherRequest.isRequest()) { 3315 if (DBG) log(" still have other legacy request - leaving"); 3316 doRemove = false; 3317 } 3318 } 3319 } 3320 3321 if (doRemove) { 3322 mLegacyTypeTracker.remove(nri.request.legacyType, nai, false); 3323 } 3324 } 3325 3326 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 3327 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, 3328 nri.request); 3329 } 3330 } else { 3331 // listens don't have a singular affectedNetwork. Check all networks to see 3332 // if this listen request applies and remove it. 3333 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 3334 nai.removeRequest(nri.request.requestId); 3335 if (nri.request.networkCapabilities.hasSignalStrength() && 3336 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 3337 updateSignalStrengthThresholds(nai, "RELEASE", nri.request); 3338 } 3339 } 3340 } 3341 } 3342 3343 @Override setAcceptUnvalidated(Network network, boolean accept, boolean always)3344 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 3345 enforceNetworkStackSettingsOrSetup(); 3346 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 3347 encodeBool(accept), encodeBool(always), network)); 3348 } 3349 3350 @Override setAcceptPartialConnectivity(Network network, boolean accept, boolean always)3351 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { 3352 enforceNetworkStackSettingsOrSetup(); 3353 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY, 3354 encodeBool(accept), encodeBool(always), network)); 3355 } 3356 3357 @Override setAvoidUnvalidated(Network network)3358 public void setAvoidUnvalidated(Network network) { 3359 enforceNetworkStackSettingsOrSetup(); 3360 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 3361 } 3362 handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)3363 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 3364 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 3365 " accept=" + accept + " always=" + always); 3366 3367 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3368 if (nai == null) { 3369 // Nothing to do. 3370 return; 3371 } 3372 3373 if (nai.everValidated) { 3374 // The network validated while the dialog box was up. Take no action. 3375 return; 3376 } 3377 3378 if (!nai.networkMisc.explicitlySelected) { 3379 Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 3380 } 3381 3382 if (accept != nai.networkMisc.acceptUnvalidated) { 3383 int oldScore = nai.getCurrentScore(); 3384 nai.networkMisc.acceptUnvalidated = accept; 3385 // If network becomes partial connectivity and user already accepted to use this 3386 // network, we should respect the user's option and don't need to popup the 3387 // PARTIAL_CONNECTIVITY notification to user again. 3388 nai.networkMisc.acceptPartialConnectivity = accept; 3389 rematchAllNetworksAndRequests(nai, oldScore); 3390 sendUpdatedScoreToFactories(nai); 3391 } 3392 3393 if (always) { 3394 nai.asyncChannel.sendMessage( 3395 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept)); 3396 } 3397 3398 if (!accept) { 3399 // Tell the NetworkAgent to not automatically reconnect to the network. 3400 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 3401 // Teardown the network. 3402 teardownUnneededNetwork(nai); 3403 } 3404 3405 } 3406 handleSetAcceptPartialConnectivity(Network network, boolean accept, boolean always)3407 private void handleSetAcceptPartialConnectivity(Network network, boolean accept, 3408 boolean always) { 3409 if (DBG) { 3410 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept 3411 + " always=" + always); 3412 } 3413 3414 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3415 if (nai == null) { 3416 // Nothing to do. 3417 return; 3418 } 3419 3420 if (nai.lastValidated) { 3421 // The network validated while the dialog box was up. Take no action. 3422 return; 3423 } 3424 3425 if (accept != nai.networkMisc.acceptPartialConnectivity) { 3426 nai.networkMisc.acceptPartialConnectivity = accept; 3427 } 3428 3429 // TODO: Use the current design or save the user choice into IpMemoryStore. 3430 if (always) { 3431 nai.asyncChannel.sendMessage( 3432 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept)); 3433 } 3434 3435 if (!accept) { 3436 // Tell the NetworkAgent to not automatically reconnect to the network. 3437 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 3438 // Tear down the network. 3439 teardownUnneededNetwork(nai); 3440 } else { 3441 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely 3442 // result in a partial connectivity result which will be processed by 3443 // maybeHandleNetworkMonitorMessage. 3444 // 3445 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored 3446 // per network. Therefore, NetworkMonitor may still do https probe. 3447 nai.networkMonitor().setAcceptPartialConnectivity(); 3448 } 3449 } 3450 handleSetAvoidUnvalidated(Network network)3451 private void handleSetAvoidUnvalidated(Network network) { 3452 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3453 if (nai == null || nai.lastValidated) { 3454 // Nothing to do. The network either disconnected or revalidated. 3455 return; 3456 } 3457 if (!nai.avoidUnvalidated) { 3458 int oldScore = nai.getCurrentScore(); 3459 nai.avoidUnvalidated = true; 3460 rematchAllNetworksAndRequests(nai, oldScore); 3461 sendUpdatedScoreToFactories(nai); 3462 } 3463 } 3464 scheduleUnvalidatedPrompt(NetworkAgentInfo nai)3465 private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { 3466 if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); 3467 mHandler.sendMessageDelayed( 3468 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network), 3469 PROMPT_UNVALIDATED_DELAY_MS); 3470 } 3471 3472 @Override startCaptivePortalApp(Network network)3473 public void startCaptivePortalApp(Network network) { 3474 enforceConnectivityInternalPermission(); 3475 mHandler.post(() -> { 3476 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3477 if (nai == null) return; 3478 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 3479 nai.networkMonitor().launchCaptivePortalApp(); 3480 }); 3481 } 3482 3483 /** 3484 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this 3485 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. 3486 * @param network Network on which the captive portal was detected. 3487 * @param appExtras Bundle to use as intent extras for the captive portal application. 3488 * Must be treated as opaque to avoid preventing the captive portal app to 3489 * update its arguments. 3490 */ 3491 @Override startCaptivePortalAppInternal(Network network, Bundle appExtras)3492 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { 3493 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3494 "ConnectivityService"); 3495 3496 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); 3497 appIntent.putExtras(appExtras); 3498 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, 3499 new CaptivePortal(new CaptivePortalImpl(network).asBinder())); 3500 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); 3501 3502 // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe, 3503 // and captivePortalValidationPending is volatile. 3504 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3505 if (nai != null) { 3506 nai.captivePortalValidationPending = true; 3507 } 3508 Binder.withCleanCallingIdentity(() -> 3509 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT)); 3510 } 3511 3512 private class CaptivePortalImpl extends ICaptivePortal.Stub { 3513 private final Network mNetwork; 3514 CaptivePortalImpl(Network network)3515 private CaptivePortalImpl(Network network) { 3516 mNetwork = network; 3517 } 3518 3519 @Override appResponse(final int response)3520 public void appResponse(final int response) { 3521 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { 3522 enforceSettingsPermission(); 3523 } 3524 3525 // getNetworkAgentInfoForNetwork is thread-safe 3526 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork); 3527 if (nai == null) return; 3528 3529 // nai.networkMonitor() is thread-safe 3530 final NetworkMonitorManager nm = nai.networkMonitor(); 3531 if (nm == null) return; 3532 nm.notifyCaptivePortalAppFinished(response); 3533 } 3534 3535 @Override logEvent(int eventId, String packageName)3536 public void logEvent(int eventId, String packageName) { 3537 enforceSettingsPermission(); 3538 3539 new MetricsLogger().action(eventId, packageName); 3540 } 3541 } 3542 avoidBadWifi()3543 public boolean avoidBadWifi() { 3544 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 3545 } 3546 3547 /** 3548 * Return whether the device should maintain continuous, working connectivity by switching away 3549 * from WiFi networks having no connectivity. 3550 * @see MultinetworkPolicyTracker#getAvoidBadWifi() 3551 */ shouldAvoidBadWifi()3552 public boolean shouldAvoidBadWifi() { 3553 if (!checkNetworkStackPermission()) { 3554 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); 3555 } 3556 return avoidBadWifi(); 3557 } 3558 3559 rematchForAvoidBadWifiUpdate()3560 private void rematchForAvoidBadWifiUpdate() { 3561 rematchAllNetworksAndRequests(null, 0); 3562 for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) { 3563 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 3564 sendUpdatedScoreToFactories(nai); 3565 } 3566 } 3567 } 3568 3569 // TODO: Evaluate whether this is of interest to other consumers of 3570 // MultinetworkPolicyTracker and worth moving out of here. dumpAvoidBadWifiSettings(IndentingPrintWriter pw)3571 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 3572 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 3573 if (!configRestrict) { 3574 pw.println("Bad Wi-Fi avoidance: unrestricted"); 3575 return; 3576 } 3577 3578 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 3579 pw.increaseIndent(); 3580 pw.println("Config restrict: " + configRestrict); 3581 3582 final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 3583 String description; 3584 // Can't use a switch statement because strings are legal case labels, but null is not. 3585 if ("0".equals(value)) { 3586 description = "get stuck"; 3587 } else if (value == null) { 3588 description = "prompt"; 3589 } else if ("1".equals(value)) { 3590 description = "avoid"; 3591 } else { 3592 description = value + " (?)"; 3593 } 3594 pw.println("User setting: " + description); 3595 pw.println("Network overrides:"); 3596 pw.increaseIndent(); 3597 for (NetworkAgentInfo nai : networksSortedById()) { 3598 if (nai.avoidUnvalidated) { 3599 pw.println(nai.name()); 3600 } 3601 } 3602 pw.decreaseIndent(); 3603 pw.decreaseIndent(); 3604 } 3605 showNetworkNotification(NetworkAgentInfo nai, NotificationType type)3606 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) { 3607 final String action; 3608 final boolean highPriority; 3609 switch (type) { 3610 case LOGGED_IN: 3611 action = Settings.ACTION_WIFI_SETTINGS; 3612 mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION); 3613 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION, 3614 nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS); 3615 // High priority because it is a direct result of the user logging in to a portal. 3616 highPriority = true; 3617 break; 3618 case NO_INTERNET: 3619 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 3620 // High priority because it is only displayed for explicitly selected networks. 3621 highPriority = true; 3622 break; 3623 case LOST_INTERNET: 3624 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 3625 // High priority because it could help the user avoid unexpected data usage. 3626 highPriority = true; 3627 break; 3628 case PARTIAL_CONNECTIVITY: 3629 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY; 3630 // Don't bother the user with a high-priority notification if the network was not 3631 // explicitly selected by the user. 3632 highPriority = nai.networkMisc.explicitlySelected; 3633 break; 3634 default: 3635 Slog.wtf(TAG, "Unknown notification type " + type); 3636 return; 3637 } 3638 3639 Intent intent = new Intent(action); 3640 if (type != NotificationType.LOGGED_IN) { 3641 intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null)); 3642 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3643 intent.setClassName("com.android.settings", 3644 "com.android.settings.wifi.WifiNoInternetDialog"); 3645 } 3646 3647 PendingIntent pendingIntent = PendingIntent.getActivityAsUser( 3648 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 3649 3650 mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority); 3651 } 3652 shouldPromptUnvalidated(NetworkAgentInfo nai)3653 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) { 3654 // Don't prompt if the network is validated, and don't prompt on captive portals 3655 // because we're already prompting the user to sign in. 3656 if (nai.everValidated || nai.everCaptivePortalDetected) { 3657 return false; 3658 } 3659 3660 // If a network has partial connectivity, always prompt unless the user has already accepted 3661 // partial connectivity and selected don't ask again. This ensures that if the device 3662 // automatically connects to a network that has partial Internet access, the user will 3663 // always be able to use it, either because they've already chosen "don't ask again" or 3664 // because we have prompt them. 3665 if (nai.partialConnectivity && !nai.networkMisc.acceptPartialConnectivity) { 3666 return true; 3667 } 3668 3669 // If a network has no Internet access, only prompt if the network was explicitly selected 3670 // and if the user has not already told us to use the network regardless of whether it 3671 // validated or not. 3672 if (nai.networkMisc.explicitlySelected && !nai.networkMisc.acceptUnvalidated) { 3673 return true; 3674 } 3675 3676 return false; 3677 } 3678 handlePromptUnvalidated(Network network)3679 private void handlePromptUnvalidated(Network network) { 3680 if (VDBG || DDBG) log("handlePromptUnvalidated " + network); 3681 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3682 3683 if (nai == null || !shouldPromptUnvalidated(nai)) { 3684 return; 3685 } 3686 3687 // Stop automatically reconnecting to this network in the future. Automatically connecting 3688 // to a network that provides no or limited connectivity is not useful, because the user 3689 // cannot use that network except through the notification shown by this method, and the 3690 // notification is only shown if the network is explicitly selected by the user. 3691 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 3692 3693 // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when 3694 // NetworkMonitor detects the network is partial connectivity. Need to change the design to 3695 // popup the notification immediately when the network is partial connectivity. 3696 if (nai.partialConnectivity) { 3697 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); 3698 } else { 3699 showNetworkNotification(nai, NotificationType.NO_INTERNET); 3700 } 3701 } 3702 handleNetworkUnvalidated(NetworkAgentInfo nai)3703 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 3704 NetworkCapabilities nc = nai.networkCapabilities; 3705 if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc); 3706 3707 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 3708 return; 3709 } 3710 3711 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 3712 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 3713 } 3714 } 3715 3716 @Override getMultipathPreference(Network network)3717 public int getMultipathPreference(Network network) { 3718 enforceAccessPermission(); 3719 3720 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3721 if (nai != null && nai.networkCapabilities 3722 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 3723 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 3724 } 3725 3726 Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network); 3727 if (networkPreference != null) { 3728 return networkPreference; 3729 } 3730 3731 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 3732 } 3733 3734 @Override getDefaultRequest()3735 public NetworkRequest getDefaultRequest() { 3736 return mDefaultRequest; 3737 } 3738 3739 private class InternalHandler extends Handler { InternalHandler(Looper looper)3740 public InternalHandler(Looper looper) { 3741 super(looper); 3742 } 3743 3744 @Override handleMessage(Message msg)3745 public void handleMessage(Message msg) { 3746 switch (msg.what) { 3747 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 3748 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 3749 handleReleaseNetworkTransitionWakelock(msg.what); 3750 break; 3751 } 3752 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 3753 mProxyTracker.loadDeprecatedGlobalHttpProxy(); 3754 break; 3755 } 3756 case EVENT_PROXY_HAS_CHANGED: { 3757 handleApplyDefaultProxy((ProxyInfo)msg.obj); 3758 break; 3759 } 3760 case EVENT_REGISTER_NETWORK_FACTORY: { 3761 handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); 3762 break; 3763 } 3764 case EVENT_UNREGISTER_NETWORK_FACTORY: { 3765 handleUnregisterNetworkFactory((Messenger)msg.obj); 3766 break; 3767 } 3768 case EVENT_REGISTER_NETWORK_AGENT: { 3769 final Pair<NetworkAgentInfo, INetworkMonitor> arg = 3770 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; 3771 handleRegisterNetworkAgent(arg.first, arg.second); 3772 break; 3773 } 3774 case EVENT_REGISTER_NETWORK_REQUEST: 3775 case EVENT_REGISTER_NETWORK_LISTENER: { 3776 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 3777 break; 3778 } 3779 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 3780 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 3781 handleRegisterNetworkRequestWithIntent(msg); 3782 break; 3783 } 3784 case EVENT_TIMEOUT_NETWORK_REQUEST: { 3785 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 3786 handleTimedOutNetworkRequest(nri); 3787 break; 3788 } 3789 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 3790 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 3791 break; 3792 } 3793 case EVENT_RELEASE_NETWORK_REQUEST: { 3794 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1, 3795 /* callOnUnavailable */ false); 3796 break; 3797 } 3798 case EVENT_SET_ACCEPT_UNVALIDATED: { 3799 Network network = (Network) msg.obj; 3800 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 3801 break; 3802 } 3803 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: { 3804 Network network = (Network) msg.obj; 3805 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1), 3806 toBool(msg.arg2)); 3807 break; 3808 } 3809 case EVENT_SET_AVOID_UNVALIDATED: { 3810 handleSetAvoidUnvalidated((Network) msg.obj); 3811 break; 3812 } 3813 case EVENT_PROMPT_UNVALIDATED: { 3814 handlePromptUnvalidated((Network) msg.obj); 3815 break; 3816 } 3817 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { 3818 handleConfigureAlwaysOnNetworks(); 3819 break; 3820 } 3821 // Sent by KeepaliveTracker to process an app request on the state machine thread. 3822 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: { 3823 mKeepaliveTracker.handleStartKeepalive(msg); 3824 break; 3825 } 3826 // Sent by KeepaliveTracker to process an app request on the state machine thread. 3827 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: { 3828 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 3829 int slot = msg.arg1; 3830 int reason = msg.arg2; 3831 mKeepaliveTracker.handleStopKeepalive(nai, slot, reason); 3832 break; 3833 } 3834 case EVENT_SYSTEM_READY: { 3835 mMultipathPolicyTracker.start(); 3836 break; 3837 } 3838 case EVENT_REVALIDATE_NETWORK: { 3839 handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2)); 3840 break; 3841 } 3842 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 3843 handlePrivateDnsSettingsChanged(); 3844 break; 3845 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 3846 handlePrivateDnsValidationUpdate( 3847 (PrivateDnsValidationUpdate) msg.obj); 3848 break; 3849 case EVENT_UID_RULES_CHANGED: 3850 handleUidRulesChanged(msg.arg1, msg.arg2); 3851 break; 3852 case EVENT_DATA_SAVER_CHANGED: 3853 handleRestrictBackgroundChanged(toBool(msg.arg1)); 3854 break; 3855 case EVENT_TIMEOUT_NOTIFICATION: 3856 mNotifier.clearNotification(msg.arg1, NotificationType.LOGGED_IN); 3857 break; 3858 } 3859 } 3860 } 3861 3862 // javadoc from interface 3863 @Override tether(String iface, String callerPkg)3864 public int tether(String iface, String callerPkg) { 3865 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3866 if (isTetheringSupported()) { 3867 return mTethering.tether(iface); 3868 } else { 3869 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3870 } 3871 } 3872 3873 // javadoc from interface 3874 @Override untether(String iface, String callerPkg)3875 public int untether(String iface, String callerPkg) { 3876 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3877 3878 if (isTetheringSupported()) { 3879 return mTethering.untether(iface); 3880 } else { 3881 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3882 } 3883 } 3884 3885 // javadoc from interface 3886 @Override getLastTetherError(String iface)3887 public int getLastTetherError(String iface) { 3888 enforceTetherAccessPermission(); 3889 3890 if (isTetheringSupported()) { 3891 return mTethering.getLastTetherError(iface); 3892 } else { 3893 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3894 } 3895 } 3896 3897 // TODO - proper iface API for selection by property, inspection, etc 3898 @Override getTetherableUsbRegexs()3899 public String[] getTetherableUsbRegexs() { 3900 enforceTetherAccessPermission(); 3901 if (isTetheringSupported()) { 3902 return mTethering.getTetherableUsbRegexs(); 3903 } else { 3904 return new String[0]; 3905 } 3906 } 3907 3908 @Override getTetherableWifiRegexs()3909 public String[] getTetherableWifiRegexs() { 3910 enforceTetherAccessPermission(); 3911 if (isTetheringSupported()) { 3912 return mTethering.getTetherableWifiRegexs(); 3913 } else { 3914 return new String[0]; 3915 } 3916 } 3917 3918 @Override getTetherableBluetoothRegexs()3919 public String[] getTetherableBluetoothRegexs() { 3920 enforceTetherAccessPermission(); 3921 if (isTetheringSupported()) { 3922 return mTethering.getTetherableBluetoothRegexs(); 3923 } else { 3924 return new String[0]; 3925 } 3926 } 3927 3928 @Override setUsbTethering(boolean enable, String callerPkg)3929 public int setUsbTethering(boolean enable, String callerPkg) { 3930 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3931 if (isTetheringSupported()) { 3932 return mTethering.setUsbTethering(enable); 3933 } else { 3934 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3935 } 3936 } 3937 3938 // TODO - move iface listing, queries, etc to new module 3939 // javadoc from interface 3940 @Override getTetherableIfaces()3941 public String[] getTetherableIfaces() { 3942 enforceTetherAccessPermission(); 3943 return mTethering.getTetherableIfaces(); 3944 } 3945 3946 @Override getTetheredIfaces()3947 public String[] getTetheredIfaces() { 3948 enforceTetherAccessPermission(); 3949 return mTethering.getTetheredIfaces(); 3950 } 3951 3952 @Override getTetheringErroredIfaces()3953 public String[] getTetheringErroredIfaces() { 3954 enforceTetherAccessPermission(); 3955 return mTethering.getErroredIfaces(); 3956 } 3957 3958 @Override getTetheredDhcpRanges()3959 public String[] getTetheredDhcpRanges() { 3960 enforceConnectivityInternalPermission(); 3961 return mTethering.getTetheredDhcpRanges(); 3962 } 3963 3964 @Override isTetheringSupported(String callerPkg)3965 public boolean isTetheringSupported(String callerPkg) { 3966 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3967 return isTetheringSupported(); 3968 } 3969 3970 // if ro.tether.denied = true we default to no tethering 3971 // gservices could set the secure setting to 1 though to enable it on a build where it 3972 // had previously been turned off. isTetheringSupported()3973 private boolean isTetheringSupported() { 3974 int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true")); 3975 boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(), 3976 Settings.Global.TETHER_SUPPORTED, defaultVal)); 3977 boolean tetherEnabledInSettings = tetherSupported 3978 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); 3979 3980 // Elevate to system UID to avoid caller requiring MANAGE_USERS permission. 3981 boolean adminUser = false; 3982 final long token = Binder.clearCallingIdentity(); 3983 try { 3984 adminUser = mUserManager.isAdminUser(); 3985 } finally { 3986 Binder.restoreCallingIdentity(token); 3987 } 3988 3989 return tetherEnabledInSettings && adminUser && mTethering.hasTetherableConfiguration(); 3990 } 3991 3992 @Override startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, String callerPkg)3993 public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, 3994 String callerPkg) { 3995 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3996 if (!isTetheringSupported()) { 3997 receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null); 3998 return; 3999 } 4000 mTethering.startTethering(type, receiver, showProvisioningUi); 4001 } 4002 4003 @Override stopTethering(int type, String callerPkg)4004 public void stopTethering(int type, String callerPkg) { 4005 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 4006 mTethering.stopTethering(type); 4007 } 4008 4009 /** 4010 * Get the latest value of the tethering entitlement check. 4011 * 4012 * Note: Allow privileged apps who have TETHER_PRIVILEGED permission to access. If it turns 4013 * out some such apps are observed to abuse this API, change to per-UID limits on this API 4014 * if it's really needed. 4015 */ 4016 @Override getLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi, String callerPkg)4017 public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver, 4018 boolean showEntitlementUi, String callerPkg) { 4019 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 4020 mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi); 4021 } 4022 4023 /** Register tethering event callback. */ 4024 @Override registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg)4025 public void registerTetheringEventCallback(ITetheringEventCallback callback, 4026 String callerPkg) { 4027 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 4028 mTethering.registerTetheringEventCallback(callback); 4029 } 4030 4031 /** Unregister tethering event callback. */ 4032 @Override unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg)4033 public void unregisterTetheringEventCallback(ITetheringEventCallback callback, 4034 String callerPkg) { 4035 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 4036 mTethering.unregisterTetheringEventCallback(callback); 4037 } 4038 4039 // Called when we lose the default network and have no replacement yet. 4040 // This will automatically be cleared after X seconds or a new default network 4041 // becomes CONNECTED, whichever happens first. The timer is started by the 4042 // first caller and not restarted by subsequent callers. ensureNetworkTransitionWakelock(String forWhom)4043 private void ensureNetworkTransitionWakelock(String forWhom) { 4044 synchronized (this) { 4045 if (mNetTransitionWakeLock.isHeld()) { 4046 return; 4047 } 4048 mNetTransitionWakeLock.acquire(); 4049 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 4050 mTotalWakelockAcquisitions++; 4051 } 4052 mWakelockLogs.log("ACQUIRE for " + forWhom); 4053 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 4054 mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout); 4055 } 4056 4057 // Called when we gain a new default network to release the network transition wakelock in a 4058 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 4059 // message is cancelled. scheduleReleaseNetworkTransitionWakelock()4060 private void scheduleReleaseNetworkTransitionWakelock() { 4061 synchronized (this) { 4062 if (!mNetTransitionWakeLock.isHeld()) { 4063 return; // expiry message released the lock first. 4064 } 4065 } 4066 // Cancel self timeout on wakelock hold. 4067 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 4068 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 4069 mHandler.sendMessageDelayed(msg, 1000); 4070 } 4071 4072 // Called when either message of ensureNetworkTransitionWakelock or 4073 // scheduleReleaseNetworkTransitionWakelock is processed. handleReleaseNetworkTransitionWakelock(int eventId)4074 private void handleReleaseNetworkTransitionWakelock(int eventId) { 4075 String event = eventName(eventId); 4076 synchronized (this) { 4077 if (!mNetTransitionWakeLock.isHeld()) { 4078 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 4079 Slog.w(TAG, "expected Net Transition WakeLock to be held"); 4080 return; 4081 } 4082 mNetTransitionWakeLock.release(); 4083 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 4084 mTotalWakelockDurationMs += lockDuration; 4085 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 4086 mTotalWakelockReleases++; 4087 } 4088 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 4089 } 4090 4091 // 100 percent is full good, 0 is full bad. 4092 @Override reportInetCondition(int networkType, int percentage)4093 public void reportInetCondition(int networkType, int percentage) { 4094 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 4095 if (nai == null) return; 4096 reportNetworkConnectivity(nai.network, percentage > 50); 4097 } 4098 4099 @Override reportNetworkConnectivity(Network network, boolean hasConnectivity)4100 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 4101 enforceAccessPermission(); 4102 enforceInternetPermission(); 4103 final int uid = Binder.getCallingUid(); 4104 final int connectivityInfo = encodeBool(hasConnectivity); 4105 mHandler.sendMessage( 4106 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network)); 4107 } 4108 handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)4109 private void handleReportNetworkConnectivity( 4110 Network network, int uid, boolean hasConnectivity) { 4111 final NetworkAgentInfo nai; 4112 if (network == null) { 4113 nai = getDefaultNetwork(); 4114 } else { 4115 nai = getNetworkAgentInfoForNetwork(network); 4116 } 4117 if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING || 4118 nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 4119 return; 4120 } 4121 // Revalidate if the app report does not match our current validated state. 4122 if (hasConnectivity == nai.lastValidated) { 4123 return; 4124 } 4125 if (DBG) { 4126 int netid = nai.network.netId; 4127 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 4128 } 4129 // Validating a network that has not yet connected could result in a call to 4130 // rematchNetworkAndRequests() which is not meant to work on such networks. 4131 if (!nai.everConnected) { 4132 return; 4133 } 4134 LinkProperties lp = getLinkProperties(nai); 4135 if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) { 4136 return; 4137 } 4138 nai.networkMonitor().forceReevaluation(uid); 4139 } 4140 4141 /** 4142 * Returns information about the proxy a certain network is using. If given a null network, it 4143 * it will return the proxy for the bound network for the caller app or the default proxy if 4144 * none. 4145 * 4146 * @param network the network we want to get the proxy information for. 4147 * @return Proxy information if a network has a proxy configured, or otherwise null. 4148 */ 4149 @Override getProxyForNetwork(Network network)4150 public ProxyInfo getProxyForNetwork(Network network) { 4151 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy(); 4152 if (globalProxy != null) return globalProxy; 4153 if (network == null) { 4154 // Get the network associated with the calling UID. 4155 final Network activeNetwork = getActiveNetworkForUidInternal(Binder.getCallingUid(), 4156 true); 4157 if (activeNetwork == null) { 4158 return null; 4159 } 4160 return getLinkPropertiesProxyInfo(activeNetwork); 4161 } else if (queryUserAccess(Binder.getCallingUid(), network.netId)) { 4162 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 4163 // caller may not have. 4164 return getLinkPropertiesProxyInfo(network); 4165 } 4166 // No proxy info available if the calling UID does not have network access. 4167 return null; 4168 } 4169 4170 @VisibleForTesting queryUserAccess(int uid, int netId)4171 protected boolean queryUserAccess(int uid, int netId) { 4172 return NetworkUtils.queryUserAccess(uid, netId); 4173 } 4174 getLinkPropertiesProxyInfo(Network network)4175 private ProxyInfo getLinkPropertiesProxyInfo(Network network) { 4176 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4177 if (nai == null) return null; 4178 synchronized (nai) { 4179 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy(); 4180 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy); 4181 } 4182 } 4183 4184 @Override setGlobalProxy(final ProxyInfo proxyProperties)4185 public void setGlobalProxy(final ProxyInfo proxyProperties) { 4186 enforceConnectivityInternalPermission(); 4187 mProxyTracker.setGlobalProxy(proxyProperties); 4188 } 4189 4190 @Override 4191 @Nullable getGlobalProxy()4192 public ProxyInfo getGlobalProxy() { 4193 return mProxyTracker.getGlobalProxy(); 4194 } 4195 handleApplyDefaultProxy(ProxyInfo proxy)4196 private void handleApplyDefaultProxy(ProxyInfo proxy) { 4197 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 4198 && Uri.EMPTY.equals(proxy.getPacFileUrl())) { 4199 proxy = null; 4200 } 4201 mProxyTracker.setDefaultProxy(proxy); 4202 } 4203 4204 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called 4205 // when any network changes proxy. 4206 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a 4207 // multi-network world where an app might be bound to a non-default network. updateProxy(LinkProperties newLp, LinkProperties oldLp)4208 private void updateProxy(LinkProperties newLp, LinkProperties oldLp) { 4209 ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy(); 4210 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 4211 4212 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 4213 mProxyTracker.sendProxyBroadcast(); 4214 } 4215 } 4216 4217 private static class SettingsObserver extends ContentObserver { 4218 final private HashMap<Uri, Integer> mUriEventMap; 4219 final private Context mContext; 4220 final private Handler mHandler; 4221 SettingsObserver(Context context, Handler handler)4222 SettingsObserver(Context context, Handler handler) { 4223 super(null); 4224 mUriEventMap = new HashMap<>(); 4225 mContext = context; 4226 mHandler = handler; 4227 } 4228 observe(Uri uri, int what)4229 void observe(Uri uri, int what) { 4230 mUriEventMap.put(uri, what); 4231 final ContentResolver resolver = mContext.getContentResolver(); 4232 resolver.registerContentObserver(uri, false, this); 4233 } 4234 4235 @Override onChange(boolean selfChange)4236 public void onChange(boolean selfChange) { 4237 Slog.wtf(TAG, "Should never be reached."); 4238 } 4239 4240 @Override onChange(boolean selfChange, Uri uri)4241 public void onChange(boolean selfChange, Uri uri) { 4242 final Integer what = mUriEventMap.get(uri); 4243 if (what != null) { 4244 mHandler.obtainMessage(what.intValue()).sendToTarget(); 4245 } else { 4246 loge("No matching event to send for URI=" + uri); 4247 } 4248 } 4249 } 4250 log(String s)4251 private static void log(String s) { 4252 Slog.d(TAG, s); 4253 } 4254 loge(String s)4255 private static void loge(String s) { 4256 Slog.e(TAG, s); 4257 } 4258 loge(String s, Throwable t)4259 private static void loge(String s, Throwable t) { 4260 Slog.e(TAG, s, t); 4261 } 4262 4263 /** 4264 * Prepare for a VPN application. 4265 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 4266 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 4267 * 4268 * @param oldPackage Package name of the application which currently controls VPN, which will 4269 * be replaced. If there is no such application, this should should either be 4270 * {@code null} or {@link VpnConfig.LEGACY_VPN}. 4271 * @param newPackage Package name of the application which should gain control of VPN, or 4272 * {@code null} to disable. 4273 * @param userId User for whom to prepare the new VPN. 4274 * 4275 * @hide 4276 */ 4277 @Override prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)4278 public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage, 4279 int userId) { 4280 enforceCrossUserPermission(userId); 4281 4282 synchronized (mVpns) { 4283 throwIfLockdownEnabled(); 4284 Vpn vpn = mVpns.get(userId); 4285 if (vpn != null) { 4286 return vpn.prepare(oldPackage, newPackage); 4287 } else { 4288 return false; 4289 } 4290 } 4291 } 4292 4293 /** 4294 * Set whether the VPN package has the ability to launch VPNs without user intervention. 4295 * This method is used by system-privileged apps. 4296 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 4297 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 4298 * 4299 * @param packageName The package for which authorization state should change. 4300 * @param userId User for whom {@code packageName} is installed. 4301 * @param authorized {@code true} if this app should be able to start a VPN connection without 4302 * explicit user approval, {@code false} if not. 4303 * 4304 * @hide 4305 */ 4306 @Override setVpnPackageAuthorization(String packageName, int userId, boolean authorized)4307 public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) { 4308 enforceCrossUserPermission(userId); 4309 4310 synchronized (mVpns) { 4311 Vpn vpn = mVpns.get(userId); 4312 if (vpn != null) { 4313 vpn.setPackageAuthorization(packageName, authorized); 4314 } 4315 } 4316 } 4317 4318 /** 4319 * Configure a TUN interface and return its file descriptor. Parameters 4320 * are encoded and opaque to this class. This method is used by VpnBuilder 4321 * and not available in ConnectivityManager. Permissions are checked in 4322 * Vpn class. 4323 * @hide 4324 */ 4325 @Override establishVpn(VpnConfig config)4326 public ParcelFileDescriptor establishVpn(VpnConfig config) { 4327 int user = UserHandle.getUserId(Binder.getCallingUid()); 4328 synchronized (mVpns) { 4329 throwIfLockdownEnabled(); 4330 return mVpns.get(user).establish(config); 4331 } 4332 } 4333 4334 /** 4335 * Start legacy VPN, controlling native daemons as needed. Creates a 4336 * secondary thread to perform connection work, returning quickly. 4337 */ 4338 @Override startLegacyVpn(VpnProfile profile)4339 public void startLegacyVpn(VpnProfile profile) { 4340 int user = UserHandle.getUserId(Binder.getCallingUid()); 4341 final LinkProperties egress = getActiveLinkProperties(); 4342 if (egress == null) { 4343 throw new IllegalStateException("Missing active network connection"); 4344 } 4345 synchronized (mVpns) { 4346 throwIfLockdownEnabled(); 4347 mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress); 4348 } 4349 } 4350 4351 /** 4352 * Return the information of the ongoing legacy VPN. This method is used 4353 * by VpnSettings and not available in ConnectivityManager. Permissions 4354 * are checked in Vpn class. 4355 */ 4356 @Override getLegacyVpnInfo(int userId)4357 public LegacyVpnInfo getLegacyVpnInfo(int userId) { 4358 enforceCrossUserPermission(userId); 4359 4360 synchronized (mVpns) { 4361 return mVpns.get(userId).getLegacyVpnInfo(); 4362 } 4363 } 4364 4365 /** 4366 * Return the information of all ongoing VPNs. 4367 * 4368 * <p>This method is used to update NetworkStatsService. 4369 * 4370 * <p>Must be called on the handler thread. 4371 */ getAllVpnInfo()4372 private VpnInfo[] getAllVpnInfo() { 4373 ensureRunningOnConnectivityServiceThread(); 4374 synchronized (mVpns) { 4375 if (mLockdownEnabled) { 4376 return new VpnInfo[0]; 4377 } 4378 4379 List<VpnInfo> infoList = new ArrayList<>(); 4380 for (int i = 0; i < mVpns.size(); i++) { 4381 VpnInfo info = createVpnInfo(mVpns.valueAt(i)); 4382 if (info != null) { 4383 infoList.add(info); 4384 } 4385 } 4386 return infoList.toArray(new VpnInfo[infoList.size()]); 4387 } 4388 } 4389 4390 /** 4391 * @return VPN information for accounting, or null if we can't retrieve all required 4392 * information, e.g primary underlying iface. 4393 */ 4394 @Nullable createVpnInfo(Vpn vpn)4395 private VpnInfo createVpnInfo(Vpn vpn) { 4396 VpnInfo info = vpn.getVpnInfo(); 4397 if (info == null) { 4398 return null; 4399 } 4400 Network[] underlyingNetworks = vpn.getUnderlyingNetworks(); 4401 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 4402 // the underlyingNetworks list. 4403 if (underlyingNetworks == null) { 4404 NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 4405 if (defaultNetwork != null && defaultNetwork.linkProperties != null) { 4406 info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName(); 4407 } 4408 } else if (underlyingNetworks.length > 0) { 4409 LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]); 4410 if (linkProperties != null) { 4411 info.primaryUnderlyingIface = linkProperties.getInterfaceName(); 4412 } 4413 } 4414 return info.primaryUnderlyingIface == null ? null : info; 4415 } 4416 4417 /** 4418 * Returns the information of the ongoing VPN for {@code userId}. This method is used by 4419 * VpnDialogs and not available in ConnectivityManager. 4420 * Permissions are checked in Vpn class. 4421 * @hide 4422 */ 4423 @Override getVpnConfig(int userId)4424 public VpnConfig getVpnConfig(int userId) { 4425 enforceCrossUserPermission(userId); 4426 synchronized (mVpns) { 4427 Vpn vpn = mVpns.get(userId); 4428 if (vpn != null) { 4429 return vpn.getVpnConfig(); 4430 } else { 4431 return null; 4432 } 4433 } 4434 } 4435 4436 /** 4437 * Ask all VPN objects to recompute and update their capabilities. 4438 * 4439 * When underlying networks change, VPNs may have to update capabilities to reflect things 4440 * like the metered bit, their transports, and so on. This asks the VPN objects to update 4441 * their capabilities, and as this will cause them to send messages to the ConnectivityService 4442 * handler thread through their agent, this is asynchronous. When the capabilities objects 4443 * are computed they will be up-to-date as they are computed synchronously from here and 4444 * this is running on the ConnectivityService thread. 4445 */ updateAllVpnsCapabilities()4446 private void updateAllVpnsCapabilities() { 4447 Network defaultNetwork = getNetwork(getDefaultNetwork()); 4448 synchronized (mVpns) { 4449 for (int i = 0; i < mVpns.size(); i++) { 4450 final Vpn vpn = mVpns.valueAt(i); 4451 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); 4452 updateVpnCapabilities(vpn, nc); 4453 } 4454 } 4455 } 4456 updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc)4457 private void updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc) { 4458 ensureRunningOnConnectivityServiceThread(); 4459 NetworkAgentInfo vpnNai = getNetworkAgentInfoForNetId(vpn.getNetId()); 4460 if (vpnNai == null || nc == null) { 4461 return; 4462 } 4463 updateCapabilities(vpnNai.getCurrentScore(), vpnNai, nc); 4464 } 4465 4466 @Override updateLockdownVpn()4467 public boolean updateLockdownVpn() { 4468 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 4469 Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM"); 4470 return false; 4471 } 4472 4473 synchronized (mVpns) { 4474 // Tear down existing lockdown if profile was removed 4475 mLockdownEnabled = LockdownVpnTracker.isEnabled(); 4476 if (mLockdownEnabled) { 4477 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN); 4478 if (profileTag == null) { 4479 Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore"); 4480 return false; 4481 } 4482 String profileName = new String(profileTag); 4483 final VpnProfile profile = VpnProfile.decode( 4484 profileName, mKeyStore.get(Credentials.VPN + profileName)); 4485 if (profile == null) { 4486 Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName); 4487 setLockdownTracker(null); 4488 return true; 4489 } 4490 int user = UserHandle.getUserId(Binder.getCallingUid()); 4491 Vpn vpn = mVpns.get(user); 4492 if (vpn == null) { 4493 Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown"); 4494 return false; 4495 } 4496 setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile)); 4497 } else { 4498 setLockdownTracker(null); 4499 } 4500 } 4501 4502 return true; 4503 } 4504 4505 /** 4506 * Internally set new {@link LockdownVpnTracker}, shutting down any existing 4507 * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown. 4508 */ 4509 @GuardedBy("mVpns") setLockdownTracker(LockdownVpnTracker tracker)4510 private void setLockdownTracker(LockdownVpnTracker tracker) { 4511 // Shutdown any existing tracker 4512 final LockdownVpnTracker existing = mLockdownTracker; 4513 // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the 4514 // necessary onBlockedStatusChanged callbacks. 4515 mLockdownTracker = null; 4516 if (existing != null) { 4517 existing.shutdown(); 4518 } 4519 4520 if (tracker != null) { 4521 mLockdownTracker = tracker; 4522 mLockdownTracker.init(); 4523 } 4524 } 4525 4526 @GuardedBy("mVpns") throwIfLockdownEnabled()4527 private void throwIfLockdownEnabled() { 4528 if (mLockdownEnabled) { 4529 throw new IllegalStateException("Unavailable in lockdown mode"); 4530 } 4531 } 4532 4533 /** 4534 * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform 4535 * some setup and then call {@code establish()} to connect. 4536 * 4537 * @return {@code true} if the service was started, the service was already connected, or there 4538 * was no always-on VPN to start. {@code false} otherwise. 4539 */ startAlwaysOnVpn(int userId)4540 private boolean startAlwaysOnVpn(int userId) { 4541 synchronized (mVpns) { 4542 Vpn vpn = mVpns.get(userId); 4543 if (vpn == null) { 4544 // Shouldn't happen as all code paths that point here should have checked the Vpn 4545 // exists already. 4546 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration"); 4547 return false; 4548 } 4549 4550 return vpn.startAlwaysOnVpn(); 4551 } 4552 } 4553 4554 @Override isAlwaysOnVpnPackageSupported(int userId, String packageName)4555 public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) { 4556 enforceSettingsPermission(); 4557 enforceCrossUserPermission(userId); 4558 4559 synchronized (mVpns) { 4560 Vpn vpn = mVpns.get(userId); 4561 if (vpn == null) { 4562 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 4563 return false; 4564 } 4565 return vpn.isAlwaysOnPackageSupported(packageName); 4566 } 4567 } 4568 4569 @Override setAlwaysOnVpnPackage( int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist)4570 public boolean setAlwaysOnVpnPackage( 4571 int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist) { 4572 enforceControlAlwaysOnVpnPermission(); 4573 enforceCrossUserPermission(userId); 4574 4575 synchronized (mVpns) { 4576 // Can't set always-on VPN if legacy VPN is already in lockdown mode. 4577 if (LockdownVpnTracker.isEnabled()) { 4578 return false; 4579 } 4580 4581 Vpn vpn = mVpns.get(userId); 4582 if (vpn == null) { 4583 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 4584 return false; 4585 } 4586 if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownWhitelist)) { 4587 return false; 4588 } 4589 if (!startAlwaysOnVpn(userId)) { 4590 vpn.setAlwaysOnPackage(null, false, null); 4591 return false; 4592 } 4593 } 4594 return true; 4595 } 4596 4597 @Override getAlwaysOnVpnPackage(int userId)4598 public String getAlwaysOnVpnPackage(int userId) { 4599 enforceControlAlwaysOnVpnPermission(); 4600 enforceCrossUserPermission(userId); 4601 4602 synchronized (mVpns) { 4603 Vpn vpn = mVpns.get(userId); 4604 if (vpn == null) { 4605 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 4606 return null; 4607 } 4608 return vpn.getAlwaysOnPackage(); 4609 } 4610 } 4611 4612 @Override isVpnLockdownEnabled(int userId)4613 public boolean isVpnLockdownEnabled(int userId) { 4614 enforceControlAlwaysOnVpnPermission(); 4615 enforceCrossUserPermission(userId); 4616 4617 synchronized (mVpns) { 4618 Vpn vpn = mVpns.get(userId); 4619 if (vpn == null) { 4620 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 4621 return false; 4622 } 4623 return vpn.getLockdown(); 4624 } 4625 } 4626 4627 @Override getVpnLockdownWhitelist(int userId)4628 public List<String> getVpnLockdownWhitelist(int userId) { 4629 enforceControlAlwaysOnVpnPermission(); 4630 enforceCrossUserPermission(userId); 4631 4632 synchronized (mVpns) { 4633 Vpn vpn = mVpns.get(userId); 4634 if (vpn == null) { 4635 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 4636 return null; 4637 } 4638 return vpn.getLockdownWhitelist(); 4639 } 4640 } 4641 4642 @Override checkMobileProvisioning(int suggestedTimeOutMs)4643 public int checkMobileProvisioning(int suggestedTimeOutMs) { 4644 // TODO: Remove? Any reason to trigger a provisioning check? 4645 return -1; 4646 } 4647 4648 /** Location to an updatable file listing carrier provisioning urls. 4649 * An example: 4650 * 4651 * <?xml version="1.0" encoding="utf-8"?> 4652 * <provisioningUrls> 4653 * <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl> 4654 * </provisioningUrls> 4655 */ 4656 private static final String PROVISIONING_URL_PATH = 4657 "/data/misc/radio/provisioning_urls.xml"; 4658 private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH); 4659 4660 /** XML tag for root element. */ 4661 private static final String TAG_PROVISIONING_URLS = "provisioningUrls"; 4662 /** XML tag for individual url */ 4663 private static final String TAG_PROVISIONING_URL = "provisioningUrl"; 4664 /** XML attribute for mcc */ 4665 private static final String ATTR_MCC = "mcc"; 4666 /** XML attribute for mnc */ 4667 private static final String ATTR_MNC = "mnc"; 4668 getProvisioningUrlBaseFromFile()4669 private String getProvisioningUrlBaseFromFile() { 4670 FileReader fileReader = null; 4671 XmlPullParser parser = null; 4672 Configuration config = mContext.getResources().getConfiguration(); 4673 4674 try { 4675 fileReader = new FileReader(mProvisioningUrlFile); 4676 parser = Xml.newPullParser(); 4677 parser.setInput(fileReader); 4678 XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS); 4679 4680 while (true) { 4681 XmlUtils.nextElement(parser); 4682 4683 String element = parser.getName(); 4684 if (element == null) break; 4685 4686 if (element.equals(TAG_PROVISIONING_URL)) { 4687 String mcc = parser.getAttributeValue(null, ATTR_MCC); 4688 try { 4689 if (mcc != null && Integer.parseInt(mcc) == config.mcc) { 4690 String mnc = parser.getAttributeValue(null, ATTR_MNC); 4691 if (mnc != null && Integer.parseInt(mnc) == config.mnc) { 4692 parser.next(); 4693 if (parser.getEventType() == XmlPullParser.TEXT) { 4694 return parser.getText(); 4695 } 4696 } 4697 } 4698 } catch (NumberFormatException e) { 4699 loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e); 4700 } 4701 } 4702 } 4703 return null; 4704 } catch (FileNotFoundException e) { 4705 loge("Carrier Provisioning Urls file not found"); 4706 } catch (XmlPullParserException e) { 4707 loge("Xml parser exception reading Carrier Provisioning Urls file: " + e); 4708 } catch (IOException e) { 4709 loge("I/O exception reading Carrier Provisioning Urls file: " + e); 4710 } finally { 4711 if (fileReader != null) { 4712 try { 4713 fileReader.close(); 4714 } catch (IOException e) {} 4715 } 4716 } 4717 return null; 4718 } 4719 4720 @Override getMobileProvisioningUrl()4721 public String getMobileProvisioningUrl() { 4722 enforceConnectivityInternalPermission(); 4723 String url = getProvisioningUrlBaseFromFile(); 4724 if (TextUtils.isEmpty(url)) { 4725 url = mContext.getResources().getString(R.string.mobile_provisioning_url); 4726 log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url); 4727 } else { 4728 log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url); 4729 } 4730 // populate the iccid, imei and phone number in the provisioning url. 4731 if (!TextUtils.isEmpty(url)) { 4732 String phoneNumber = mTelephonyManager.getLine1Number(); 4733 if (TextUtils.isEmpty(phoneNumber)) { 4734 phoneNumber = "0000000000"; 4735 } 4736 url = String.format(url, 4737 mTelephonyManager.getSimSerialNumber() /* ICCID */, 4738 mTelephonyManager.getDeviceId() /* IMEI */, 4739 phoneNumber /* Phone number */); 4740 } 4741 4742 return url; 4743 } 4744 4745 @Override setProvisioningNotificationVisible(boolean visible, int networkType, String action)4746 public void setProvisioningNotificationVisible(boolean visible, int networkType, 4747 String action) { 4748 enforceConnectivityInternalPermission(); 4749 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 4750 return; 4751 } 4752 final long ident = Binder.clearCallingIdentity(); 4753 try { 4754 // Concatenate the range of types onto the range of NetIDs. 4755 int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 4756 mNotifier.setProvNotificationVisible(visible, id, action); 4757 } finally { 4758 Binder.restoreCallingIdentity(ident); 4759 } 4760 } 4761 4762 @Override setAirplaneMode(boolean enable)4763 public void setAirplaneMode(boolean enable) { 4764 enforceNetworkStackSettingsOrSetup(); 4765 final long ident = Binder.clearCallingIdentity(); 4766 try { 4767 final ContentResolver cr = mContext.getContentResolver(); 4768 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 4769 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 4770 intent.putExtra("state", enable); 4771 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 4772 } finally { 4773 Binder.restoreCallingIdentity(ident); 4774 } 4775 } 4776 onUserStart(int userId)4777 private void onUserStart(int userId) { 4778 synchronized (mVpns) { 4779 Vpn userVpn = mVpns.get(userId); 4780 if (userVpn != null) { 4781 loge("Starting user already has a VPN"); 4782 return; 4783 } 4784 userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId); 4785 mVpns.put(userId, userVpn); 4786 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 4787 updateLockdownVpn(); 4788 } 4789 } 4790 } 4791 onUserStop(int userId)4792 private void onUserStop(int userId) { 4793 synchronized (mVpns) { 4794 Vpn userVpn = mVpns.get(userId); 4795 if (userVpn == null) { 4796 loge("Stopped user has no VPN"); 4797 return; 4798 } 4799 userVpn.onUserStopped(); 4800 mVpns.delete(userId); 4801 } 4802 } 4803 onUserAdded(int userId)4804 private void onUserAdded(int userId) { 4805 mPermissionMonitor.onUserAdded(userId); 4806 Network defaultNetwork = getNetwork(getDefaultNetwork()); 4807 synchronized (mVpns) { 4808 final int vpnsSize = mVpns.size(); 4809 for (int i = 0; i < vpnsSize; i++) { 4810 Vpn vpn = mVpns.valueAt(i); 4811 vpn.onUserAdded(userId); 4812 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); 4813 updateVpnCapabilities(vpn, nc); 4814 } 4815 } 4816 } 4817 onUserRemoved(int userId)4818 private void onUserRemoved(int userId) { 4819 mPermissionMonitor.onUserRemoved(userId); 4820 Network defaultNetwork = getNetwork(getDefaultNetwork()); 4821 synchronized (mVpns) { 4822 final int vpnsSize = mVpns.size(); 4823 for (int i = 0; i < vpnsSize; i++) { 4824 Vpn vpn = mVpns.valueAt(i); 4825 vpn.onUserRemoved(userId); 4826 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); 4827 updateVpnCapabilities(vpn, nc); 4828 } 4829 } 4830 } 4831 onPackageAdded(String packageName, int uid)4832 private void onPackageAdded(String packageName, int uid) { 4833 if (TextUtils.isEmpty(packageName) || uid < 0) { 4834 Slog.wtf(TAG, "Invalid package in onPackageAdded: " + packageName + " | " + uid); 4835 return; 4836 } 4837 mPermissionMonitor.onPackageAdded(packageName, uid); 4838 } 4839 onPackageReplaced(String packageName, int uid)4840 private void onPackageReplaced(String packageName, int uid) { 4841 if (TextUtils.isEmpty(packageName) || uid < 0) { 4842 Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid); 4843 return; 4844 } 4845 final int userId = UserHandle.getUserId(uid); 4846 synchronized (mVpns) { 4847 final Vpn vpn = mVpns.get(userId); 4848 if (vpn == null) { 4849 return; 4850 } 4851 // Legacy always-on VPN won't be affected since the package name is not set. 4852 if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) { 4853 Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user " 4854 + userId); 4855 vpn.startAlwaysOnVpn(); 4856 } 4857 } 4858 } 4859 onPackageRemoved(String packageName, int uid, boolean isReplacing)4860 private void onPackageRemoved(String packageName, int uid, boolean isReplacing) { 4861 if (TextUtils.isEmpty(packageName) || uid < 0) { 4862 Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid); 4863 return; 4864 } 4865 mPermissionMonitor.onPackageRemoved(uid); 4866 4867 final int userId = UserHandle.getUserId(uid); 4868 synchronized (mVpns) { 4869 final Vpn vpn = mVpns.get(userId); 4870 if (vpn == null) { 4871 return; 4872 } 4873 // Legacy always-on VPN won't be affected since the package name is not set. 4874 if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) { 4875 Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user " 4876 + userId); 4877 vpn.setAlwaysOnPackage(null, false, null); 4878 } 4879 } 4880 } 4881 onUserUnlocked(int userId)4882 private void onUserUnlocked(int userId) { 4883 synchronized (mVpns) { 4884 // User present may be sent because of an unlock, which might mean an unlocked keystore. 4885 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 4886 updateLockdownVpn(); 4887 } else { 4888 startAlwaysOnVpn(userId); 4889 } 4890 } 4891 } 4892 4893 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 4894 @Override 4895 public void onReceive(Context context, Intent intent) { 4896 ensureRunningOnConnectivityServiceThread(); 4897 final String action = intent.getAction(); 4898 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 4899 final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 4900 final Uri packageData = intent.getData(); 4901 final String packageName = 4902 packageData != null ? packageData.getSchemeSpecificPart() : null; 4903 if (userId == UserHandle.USER_NULL) return; 4904 4905 if (Intent.ACTION_USER_STARTED.equals(action)) { 4906 onUserStart(userId); 4907 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 4908 onUserStop(userId); 4909 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 4910 onUserAdded(userId); 4911 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 4912 onUserRemoved(userId); 4913 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { 4914 onUserUnlocked(userId); 4915 } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 4916 onPackageAdded(packageName, uid); 4917 } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 4918 onPackageReplaced(packageName, uid); 4919 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 4920 final boolean isReplacing = intent.getBooleanExtra( 4921 Intent.EXTRA_REPLACING, false); 4922 onPackageRemoved(packageName, uid, isReplacing); 4923 } 4924 } 4925 }; 4926 4927 private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() { 4928 @Override 4929 public void onReceive(Context context, Intent intent) { 4930 // Try creating lockdown tracker, since user present usually means 4931 // unlocked keystore. 4932 updateLockdownVpn(); 4933 mContext.unregisterReceiver(this); 4934 } 4935 }; 4936 4937 private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = new HashMap<>(); 4938 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); 4939 4940 private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 4941 // Map from UID to number of NetworkRequests that UID has filed. 4942 @GuardedBy("mUidToNetworkRequestCount") 4943 private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); 4944 4945 private static class NetworkFactoryInfo { 4946 public final String name; 4947 public final Messenger messenger; 4948 public final AsyncChannel asyncChannel; 4949 public final int factorySerialNumber; 4950 NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, int factorySerialNumber)4951 NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, 4952 int factorySerialNumber) { 4953 this.name = name; 4954 this.messenger = messenger; 4955 this.asyncChannel = asyncChannel; 4956 this.factorySerialNumber = factorySerialNumber; 4957 } 4958 } 4959 ensureNetworkRequestHasType(NetworkRequest request)4960 private void ensureNetworkRequestHasType(NetworkRequest request) { 4961 if (request.type == NetworkRequest.Type.NONE) { 4962 throw new IllegalArgumentException( 4963 "All NetworkRequests in ConnectivityService must have a type"); 4964 } 4965 } 4966 4967 /** 4968 * Tracks info about the requester. 4969 * Also used to notice when the calling process dies so we can self-expire 4970 */ 4971 private class NetworkRequestInfo implements IBinder.DeathRecipient { 4972 final NetworkRequest request; 4973 final PendingIntent mPendingIntent; 4974 boolean mPendingIntentSent; 4975 private final IBinder mBinder; 4976 final int mPid; 4977 final int mUid; 4978 final Messenger messenger; 4979 NetworkRequestInfo(NetworkRequest r, PendingIntent pi)4980 NetworkRequestInfo(NetworkRequest r, PendingIntent pi) { 4981 request = r; 4982 ensureNetworkRequestHasType(request); 4983 mPendingIntent = pi; 4984 messenger = null; 4985 mBinder = null; 4986 mPid = getCallingPid(); 4987 mUid = getCallingUid(); 4988 enforceRequestCountLimit(); 4989 } 4990 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder)4991 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) { 4992 super(); 4993 messenger = m; 4994 request = r; 4995 ensureNetworkRequestHasType(request); 4996 mBinder = binder; 4997 mPid = getCallingPid(); 4998 mUid = getCallingUid(); 4999 mPendingIntent = null; 5000 enforceRequestCountLimit(); 5001 5002 try { 5003 mBinder.linkToDeath(this, 0); 5004 } catch (RemoteException e) { 5005 binderDied(); 5006 } 5007 } 5008 enforceRequestCountLimit()5009 private void enforceRequestCountLimit() { 5010 synchronized (mUidToNetworkRequestCount) { 5011 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1; 5012 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) { 5013 throw new ServiceSpecificException( 5014 ConnectivityManager.Errors.TOO_MANY_REQUESTS); 5015 } 5016 mUidToNetworkRequestCount.put(mUid, networkRequests); 5017 } 5018 } 5019 unlinkDeathRecipient()5020 void unlinkDeathRecipient() { 5021 if (mBinder != null) { 5022 mBinder.unlinkToDeath(this, 0); 5023 } 5024 } 5025 binderDied()5026 public void binderDied() { 5027 log("ConnectivityService NetworkRequestInfo binderDied(" + 5028 request + ", " + mBinder + ")"); 5029 releaseNetworkRequest(request); 5030 } 5031 toString()5032 public String toString() { 5033 return "uid/pid:" + mUid + "/" + mPid + " " + request + 5034 (mPendingIntent == null ? "" : " to trigger " + mPendingIntent); 5035 } 5036 } 5037 ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)5038 private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) { 5039 final String badCapability = networkCapabilities.describeFirstNonRequestableCapability(); 5040 if (badCapability != null) { 5041 throw new IllegalArgumentException("Cannot request network with " + badCapability); 5042 } 5043 } 5044 5045 // This checks that the passed capabilities either do not request a specific SSID/SignalStrength 5046 // , or the calling app has permission to do so. ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid)5047 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 5048 int callerPid, int callerUid) { 5049 if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { 5050 throw new SecurityException("Insufficient permissions to request a specific SSID"); 5051 } 5052 5053 if (nc.hasSignalStrength() 5054 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { 5055 throw new SecurityException( 5056 "Insufficient permissions to request a specific signal strength"); 5057 } 5058 } 5059 getSignalStrengthThresholds(NetworkAgentInfo nai)5060 private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { 5061 final SortedSet<Integer> thresholds = new TreeSet<>(); 5062 synchronized (nai) { 5063 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5064 if (nri.request.networkCapabilities.hasSignalStrength() && 5065 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 5066 thresholds.add(nri.request.networkCapabilities.getSignalStrength()); 5067 } 5068 } 5069 } 5070 return new ArrayList<>(thresholds); 5071 } 5072 updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)5073 private void updateSignalStrengthThresholds( 5074 NetworkAgentInfo nai, String reason, NetworkRequest request) { 5075 ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai); 5076 Bundle thresholds = new Bundle(); 5077 thresholds.putIntegerArrayList("thresholds", thresholdsArray); 5078 5079 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 5080 String detail; 5081 if (request != null && request.networkCapabilities.hasSignalStrength()) { 5082 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 5083 } else { 5084 detail = reason; 5085 } 5086 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 5087 detail, Arrays.toString(thresholdsArray.toArray()), nai.name())); 5088 } 5089 5090 nai.asyncChannel.sendMessage( 5091 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, 5092 0, 0, thresholds); 5093 } 5094 ensureValidNetworkSpecifier(NetworkCapabilities nc)5095 private void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 5096 if (nc == null) { 5097 return; 5098 } 5099 NetworkSpecifier ns = nc.getNetworkSpecifier(); 5100 if (ns == null) { 5101 return; 5102 } 5103 MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns); 5104 ns.assertValidFromUid(Binder.getCallingUid()); 5105 } 5106 5107 @Override requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType)5108 public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, 5109 Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { 5110 final NetworkRequest.Type type = (networkCapabilities == null) 5111 ? NetworkRequest.Type.TRACK_DEFAULT 5112 : NetworkRequest.Type.REQUEST; 5113 // If the requested networkCapabilities is null, take them instead from 5114 // the default network request. This allows callers to keep track of 5115 // the system default network. 5116 if (type == NetworkRequest.Type.TRACK_DEFAULT) { 5117 networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid()); 5118 enforceAccessPermission(); 5119 } else { 5120 networkCapabilities = new NetworkCapabilities(networkCapabilities); 5121 enforceNetworkRequestPermissions(networkCapabilities); 5122 // TODO: this is incorrect. We mark the request as metered or not depending on the state 5123 // of the app when the request is filed, but we never change the request if the app 5124 // changes network state. http://b/29964605 5125 enforceMeteredApnPolicy(networkCapabilities); 5126 } 5127 ensureRequestableCapabilities(networkCapabilities); 5128 ensureSufficientPermissionsForRequest(networkCapabilities, 5129 Binder.getCallingPid(), Binder.getCallingUid()); 5130 // Set the UID range for this request to the single UID of the requester, or to an empty 5131 // set of UIDs if the caller has the appropriate permission and UIDs have not been set. 5132 // This will overwrite any allowed UIDs in the requested capabilities. Though there 5133 // are no visible methods to set the UIDs, an app could use reflection to try and get 5134 // networks for other apps so it's essential that the UIDs are overwritten. 5135 restrictRequestUidsForCaller(networkCapabilities); 5136 5137 if (timeoutMs < 0) { 5138 throw new IllegalArgumentException("Bad timeout specified"); 5139 } 5140 ensureValidNetworkSpecifier(networkCapabilities); 5141 5142 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 5143 nextNetworkRequestId(), type); 5144 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 5145 if (DBG) log("requestNetwork for " + nri); 5146 5147 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); 5148 if (timeoutMs > 0) { 5149 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 5150 nri), timeoutMs); 5151 } 5152 return networkRequest; 5153 } 5154 enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities)5155 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { 5156 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { 5157 enforceConnectivityRestrictedNetworksPermission(); 5158 } else { 5159 enforceChangePermission(); 5160 } 5161 } 5162 5163 @Override requestBandwidthUpdate(Network network)5164 public boolean requestBandwidthUpdate(Network network) { 5165 enforceAccessPermission(); 5166 NetworkAgentInfo nai = null; 5167 if (network == null) { 5168 return false; 5169 } 5170 synchronized (mNetworkForNetId) { 5171 nai = mNetworkForNetId.get(network.netId); 5172 } 5173 if (nai != null) { 5174 nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE); 5175 synchronized (mBandwidthRequests) { 5176 final int uid = Binder.getCallingUid(); 5177 Integer uidReqs = mBandwidthRequests.get(uid); 5178 if (uidReqs == null) { 5179 uidReqs = new Integer(0); 5180 } 5181 mBandwidthRequests.put(uid, ++uidReqs); 5182 } 5183 return true; 5184 } 5185 return false; 5186 } 5187 isSystem(int uid)5188 private boolean isSystem(int uid) { 5189 return uid < Process.FIRST_APPLICATION_UID; 5190 } 5191 enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)5192 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 5193 final int uid = Binder.getCallingUid(); 5194 if (isSystem(uid)) { 5195 // Exemption for system uid. 5196 return; 5197 } 5198 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 5199 // Policy already enforced. 5200 return; 5201 } 5202 if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) { 5203 // If UID is restricted, don't allow them to bring up metered APNs. 5204 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 5205 } 5206 } 5207 5208 @Override pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)5209 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 5210 PendingIntent operation) { 5211 checkNotNull(operation, "PendingIntent cannot be null."); 5212 networkCapabilities = new NetworkCapabilities(networkCapabilities); 5213 enforceNetworkRequestPermissions(networkCapabilities); 5214 enforceMeteredApnPolicy(networkCapabilities); 5215 ensureRequestableCapabilities(networkCapabilities); 5216 ensureSufficientPermissionsForRequest(networkCapabilities, 5217 Binder.getCallingPid(), Binder.getCallingUid()); 5218 ensureValidNetworkSpecifier(networkCapabilities); 5219 restrictRequestUidsForCaller(networkCapabilities); 5220 5221 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 5222 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 5223 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 5224 if (DBG) log("pendingRequest for " + nri); 5225 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, 5226 nri)); 5227 return networkRequest; 5228 } 5229 releasePendingNetworkRequestWithDelay(PendingIntent operation)5230 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 5231 mHandler.sendMessageDelayed( 5232 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 5233 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 5234 } 5235 5236 @Override releasePendingNetworkRequest(PendingIntent operation)5237 public void releasePendingNetworkRequest(PendingIntent operation) { 5238 checkNotNull(operation, "PendingIntent cannot be null."); 5239 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 5240 getCallingUid(), 0, operation)); 5241 } 5242 5243 // In order to implement the compatibility measure for pre-M apps that call 5244 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 5245 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 5246 // This ensures it has permission to do so. hasWifiNetworkListenPermission(NetworkCapabilities nc)5247 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 5248 if (nc == null) { 5249 return false; 5250 } 5251 int[] transportTypes = nc.getTransportTypes(); 5252 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 5253 return false; 5254 } 5255 try { 5256 mContext.enforceCallingOrSelfPermission( 5257 android.Manifest.permission.ACCESS_WIFI_STATE, 5258 "ConnectivityService"); 5259 } catch (SecurityException e) { 5260 return false; 5261 } 5262 return true; 5263 } 5264 5265 @Override listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder)5266 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 5267 Messenger messenger, IBinder binder) { 5268 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 5269 enforceAccessPermission(); 5270 } 5271 5272 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 5273 ensureSufficientPermissionsForRequest(networkCapabilities, 5274 Binder.getCallingPid(), Binder.getCallingUid()); 5275 restrictRequestUidsForCaller(nc); 5276 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 5277 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 5278 // onLost and onAvailable callbacks when networks move in and out of the background. 5279 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 5280 // can't request networks. 5281 restrictBackgroundRequestForCaller(nc); 5282 ensureValidNetworkSpecifier(nc); 5283 5284 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 5285 NetworkRequest.Type.LISTEN); 5286 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 5287 if (VDBG) log("listenForNetwork for " + nri); 5288 5289 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 5290 return networkRequest; 5291 } 5292 5293 @Override pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)5294 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 5295 PendingIntent operation) { 5296 checkNotNull(operation, "PendingIntent cannot be null."); 5297 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 5298 enforceAccessPermission(); 5299 } 5300 ensureValidNetworkSpecifier(networkCapabilities); 5301 ensureSufficientPermissionsForRequest(networkCapabilities, 5302 Binder.getCallingPid(), Binder.getCallingUid()); 5303 5304 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 5305 restrictRequestUidsForCaller(nc); 5306 5307 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 5308 NetworkRequest.Type.LISTEN); 5309 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 5310 if (VDBG) log("pendingListenForNetwork for " + nri); 5311 5312 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 5313 } 5314 5315 @Override releaseNetworkRequest(NetworkRequest networkRequest)5316 public void releaseNetworkRequest(NetworkRequest networkRequest) { 5317 ensureNetworkRequestHasType(networkRequest); 5318 mHandler.sendMessage(mHandler.obtainMessage( 5319 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest)); 5320 } 5321 5322 @Override registerNetworkFactory(Messenger messenger, String name)5323 public int registerNetworkFactory(Messenger messenger, String name) { 5324 enforceConnectivityInternalPermission(); 5325 NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(), 5326 NetworkFactory.SerialNumber.nextSerialNumber()); 5327 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); 5328 return nfi.factorySerialNumber; 5329 } 5330 handleRegisterNetworkFactory(NetworkFactoryInfo nfi)5331 private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { 5332 if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); 5333 mNetworkFactoryInfos.put(nfi.messenger, nfi); 5334 nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); 5335 } 5336 5337 @Override unregisterNetworkFactory(Messenger messenger)5338 public void unregisterNetworkFactory(Messenger messenger) { 5339 enforceConnectivityInternalPermission(); 5340 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); 5341 } 5342 handleUnregisterNetworkFactory(Messenger messenger)5343 private void handleUnregisterNetworkFactory(Messenger messenger) { 5344 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); 5345 if (nfi == null) { 5346 loge("Failed to find Messenger in unregisterNetworkFactory"); 5347 return; 5348 } 5349 if (DBG) log("unregisterNetworkFactory for " + nfi.name); 5350 } 5351 5352 /** 5353 * NetworkAgentInfo supporting a request by requestId. 5354 * These have already been vetted (their Capabilities satisfy the request) 5355 * and the are the highest scored network available. 5356 * the are keyed off the Requests requestId. 5357 */ 5358 // NOTE: Accessed on multiple threads, must be synchronized on itself. 5359 @GuardedBy("mNetworkForRequestId") 5360 private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>(); 5361 5362 // NOTE: Accessed on multiple threads, must be synchronized on itself. 5363 @GuardedBy("mNetworkForNetId") 5364 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); 5365 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 5366 // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so 5367 // there may not be a strict 1:1 correlation between the two. 5368 @GuardedBy("mNetworkForNetId") 5369 private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); 5370 5371 // NetworkAgentInfo keyed off its connecting messenger 5372 // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays 5373 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 5374 private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = new HashMap<>(); 5375 5376 @GuardedBy("mBlockedAppUids") 5377 private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 5378 5379 // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated. 5380 private final NetworkRequest mDefaultRequest; 5381 5382 // Request used to optionally keep mobile data active even when higher 5383 // priority networks like Wi-Fi are active. 5384 private final NetworkRequest mDefaultMobileDataRequest; 5385 5386 // Request used to optionally keep wifi data active even when higher 5387 // priority networks like ethernet are active. 5388 private final NetworkRequest mDefaultWifiRequest; 5389 getNetworkForRequest(int requestId)5390 private NetworkAgentInfo getNetworkForRequest(int requestId) { 5391 synchronized (mNetworkForRequestId) { 5392 return mNetworkForRequestId.get(requestId); 5393 } 5394 } 5395 clearNetworkForRequest(int requestId)5396 private void clearNetworkForRequest(int requestId) { 5397 synchronized (mNetworkForRequestId) { 5398 mNetworkForRequestId.remove(requestId); 5399 } 5400 } 5401 setNetworkForRequest(int requestId, NetworkAgentInfo nai)5402 private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) { 5403 synchronized (mNetworkForRequestId) { 5404 mNetworkForRequestId.put(requestId, nai); 5405 } 5406 } 5407 getDefaultNetwork()5408 private NetworkAgentInfo getDefaultNetwork() { 5409 return getNetworkForRequest(mDefaultRequest.requestId); 5410 } 5411 5412 @Nullable getNetwork(@ullable NetworkAgentInfo nai)5413 private Network getNetwork(@Nullable NetworkAgentInfo nai) { 5414 return nai != null ? nai.network : null; 5415 } 5416 ensureRunningOnConnectivityServiceThread()5417 private void ensureRunningOnConnectivityServiceThread() { 5418 if (mHandler.getLooper().getThread() != Thread.currentThread()) { 5419 throw new IllegalStateException( 5420 "Not running on ConnectivityService thread: " 5421 + Thread.currentThread().getName()); 5422 } 5423 } 5424 5425 @VisibleForTesting isDefaultNetwork(NetworkAgentInfo nai)5426 protected boolean isDefaultNetwork(NetworkAgentInfo nai) { 5427 return nai == getDefaultNetwork(); 5428 } 5429 isDefaultRequest(NetworkRequestInfo nri)5430 private boolean isDefaultRequest(NetworkRequestInfo nri) { 5431 return nri.request.requestId == mDefaultRequest.requestId; 5432 } 5433 5434 // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent 5435 // changes that would conflict throughout the automerger graph. Having this method temporarily 5436 // helps with the process of going through with all these dependent changes across the entire 5437 // tree. registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc)5438 public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, 5439 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 5440 int currentScore, NetworkMisc networkMisc) { 5441 return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities, 5442 currentScore, networkMisc, NetworkFactory.SerialNumber.NONE); 5443 } 5444 5445 /** 5446 * Register a new agent with ConnectivityService to handle a network. 5447 * 5448 * @param messenger a messenger for ConnectivityService to contact the agent asynchronously. 5449 * @param networkInfo the initial info associated with this network. It can be updated later : 5450 * see {@link #updateNetworkInfo}. 5451 * @param linkProperties the initial link properties of this network. They can be updated 5452 * later : see {@link #updateLinkProperties}. 5453 * @param networkCapabilities the initial capabilites of this network. They can be updated 5454 * later : see {@link #updateNetworkCapabilities}. 5455 * @param currentScore the initial score of the network. See 5456 * {@link NetworkAgentInfo#getCurrentScore}. 5457 * @param networkMisc metadata about the network. This is never updated. 5458 * @param factorySerialNumber the serial number of the factory owning this NetworkAgent. 5459 */ registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc, int factorySerialNumber)5460 public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, 5461 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 5462 int currentScore, NetworkMisc networkMisc, int factorySerialNumber) { 5463 enforceConnectivityInternalPermission(); 5464 5465 LinkProperties lp = new LinkProperties(linkProperties); 5466 lp.ensureDirectlyConnectedRoutes(); 5467 // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network 5468 // satisfies mDefaultRequest. 5469 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 5470 final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), 5471 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, 5472 mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, 5473 mNMS, factorySerialNumber); 5474 // Make sure the network capabilities reflect what the agent info says. 5475 nai.setNetworkCapabilities(mixInCapabilities(nai, nc)); 5476 final String extraInfo = networkInfo.getExtraInfo(); 5477 final String name = TextUtils.isEmpty(extraInfo) 5478 ? nai.networkCapabilities.getSSID() : extraInfo; 5479 if (DBG) log("registerNetworkAgent " + nai); 5480 final long token = Binder.clearCallingIdentity(); 5481 try { 5482 getNetworkStack().makeNetworkMonitor( 5483 nai.network, name, new NetworkMonitorCallbacks(nai)); 5484 } finally { 5485 Binder.restoreCallingIdentity(token); 5486 } 5487 // NetworkAgentInfo registration will finish when the NetworkMonitor is created. 5488 // If the network disconnects or sends any other event before that, messages are deferred by 5489 // NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the 5490 // registration. 5491 return nai.network.netId; 5492 } 5493 5494 @VisibleForTesting getNetworkStack()5495 protected NetworkStackClient getNetworkStack() { 5496 return NetworkStackClient.getInstance(); 5497 } 5498 handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor)5499 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { 5500 nai.onNetworkMonitorCreated(networkMonitor); 5501 if (VDBG) log("Got NetworkAgent Messenger"); 5502 mNetworkAgentInfos.put(nai.messenger, nai); 5503 synchronized (mNetworkForNetId) { 5504 mNetworkForNetId.put(nai.network.netId, nai); 5505 } 5506 5507 try { 5508 networkMonitor.start(); 5509 } catch (RemoteException e) { 5510 e.rethrowAsRuntimeException(); 5511 } 5512 nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger); 5513 NetworkInfo networkInfo = nai.networkInfo; 5514 nai.networkInfo = null; 5515 updateNetworkInfo(nai, networkInfo); 5516 updateUids(nai, null, nai.networkCapabilities); 5517 } 5518 updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp, LinkProperties oldLp)5519 private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp, 5520 LinkProperties oldLp) { 5521 int netId = networkAgent.network.netId; 5522 5523 // The NetworkAgentInfo does not know whether clatd is running on its network or not, or 5524 // whether there is a NAT64 prefix. Before we do anything else, make sure its LinkProperties 5525 // are accurate. 5526 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 5527 5528 updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities); 5529 5530 // update filtering rules, need to happen after the interface update so netd knows about the 5531 // new interface (the interface name -> index map becomes initialized) 5532 updateVpnFiltering(newLp, oldLp, networkAgent); 5533 5534 updateMtu(newLp, oldLp); 5535 // TODO - figure out what to do for clat 5536 // for (LinkProperties lp : newLp.getStackedLinks()) { 5537 // updateMtu(lp, null); 5538 // } 5539 if (isDefaultNetwork(networkAgent)) { 5540 updateTcpBufferSizes(newLp.getTcpBufferSizes()); 5541 } 5542 5543 updateRoutes(newLp, oldLp, netId); 5544 updateDnses(newLp, oldLp, netId); 5545 // Make sure LinkProperties represents the latest private DNS status. 5546 // This does not need to be done before updateDnses because the 5547 // LinkProperties are not the source of the private DNS configuration. 5548 // updateDnses will fetch the private DNS configuration from DnsManager. 5549 mDnsManager.updatePrivateDnsStatus(netId, newLp); 5550 5551 if (isDefaultNetwork(networkAgent)) { 5552 handleApplyDefaultProxy(newLp.getHttpProxy()); 5553 } else { 5554 updateProxy(newLp, oldLp); 5555 } 5556 // TODO - move this check to cover the whole function 5557 if (!Objects.equals(newLp, oldLp)) { 5558 synchronized (networkAgent) { 5559 networkAgent.linkProperties = newLp; 5560 } 5561 // Start or stop DNS64 detection and 464xlat according to network state. 5562 networkAgent.clatd.update(); 5563 notifyIfacesChangedForNetworkStats(); 5564 networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp); 5565 if (networkAgent.everConnected) { 5566 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 5567 } 5568 } 5569 5570 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 5571 } 5572 wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)5573 private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) { 5574 // Marks are only available on WiFi interfaces. Checking for 5575 // marks on unsupported interfaces is harmless. 5576 if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 5577 return; 5578 } 5579 5580 int mark = mContext.getResources().getInteger( 5581 com.android.internal.R.integer.config_networkWakeupPacketMark); 5582 int mask = mContext.getResources().getInteger( 5583 com.android.internal.R.integer.config_networkWakeupPacketMask); 5584 5585 // Mask/mark of zero will not detect anything interesting. 5586 // Don't install rules unless both values are nonzero. 5587 if (mark == 0 || mask == 0) { 5588 return; 5589 } 5590 5591 final String prefix = "iface:" + iface; 5592 try { 5593 if (add) { 5594 mNetd.wakeupAddInterface(iface, prefix, mark, mask); 5595 } else { 5596 mNetd.wakeupDelInterface(iface, prefix, mark, mask); 5597 } 5598 } catch (Exception e) { 5599 loge("Exception modifying wakeup packet monitoring: " + e); 5600 } 5601 5602 } 5603 updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, NetworkCapabilities caps)5604 private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, 5605 NetworkCapabilities caps) { 5606 CompareResult<String> interfaceDiff = new CompareResult<>( 5607 oldLp != null ? oldLp.getAllInterfaceNames() : null, 5608 newLp != null ? newLp.getAllInterfaceNames() : null); 5609 for (String iface : interfaceDiff.added) { 5610 try { 5611 if (DBG) log("Adding iface " + iface + " to network " + netId); 5612 mNMS.addInterfaceToNetwork(iface, netId); 5613 wakeupModifyInterface(iface, caps, true); 5614 } catch (Exception e) { 5615 loge("Exception adding interface: " + e); 5616 } 5617 } 5618 for (String iface : interfaceDiff.removed) { 5619 try { 5620 if (DBG) log("Removing iface " + iface + " from network " + netId); 5621 wakeupModifyInterface(iface, caps, false); 5622 mNMS.removeInterfaceFromNetwork(iface, netId); 5623 } catch (Exception e) { 5624 loge("Exception removing interface: " + e); 5625 } 5626 } 5627 } 5628 5629 /** 5630 * Have netd update routes from oldLp to newLp. 5631 * @return true if routes changed between oldLp and newLp 5632 */ updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)5633 private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { 5634 // Compare the route diff to determine which routes should be added and removed. 5635 CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>( 5636 oldLp != null ? oldLp.getAllRoutes() : null, 5637 newLp != null ? newLp.getAllRoutes() : null); 5638 5639 // add routes before removing old in case it helps with continuous connectivity 5640 5641 // do this twice, adding non-next-hop routes first, then routes they are dependent on 5642 for (RouteInfo route : routeDiff.added) { 5643 if (route.hasGateway()) continue; 5644 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 5645 try { 5646 mNMS.addRoute(netId, route); 5647 } catch (Exception e) { 5648 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 5649 loge("Exception in addRoute for non-gateway: " + e); 5650 } 5651 } 5652 } 5653 for (RouteInfo route : routeDiff.added) { 5654 if (route.hasGateway() == false) continue; 5655 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 5656 try { 5657 mNMS.addRoute(netId, route); 5658 } catch (Exception e) { 5659 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 5660 loge("Exception in addRoute for gateway: " + e); 5661 } 5662 } 5663 } 5664 5665 for (RouteInfo route : routeDiff.removed) { 5666 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); 5667 try { 5668 mNMS.removeRoute(netId, route); 5669 } catch (Exception e) { 5670 loge("Exception in removeRoute: " + e); 5671 } 5672 } 5673 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); 5674 } 5675 updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)5676 private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { 5677 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 5678 return; // no updating necessary 5679 } 5680 5681 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 5682 final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId); 5683 5684 if (DBG) { 5685 final Collection<InetAddress> dnses = newLp.getDnsServers(); 5686 log("Setting DNS servers for network " + netId + " to " + dnses); 5687 } 5688 try { 5689 mDnsManager.setDnsConfigurationForNetwork(netId, newLp, isDefaultNetwork); 5690 } catch (Exception e) { 5691 loge("Exception in setDnsConfigurationForNetwork: " + e); 5692 } 5693 } 5694 updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)5695 private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, 5696 NetworkAgentInfo nai) { 5697 final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null; 5698 final String newIface = newLp != null ? newLp.getInterfaceName() : null; 5699 final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp); 5700 final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp); 5701 5702 if (!wasFiltering && !needsFiltering) { 5703 // Nothing to do. 5704 return; 5705 } 5706 5707 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) { 5708 // Nothing changed. 5709 return; 5710 } 5711 5712 final Set<UidRange> ranges = nai.networkCapabilities.getUids(); 5713 final int vpnAppUid = nai.networkCapabilities.getEstablishingVpnAppUid(); 5714 // TODO: this create a window of opportunity for apps to receive traffic between the time 5715 // when the old rules are removed and the time when new rules are added. To fix this, 5716 // make eBPF support two whitelisted interfaces so here new rules can be added before the 5717 // old rules are being removed. 5718 if (wasFiltering) { 5719 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid); 5720 } 5721 if (needsFiltering) { 5722 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid); 5723 } 5724 } 5725 getNetworkPermission(NetworkCapabilities nc)5726 private int getNetworkPermission(NetworkCapabilities nc) { 5727 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 5728 return INetd.PERMISSION_SYSTEM; 5729 } 5730 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 5731 return INetd.PERMISSION_NETWORK; 5732 } 5733 return INetd.PERMISSION_NONE; 5734 } 5735 5736 /** 5737 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 5738 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 5739 * and foreground status). 5740 */ mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)5741 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 5742 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 5743 // Don't complain for VPNs since they're not driven by requests and there is no risk of 5744 // causing a connect/teardown loop. 5745 // TODO: remove this altogether and make it the responsibility of the NetworkFactories to 5746 // avoid connect/teardown loops. 5747 if (nai.everConnected && 5748 !nai.isVPN() && 5749 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 5750 // TODO: consider not complaining when a network agent degrades its capabilities if this 5751 // does not cause any request (that is not a listen) currently matching that agent to 5752 // stop being matched by the updated agent. 5753 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 5754 if (!TextUtils.isEmpty(diff)) { 5755 Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 5756 } 5757 } 5758 5759 // Don't modify caller's NetworkCapabilities. 5760 NetworkCapabilities newNc = new NetworkCapabilities(nc); 5761 if (nai.lastValidated) { 5762 newNc.addCapability(NET_CAPABILITY_VALIDATED); 5763 } else { 5764 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 5765 } 5766 if (nai.lastCaptivePortalDetected) { 5767 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 5768 } else { 5769 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 5770 } 5771 if (nai.isBackgroundNetwork()) { 5772 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 5773 } else { 5774 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 5775 } 5776 if (nai.isSuspended()) { 5777 newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 5778 } else { 5779 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 5780 } 5781 if (nai.partialConnectivity) { 5782 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 5783 } else { 5784 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 5785 } 5786 5787 return newNc; 5788 } 5789 5790 /** 5791 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 5792 * 5793 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 5794 * capabilities we manage and store in {@code nai}, such as validated status and captive 5795 * portal status) 5796 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 5797 * potentially triggers rematches. 5798 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 5799 * change.) 5800 * 5801 * @param oldScore score of the network before any of the changes that prompted us 5802 * to call this function. 5803 * @param nai the network having its capabilities updated. 5804 * @param nc the new network capabilities. 5805 */ updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc)5806 private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) { 5807 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 5808 5809 if (Objects.equals(nai.networkCapabilities, newNc)) return; 5810 5811 final int oldPermission = getNetworkPermission(nai.networkCapabilities); 5812 final int newPermission = getNetworkPermission(newNc); 5813 if (oldPermission != newPermission && nai.created && !nai.isVPN()) { 5814 try { 5815 mNMS.setNetworkPermission(nai.network.netId, newPermission); 5816 } catch (RemoteException e) { 5817 loge("Exception in setNetworkPermission: " + e); 5818 } 5819 } 5820 5821 final NetworkCapabilities prevNc; 5822 synchronized (nai) { 5823 prevNc = nai.networkCapabilities; 5824 nai.setNetworkCapabilities(newNc); 5825 } 5826 5827 updateUids(nai, prevNc, newNc); 5828 5829 if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) { 5830 // If the requestable capabilities haven't changed, and the score hasn't changed, then 5831 // the change we're processing can't affect any requests, it can only affect the listens 5832 // on this network. We might have been called by rematchNetworkAndRequests when a 5833 // network changed foreground state. 5834 processListenRequests(nai, true); 5835 } else { 5836 // If the requestable capabilities have changed or the score changed, we can't have been 5837 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 5838 rematchAllNetworksAndRequests(nai, oldScore); 5839 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 5840 } 5841 5842 if (prevNc != null) { 5843 final boolean oldMetered = prevNc.isMetered(); 5844 final boolean newMetered = newNc.isMetered(); 5845 final boolean meteredChanged = oldMetered != newMetered; 5846 5847 if (meteredChanged) { 5848 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground, 5849 mRestrictBackground); 5850 } 5851 5852 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) != 5853 newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 5854 5855 // Report changes that are interesting for network statistics tracking. 5856 if (meteredChanged || roamingChanged) { 5857 notifyIfacesChangedForNetworkStats(); 5858 } 5859 } 5860 5861 if (!newNc.hasTransport(TRANSPORT_VPN)) { 5862 // Tell VPNs about updated capabilities, since they may need to 5863 // bubble those changes through. 5864 updateAllVpnsCapabilities(); 5865 } 5866 } 5867 5868 /** 5869 * Returns whether VPN isolation (ingress interface filtering) should be applied on the given 5870 * network. 5871 * 5872 * Ingress interface filtering enforces that all apps under the given network can only receive 5873 * packets from the network's interface (and loopback). This is important for VPNs because 5874 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any 5875 * non-VPN interfaces. 5876 * 5877 * As a result, this method should return true iff 5878 * 1. the network is an app VPN (not legacy VPN) 5879 * 2. the VPN does not allow bypass 5880 * 3. the VPN is fully-routed 5881 * 4. the VPN interface is non-null 5882 * 5883 * @See INetd#firewallAddUidInterfaceRules 5884 * @See INetd#firewallRemoveUidInterfaceRules 5885 */ requiresVpnIsolation(@onNull NetworkAgentInfo nai, NetworkCapabilities nc, LinkProperties lp)5886 private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, 5887 LinkProperties lp) { 5888 if (nc == null || lp == null) return false; 5889 return nai.isVPN() 5890 && !nai.networkMisc.allowBypass 5891 && nc.getEstablishingVpnAppUid() != Process.SYSTEM_UID 5892 && lp.getInterfaceName() != null 5893 && (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute()); 5894 } 5895 updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)5896 private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, 5897 NetworkCapabilities newNc) { 5898 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids(); 5899 Set<UidRange> newRanges = null == newNc ? null : newNc.getUids(); 5900 if (null == prevRanges) prevRanges = new ArraySet<>(); 5901 if (null == newRanges) newRanges = new ArraySet<>(); 5902 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 5903 5904 prevRanges.removeAll(newRanges); 5905 newRanges.removeAll(prevRangesCopy); 5906 5907 try { 5908 // When updating the VPN uid routing rules, add the new range first then remove the old 5909 // range. If old range were removed first, there would be a window between the old 5910 // range being removed and the new range being added, during which UIDs contained 5911 // in both ranges are not subject to any VPN routing rules. Adding new range before 5912 // removing old range works because, unlike the filtering rules below, it's possible to 5913 // add duplicate UID routing rules. 5914 if (!newRanges.isEmpty()) { 5915 final UidRange[] addedRangesArray = new UidRange[newRanges.size()]; 5916 newRanges.toArray(addedRangesArray); 5917 mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray); 5918 } 5919 if (!prevRanges.isEmpty()) { 5920 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()]; 5921 prevRanges.toArray(removedRangesArray); 5922 mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray); 5923 } 5924 final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties); 5925 final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties); 5926 final String iface = nai.linkProperties.getInterfaceName(); 5927 // For VPN uid interface filtering, old ranges need to be removed before new ranges can 5928 // be added, due to the range being expanded and stored as invidiual UIDs. For example 5929 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means 5930 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges 5931 // were added first and then newRanges got removed later, there would be only one uid 5932 // 10013 left. A consequence of removing old ranges before adding new ranges is that 5933 // there is now a window of opportunity when the UIDs are not subject to any filtering. 5934 // Note that this is in contrast with the (more robust) update of VPN routing rules 5935 // above, where the addition of new ranges happens before the removal of old ranges. 5936 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range 5937 // to be removed will never overlap with the new range to be added. 5938 if (wasFiltering && !prevRanges.isEmpty()) { 5939 mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, 5940 prevNc.getEstablishingVpnAppUid()); 5941 } 5942 if (shouldFilter && !newRanges.isEmpty()) { 5943 mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, 5944 newNc.getEstablishingVpnAppUid()); 5945 } 5946 } catch (Exception e) { 5947 // Never crash! 5948 loge("Exception in updateUids: ", e); 5949 } 5950 } 5951 handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)5952 public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) { 5953 ensureRunningOnConnectivityServiceThread(); 5954 5955 if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) { 5956 // Ignore updates for disconnected networks 5957 return; 5958 } 5959 // newLp is already a defensive copy. 5960 newLp.ensureDirectlyConnectedRoutes(); 5961 if (VDBG || DDBG) { 5962 log("Update of LinkProperties for " + nai.name() + 5963 "; created=" + nai.created + 5964 "; everConnected=" + nai.everConnected); 5965 } 5966 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties)); 5967 } 5968 sendUpdatedScoreToFactories(NetworkAgentInfo nai)5969 private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) { 5970 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5971 NetworkRequest nr = nai.requestAt(i); 5972 // Don't send listening requests to factories. b/17393458 5973 if (nr.isListen()) continue; 5974 sendUpdatedScoreToFactories(nr, nai); 5975 } 5976 } 5977 sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai)5978 private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai) { 5979 int score = 0; 5980 int serial = 0; 5981 if (nai != null) { 5982 score = nai.getCurrentScore(); 5983 serial = nai.factorySerialNumber; 5984 } 5985 if (VDBG || DDBG){ 5986 log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); 5987 } 5988 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 5989 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 5990 serial, networkRequest); 5991 } 5992 } 5993 sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)5994 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 5995 int notificationType) { 5996 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 5997 Intent intent = new Intent(); 5998 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 5999 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request); 6000 nri.mPendingIntentSent = true; 6001 sendIntent(nri.mPendingIntent, intent); 6002 } 6003 // else not handled 6004 } 6005 sendIntent(PendingIntent pendingIntent, Intent intent)6006 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 6007 mPendingIntentWakeLock.acquire(); 6008 try { 6009 if (DBG) log("Sending " + pendingIntent); 6010 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */); 6011 } catch (PendingIntent.CanceledException e) { 6012 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 6013 mPendingIntentWakeLock.release(); 6014 releasePendingNetworkRequest(pendingIntent); 6015 } 6016 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 6017 } 6018 6019 @Override onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)6020 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 6021 String resultData, Bundle resultExtras) { 6022 if (DBG) log("Finished sending " + pendingIntent); 6023 mPendingIntentWakeLock.release(); 6024 // Release with a delay so the receiving client has an opportunity to put in its 6025 // own request. 6026 releasePendingNetworkRequestWithDelay(pendingIntent); 6027 } 6028 callCallbackForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType, int arg1)6029 private void callCallbackForRequest(NetworkRequestInfo nri, 6030 NetworkAgentInfo networkAgent, int notificationType, int arg1) { 6031 if (nri.messenger == null) { 6032 return; // Default request has no msgr 6033 } 6034 Bundle bundle = new Bundle(); 6035 // TODO: check if defensive copies of data is needed. 6036 putParcelable(bundle, new NetworkRequest(nri.request)); 6037 Message msg = Message.obtain(); 6038 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) { 6039 putParcelable(bundle, networkAgent.network); 6040 } 6041 switch (notificationType) { 6042 case ConnectivityManager.CALLBACK_AVAILABLE: { 6043 putParcelable(bundle, networkCapabilitiesRestrictedForCallerPermissions( 6044 networkAgent.networkCapabilities, nri.mPid, nri.mUid)); 6045 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); 6046 // For this notification, arg1 contains the blocked status. 6047 msg.arg1 = arg1; 6048 break; 6049 } 6050 case ConnectivityManager.CALLBACK_LOSING: { 6051 msg.arg1 = arg1; 6052 break; 6053 } 6054 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 6055 // networkAgent can't be null as it has been accessed a few lines above. 6056 final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions( 6057 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 6058 putParcelable(bundle, nc); 6059 break; 6060 } 6061 case ConnectivityManager.CALLBACK_IP_CHANGED: { 6062 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); 6063 break; 6064 } 6065 case ConnectivityManager.CALLBACK_BLK_CHANGED: { 6066 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1 != 0); 6067 msg.arg1 = arg1; 6068 break; 6069 } 6070 } 6071 msg.what = notificationType; 6072 msg.setData(bundle); 6073 try { 6074 if (VDBG) { 6075 String notification = ConnectivityManager.getCallbackName(notificationType); 6076 log("sending notification " + notification + " for " + nri.request); 6077 } 6078 nri.messenger.send(msg); 6079 } catch (RemoteException e) { 6080 // may occur naturally in the race of binder death. 6081 loge("RemoteException caught trying to send a callback msg for " + nri.request); 6082 } 6083 } 6084 putParcelable(Bundle bundle, T t)6085 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 6086 bundle.putParcelable(t.getClass().getSimpleName(), t); 6087 } 6088 teardownUnneededNetwork(NetworkAgentInfo nai)6089 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 6090 if (nai.numRequestNetworkRequests() != 0) { 6091 for (int i = 0; i < nai.numNetworkRequests(); i++) { 6092 NetworkRequest nr = nai.requestAt(i); 6093 // Ignore listening requests. 6094 if (nr.isListen()) continue; 6095 loge("Dead network still had at least " + nr); 6096 break; 6097 } 6098 } 6099 nai.asyncChannel.disconnect(); 6100 } 6101 handleLingerComplete(NetworkAgentInfo oldNetwork)6102 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 6103 if (oldNetwork == null) { 6104 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 6105 return; 6106 } 6107 if (DBG) log("handleLingerComplete for " + oldNetwork.name()); 6108 6109 // If we get here it means that the last linger timeout for this network expired. So there 6110 // must be no other active linger timers, and we must stop lingering. 6111 oldNetwork.clearLingerState(); 6112 6113 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 6114 // Tear the network down. 6115 teardownUnneededNetwork(oldNetwork); 6116 } else { 6117 // Put the network in the background. 6118 updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork, 6119 oldNetwork.networkCapabilities); 6120 } 6121 } 6122 makeDefault(NetworkAgentInfo newNetwork)6123 private void makeDefault(NetworkAgentInfo newNetwork) { 6124 if (DBG) log("Switching to new default network: " + newNetwork); 6125 6126 try { 6127 mNMS.setDefaultNetId(newNetwork.network.netId); 6128 } catch (Exception e) { 6129 loge("Exception setting default network :" + e); 6130 } 6131 6132 notifyLockdownVpn(newNetwork); 6133 handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); 6134 updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes()); 6135 mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); 6136 notifyIfacesChangedForNetworkStats(); 6137 // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks. 6138 updateAllVpnsCapabilities(); 6139 } 6140 processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged)6141 private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) { 6142 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 6143 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 6144 NetworkRequest nr = nri.request; 6145 if (!nr.isListen()) continue; 6146 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 6147 nai.removeRequest(nri.request.requestId); 6148 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0); 6149 } 6150 } 6151 6152 if (capabilitiesChanged) { 6153 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 6154 } 6155 6156 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 6157 NetworkRequest nr = nri.request; 6158 if (!nr.isListen()) continue; 6159 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 6160 nai.addRequest(nr); 6161 notifyNetworkAvailable(nai, nri); 6162 } 6163 } 6164 } 6165 6166 // Handles a network appearing or improving its score. 6167 // 6168 // - Evaluates all current NetworkRequests that can be 6169 // satisfied by newNetwork, and reassigns to newNetwork 6170 // any such requests for which newNetwork is the best. 6171 // 6172 // - Lingers any validated Networks that as a result are no longer 6173 // needed. A network is needed if it is the best network for 6174 // one or more NetworkRequests, or if it is a VPN. 6175 // 6176 // - Tears down newNetwork if it just became validated 6177 // but turns out to be unneeded. 6178 // 6179 // - If reapUnvalidatedNetworks==REAP, tears down unvalidated 6180 // networks that have no chance (i.e. even if validated) 6181 // of becoming the highest scoring network. 6182 // 6183 // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy, 6184 // it does not remove NetworkRequests that other Networks could better satisfy. 6185 // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}. 6186 // This function should be used when possible instead of {@code rematchAllNetworksAndRequests} 6187 // as it performs better by a factor of the number of Networks. 6188 // 6189 // @param newNetwork is the network to be matched against NetworkRequests. 6190 // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be 6191 // performed to tear down unvalidated networks that have no chance (i.e. even if 6192 // validated) of becoming the highest scoring network. rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)6193 private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, 6194 ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) { 6195 if (!newNetwork.everConnected) return; 6196 boolean keep = newNetwork.isVPN(); 6197 boolean isNewDefault = false; 6198 NetworkAgentInfo oldDefaultNetwork = null; 6199 6200 final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork(); 6201 final int score = newNetwork.getCurrentScore(); 6202 6203 if (VDBG || DDBG) log("rematching " + newNetwork.name()); 6204 6205 // Find and migrate to this Network any NetworkRequests for 6206 // which this network is now the best. 6207 ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>(); 6208 ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>(); 6209 NetworkCapabilities nc = newNetwork.networkCapabilities; 6210 if (VDBG) log(" network has: " + nc); 6211 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 6212 // Process requests in the first pass and listens in the second pass. This allows us to 6213 // change a network's capabilities depending on which requests it has. This is only 6214 // correct if the change in capabilities doesn't affect whether the network satisfies 6215 // requests or not, and doesn't affect the network's score. 6216 if (nri.request.isListen()) continue; 6217 6218 final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId); 6219 final boolean satisfies = newNetwork.satisfies(nri.request); 6220 if (newNetwork == currentNetwork && satisfies) { 6221 if (VDBG) { 6222 log("Network " + newNetwork.name() + " was already satisfying" + 6223 " request " + nri.request.requestId + ". No change."); 6224 } 6225 keep = true; 6226 continue; 6227 } 6228 6229 // check if it satisfies the NetworkCapabilities 6230 if (VDBG) log(" checking if request is satisfied: " + nri.request); 6231 if (satisfies) { 6232 // next check if it's better than any current network we're using for 6233 // this request 6234 if (VDBG || DDBG) { 6235 log("currentScore = " + 6236 (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + 6237 ", newScore = " + score); 6238 } 6239 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) { 6240 if (VDBG) log("rematch for " + newNetwork.name()); 6241 if (currentNetwork != null) { 6242 if (VDBG || DDBG){ 6243 log(" accepting network in place of " + currentNetwork.name()); 6244 } 6245 currentNetwork.removeRequest(nri.request.requestId); 6246 currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs); 6247 affectedNetworks.add(currentNetwork); 6248 } else { 6249 if (VDBG || DDBG) log(" accepting network in place of null"); 6250 } 6251 newNetwork.unlingerRequest(nri.request); 6252 setNetworkForRequest(nri.request.requestId, newNetwork); 6253 if (!newNetwork.addRequest(nri.request)) { 6254 Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request); 6255 } 6256 addedRequests.add(nri); 6257 keep = true; 6258 // Tell NetworkFactories about the new score, so they can stop 6259 // trying to connect if they know they cannot match it. 6260 // TODO - this could get expensive if we have a lot of requests for this 6261 // network. Think about if there is a way to reduce this. Push 6262 // netid->request mapping to each factory? 6263 sendUpdatedScoreToFactories(nri.request, newNetwork); 6264 if (isDefaultRequest(nri)) { 6265 isNewDefault = true; 6266 oldDefaultNetwork = currentNetwork; 6267 if (currentNetwork != null) { 6268 mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork); 6269 } 6270 } 6271 } 6272 } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) { 6273 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", 6274 // mark it as no longer satisfying "nri". Because networks are processed by 6275 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will 6276 // match "newNetwork" before this loop will encounter a "currentNetwork" with higher 6277 // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri". 6278 // This means this code doesn't have to handle the case where "currentNetwork" no 6279 // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork". 6280 if (DBG) { 6281 log("Network " + newNetwork.name() + " stopped satisfying" + 6282 " request " + nri.request.requestId); 6283 } 6284 newNetwork.removeRequest(nri.request.requestId); 6285 if (currentNetwork == newNetwork) { 6286 clearNetworkForRequest(nri.request.requestId); 6287 sendUpdatedScoreToFactories(nri.request, null); 6288 } else { 6289 Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + 6290 newNetwork.name() + 6291 " without updating mNetworkForRequestId or factories!"); 6292 } 6293 // TODO: Technically, sending CALLBACK_LOST here is 6294 // incorrect if there is a replacement network currently 6295 // connected that can satisfy nri, which is a request 6296 // (not a listen). However, the only capability that can both 6297 // a) be requested and b) change is NET_CAPABILITY_TRUSTED, 6298 // so this code is only incorrect for a network that loses 6299 // the TRUSTED capability, which is a rare case. 6300 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0); 6301 } 6302 } 6303 if (isNewDefault) { 6304 updateDataActivityTracking(newNetwork, oldDefaultNetwork); 6305 // Notify system services that this network is up. 6306 makeDefault(newNetwork); 6307 // Log 0 -> X and Y -> X default network transitions, where X is the new default. 6308 metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( 6309 now, newNetwork, oldDefaultNetwork); 6310 // Have a new default network, release the transition wakelock in 6311 scheduleReleaseNetworkTransitionWakelock(); 6312 } 6313 6314 if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) { 6315 Slog.wtf(TAG, String.format( 6316 "BUG: %s changed requestable capabilities during rematch: %s -> %s", 6317 newNetwork.name(), nc, newNetwork.networkCapabilities)); 6318 } 6319 if (newNetwork.getCurrentScore() != score) { 6320 Slog.wtf(TAG, String.format( 6321 "BUG: %s changed score during rematch: %d -> %d", 6322 newNetwork.name(), score, newNetwork.getCurrentScore())); 6323 } 6324 6325 // Second pass: process all listens. 6326 if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) { 6327 // If the network went from background to foreground or vice versa, we need to update 6328 // its foreground state. It is safe to do this after rematching the requests because 6329 // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable 6330 // capability and does not affect the network's score (see the Slog.wtf call above). 6331 updateCapabilities(score, newNetwork, newNetwork.networkCapabilities); 6332 } else { 6333 processListenRequests(newNetwork, false); 6334 } 6335 6336 // do this after the default net is switched, but 6337 // before LegacyTypeTracker sends legacy broadcasts 6338 for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri); 6339 6340 // Linger any networks that are no longer needed. This should be done after sending the 6341 // available callback for newNetwork. 6342 for (NetworkAgentInfo nai : affectedNetworks) { 6343 updateLingerState(nai, now); 6344 } 6345 // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it 6346 // does not need to be done in any particular order. 6347 updateLingerState(newNetwork, now); 6348 6349 if (isNewDefault) { 6350 // Maintain the illusion: since the legacy API only 6351 // understands one network at a time, we must pretend 6352 // that the current default network disconnected before 6353 // the new one connected. 6354 if (oldDefaultNetwork != null) { 6355 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 6356 oldDefaultNetwork, true); 6357 } 6358 mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; 6359 mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); 6360 notifyLockdownVpn(newNetwork); 6361 } 6362 6363 if (keep) { 6364 // Notify battery stats service about this network, both the normal 6365 // interface and any stacked links. 6366 // TODO: Avoid redoing this; this must only be done once when a network comes online. 6367 try { 6368 final IBatteryStats bs = BatteryStatsService.getService(); 6369 final int type = newNetwork.networkInfo.getType(); 6370 6371 final String baseIface = newNetwork.linkProperties.getInterfaceName(); 6372 bs.noteNetworkInterfaceType(baseIface, type); 6373 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) { 6374 final String stackedIface = stacked.getInterfaceName(); 6375 bs.noteNetworkInterfaceType(stackedIface, type); 6376 } 6377 } catch (RemoteException ignored) { 6378 } 6379 6380 // This has to happen after the notifyNetworkCallbacks as that tickles each 6381 // ConnectivityManager instance so that legacy requests correctly bind dns 6382 // requests to this network. The legacy users are listening for this broadcast 6383 // and will generally do a dns request so they can ensureRouteToHost and if 6384 // they do that before the callbacks happen they'll use the default network. 6385 // 6386 // TODO: Is there still a race here? We send the broadcast 6387 // after sending the callback, but if the app can receive the 6388 // broadcast before the callback, it might still break. 6389 // 6390 // This *does* introduce a race where if the user uses the new api 6391 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 6392 // they may get old info. Reverse this after the old startUsing api is removed. 6393 // This is on top of the multiple intent sequencing referenced in the todo above. 6394 for (int i = 0; i < newNetwork.numNetworkRequests(); i++) { 6395 NetworkRequest nr = newNetwork.requestAt(i); 6396 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 6397 // legacy type tracker filters out repeat adds 6398 mLegacyTypeTracker.add(nr.legacyType, newNetwork); 6399 } 6400 } 6401 6402 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 6403 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 6404 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 6405 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 6406 if (newNetwork.isVPN()) { 6407 mLegacyTypeTracker.add(TYPE_VPN, newNetwork); 6408 } 6409 } 6410 if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) { 6411 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 6412 if (unneeded(nai, UnneededFor.TEARDOWN)) { 6413 if (nai.getLingerExpiry() > 0) { 6414 // This network has active linger timers and no requests, but is not 6415 // lingering. Linger it. 6416 // 6417 // One way (the only way?) this can happen if this network is unvalidated 6418 // and became unneeded due to another network improving its score to the 6419 // point where this network will no longer be able to satisfy any requests 6420 // even if it validates. 6421 updateLingerState(nai, now); 6422 } else { 6423 if (DBG) log("Reaping " + nai.name()); 6424 teardownUnneededNetwork(nai); 6425 } 6426 } 6427 } 6428 } 6429 } 6430 6431 /** 6432 * Attempt to rematch all Networks with NetworkRequests. This may result in Networks 6433 * being disconnected. 6434 * @param changed If only one Network's score or capabilities have been modified since the last 6435 * time this function was called, pass this Network in this argument, otherwise pass 6436 * null. 6437 * @param oldScore If only one Network has been changed but its NetworkCapabilities have not 6438 * changed, pass in the Network's score (from getCurrentScore()) prior to the change via 6439 * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if 6440 * {@code changed} is {@code null}. This is because NetworkCapabilities influence a 6441 * network's score. 6442 */ rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore)6443 private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) { 6444 // TODO: This may get slow. The "changed" parameter is provided for future optimization 6445 // to avoid the slowness. It is not simply enough to process just "changed", for 6446 // example in the case where "changed"'s score decreases and another network should begin 6447 // satisfying a NetworkRequest that "changed" currently satisfies. 6448 6449 // Optimization: Only reprocess "changed" if its score improved. This is safe because it 6450 // can only add more NetworkRequests satisfied by "changed", and this is exactly what 6451 // rematchNetworkAndRequests() handles. 6452 final long now = SystemClock.elapsedRealtime(); 6453 if (changed != null && oldScore < changed.getCurrentScore()) { 6454 rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now); 6455 } else { 6456 final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray( 6457 new NetworkAgentInfo[mNetworkAgentInfos.size()]); 6458 // Rematch higher scoring networks first to prevent requests first matching a lower 6459 // scoring network and then a higher scoring network, which could produce multiple 6460 // callbacks and inadvertently unlinger networks. 6461 Arrays.sort(nais); 6462 for (NetworkAgentInfo nai : nais) { 6463 rematchNetworkAndRequests(nai, 6464 // Only reap the last time through the loop. Reaping before all rematching 6465 // is complete could incorrectly teardown a network that hasn't yet been 6466 // rematched. 6467 (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP 6468 : ReapUnvalidatedNetworks.REAP, 6469 now); 6470 } 6471 } 6472 } 6473 updateInetCondition(NetworkAgentInfo nai)6474 private void updateInetCondition(NetworkAgentInfo nai) { 6475 // Don't bother updating until we've graduated to validated at least once. 6476 if (!nai.everValidated) return; 6477 // For now only update icons for default connection. 6478 // TODO: Update WiFi and cellular icons separately. b/17237507 6479 if (!isDefaultNetwork(nai)) return; 6480 6481 int newInetCondition = nai.lastValidated ? 100 : 0; 6482 // Don't repeat publish. 6483 if (newInetCondition == mDefaultInetConditionPublished) return; 6484 6485 mDefaultInetConditionPublished = newInetCondition; 6486 sendInetConditionBroadcast(nai.networkInfo); 6487 } 6488 notifyLockdownVpn(NetworkAgentInfo nai)6489 private void notifyLockdownVpn(NetworkAgentInfo nai) { 6490 synchronized (mVpns) { 6491 if (mLockdownTracker != null) { 6492 if (nai != null && nai.isVPN()) { 6493 mLockdownTracker.onVpnStateChanged(nai.networkInfo); 6494 } else { 6495 mLockdownTracker.onNetworkInfoChanged(); 6496 } 6497 } 6498 } 6499 } 6500 updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo)6501 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { 6502 final NetworkInfo.State state = newInfo.getState(); 6503 NetworkInfo oldInfo = null; 6504 final int oldScore = networkAgent.getCurrentScore(); 6505 synchronized (networkAgent) { 6506 oldInfo = networkAgent.networkInfo; 6507 networkAgent.networkInfo = newInfo; 6508 } 6509 notifyLockdownVpn(networkAgent); 6510 6511 if (DBG) { 6512 log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " + 6513 (oldInfo == null ? "null" : oldInfo.getState()) + 6514 " to " + state); 6515 } 6516 6517 if (!networkAgent.created 6518 && (state == NetworkInfo.State.CONNECTED 6519 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { 6520 6521 // A network that has just connected has zero requests and is thus a foreground network. 6522 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 6523 6524 if (!createNativeNetwork(networkAgent)) return; 6525 networkAgent.created = true; 6526 } 6527 6528 if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) { 6529 networkAgent.everConnected = true; 6530 6531 if (networkAgent.linkProperties == null) { 6532 Slog.wtf(TAG, networkAgent.name() + " connected with null LinkProperties"); 6533 } 6534 6535 // NetworkCapabilities need to be set before sending the private DNS config to 6536 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required. 6537 synchronized (networkAgent) { 6538 networkAgent.setNetworkCapabilities(networkAgent.networkCapabilities); 6539 } 6540 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 6541 updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties), 6542 null); 6543 6544 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect 6545 // command must be sent after updating LinkProperties to maximize chances of 6546 // NetworkMonitor seeing the correct LinkProperties when starting. 6547 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call. 6548 if (networkAgent.networkMisc.acceptPartialConnectivity) { 6549 networkAgent.networkMonitor().setAcceptPartialConnectivity(); 6550 } 6551 networkAgent.networkMonitor().notifyNetworkConnected( 6552 networkAgent.linkProperties, networkAgent.networkCapabilities); 6553 scheduleUnvalidatedPrompt(networkAgent); 6554 6555 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 6556 // be communicated to a particular NetworkAgent depends only on the network's immutable, 6557 // capabilities, so it only needs to be done once on initial connect, not every time the 6558 // network's capabilities change. Note that we do this before rematching the network, 6559 // so we could decide to tear it down immediately afterwards. That's fine though - on 6560 // disconnection NetworkAgents should stop any signal strength monitoring they have been 6561 // doing. 6562 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 6563 6564 if (networkAgent.isVPN()) { 6565 updateAllVpnsCapabilities(); 6566 } 6567 6568 // Consider network even though it is not yet validated. 6569 final long now = SystemClock.elapsedRealtime(); 6570 rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now); 6571 6572 // This has to happen after matching the requests, because callbacks are just requests. 6573 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 6574 } else if (state == NetworkInfo.State.DISCONNECTED) { 6575 networkAgent.asyncChannel.disconnect(); 6576 if (networkAgent.isVPN()) { 6577 updateUids(networkAgent, networkAgent.networkCapabilities, null); 6578 } 6579 disconnectAndDestroyNetwork(networkAgent); 6580 if (networkAgent.isVPN()) { 6581 // As the active or bound network changes for apps, broadcast the default proxy, as 6582 // apps may need to update their proxy data. This is called after disconnecting from 6583 // VPN to make sure we do not broadcast the old proxy data. 6584 // TODO(b/122649188): send the broadcast only to VPN users. 6585 mProxyTracker.sendProxyBroadcast(); 6586 } 6587 } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) || 6588 state == NetworkInfo.State.SUSPENDED) { 6589 // going into or coming out of SUSPEND: re-score and notify 6590 if (networkAgent.getCurrentScore() != oldScore) { 6591 rematchAllNetworksAndRequests(networkAgent, oldScore); 6592 } 6593 updateCapabilities(networkAgent.getCurrentScore(), networkAgent, 6594 networkAgent.networkCapabilities); 6595 // TODO (b/73132094) : remove this call once the few users of onSuspended and 6596 // onResumed have been removed. 6597 notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ? 6598 ConnectivityManager.CALLBACK_SUSPENDED : 6599 ConnectivityManager.CALLBACK_RESUMED)); 6600 mLegacyTypeTracker.update(networkAgent); 6601 } 6602 } 6603 updateNetworkScore(NetworkAgentInfo nai, int score)6604 private void updateNetworkScore(NetworkAgentInfo nai, int score) { 6605 if (VDBG || DDBG) log("updateNetworkScore for " + nai.name() + " to " + score); 6606 if (score < 0) { 6607 loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score + 6608 "). Bumping score to min of 0"); 6609 score = 0; 6610 } 6611 6612 final int oldScore = nai.getCurrentScore(); 6613 nai.setCurrentScore(score); 6614 6615 rematchAllNetworksAndRequests(nai, oldScore); 6616 6617 sendUpdatedScoreToFactories(nai); 6618 } 6619 6620 // Notify only this one new request of the current state. Transfer all the 6621 // current state by calling NetworkCapabilities and LinkProperties callbacks 6622 // so that callers can be guaranteed to have as close to atomicity in state 6623 // transfer as can be supported by this current API. notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)6624 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 6625 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 6626 if (nri.mPendingIntent != null) { 6627 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE); 6628 // Attempt no subsequent state pushes where intents are involved. 6629 return; 6630 } 6631 6632 final boolean metered = nai.networkCapabilities.isMetered(); 6633 final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid), 6634 metered, mRestrictBackground); 6635 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0); 6636 } 6637 6638 /** 6639 * Notify of the blocked state apps with a registered callback matching a given NAI. 6640 * 6641 * Unlike other callbacks, blocked status is different between each individual uid. So for 6642 * any given nai, all requests need to be considered according to the uid who filed it. 6643 * 6644 * @param nai The target NetworkAgentInfo. 6645 * @param oldMetered True if the previous network capabilities is metered. 6646 * @param newRestrictBackground True if data saver is enabled. 6647 */ maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground)6648 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, 6649 boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) { 6650 6651 for (int i = 0; i < nai.numNetworkRequests(); i++) { 6652 NetworkRequest nr = nai.requestAt(i); 6653 NetworkRequestInfo nri = mNetworkRequests.get(nr); 6654 final int uidRules = mUidRules.get(nri.mUid); 6655 final boolean oldBlocked, newBlocked; 6656 // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed 6657 // between these two calls. 6658 synchronized (mVpns) { 6659 oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered, 6660 oldRestrictBackground); 6661 newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered, 6662 newRestrictBackground); 6663 } 6664 if (oldBlocked != newBlocked) { 6665 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 6666 encodeBool(newBlocked)); 6667 } 6668 } 6669 } 6670 6671 /** 6672 * Notify apps with a given UID of the new blocked state according to new uid rules. 6673 * @param uid The uid for which the rules changed. 6674 * @param newRules The new rules to apply. 6675 */ maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules)6676 private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) { 6677 for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 6678 final boolean metered = nai.networkCapabilities.isMetered(); 6679 final boolean oldBlocked, newBlocked; 6680 // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid 6681 // rules changed event. And this function actually loop through all connected nai and 6682 // its requests. It seems that mVpns lock will be grabbed frequently in this case. 6683 // Reduce the number of locking or optimize the use of lock are likely needed in future. 6684 synchronized (mVpns) { 6685 oldBlocked = isUidNetworkingWithVpnBlocked( 6686 uid, mUidRules.get(uid), metered, mRestrictBackground); 6687 newBlocked = isUidNetworkingWithVpnBlocked( 6688 uid, newRules, metered, mRestrictBackground); 6689 } 6690 if (oldBlocked == newBlocked) { 6691 continue; 6692 } 6693 final int arg = encodeBool(newBlocked); 6694 for (int i = 0; i < nai.numNetworkRequests(); i++) { 6695 NetworkRequest nr = nai.requestAt(i); 6696 NetworkRequestInfo nri = mNetworkRequests.get(nr); 6697 if (nri != null && nri.mUid == uid) { 6698 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg); 6699 } 6700 } 6701 } 6702 } 6703 6704 @VisibleForTesting sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)6705 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 6706 // The NetworkInfo we actually send out has no bearing on the real 6707 // state of affairs. For example, if the default connection is mobile, 6708 // and a request for HIPRI has just gone away, we need to pretend that 6709 // HIPRI has just disconnected. So we need to set the type to HIPRI and 6710 // the state to DISCONNECTED, even though the network is of type MOBILE 6711 // and is still connected. 6712 NetworkInfo info = new NetworkInfo(nai.networkInfo); 6713 info.setType(type); 6714 if (state != DetailedState.DISCONNECTED) { 6715 info.setDetailedState(state, null, info.getExtraInfo()); 6716 sendConnectedBroadcast(info); 6717 } else { 6718 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 6719 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 6720 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 6721 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 6722 if (info.isFailover()) { 6723 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 6724 nai.networkInfo.setFailover(false); 6725 } 6726 if (info.getReason() != null) { 6727 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 6728 } 6729 if (info.getExtraInfo() != null) { 6730 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 6731 } 6732 NetworkAgentInfo newDefaultAgent = null; 6733 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 6734 newDefaultAgent = getDefaultNetwork(); 6735 if (newDefaultAgent != null) { 6736 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 6737 newDefaultAgent.networkInfo); 6738 } else { 6739 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 6740 } 6741 } 6742 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 6743 mDefaultInetConditionPublished); 6744 sendStickyBroadcast(intent); 6745 if (newDefaultAgent != null) { 6746 sendConnectedBroadcast(newDefaultAgent.networkInfo); 6747 } 6748 } 6749 } 6750 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)6751 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 6752 if (VDBG || DDBG) { 6753 String notification = ConnectivityManager.getCallbackName(notifyType); 6754 log("notifyType " + notification + " for " + networkAgent.name()); 6755 } 6756 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 6757 NetworkRequest nr = networkAgent.requestAt(i); 6758 NetworkRequestInfo nri = mNetworkRequests.get(nr); 6759 if (VDBG) log(" sending notification for " + nr); 6760 // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for 6761 // a network that no longer satisfies the listen? 6762 if (nri.mPendingIntent == null) { 6763 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 6764 } else { 6765 sendPendingIntentForRequest(nri, networkAgent, notifyType); 6766 } 6767 } 6768 } 6769 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)6770 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 6771 notifyNetworkCallbacks(networkAgent, notifyType, 0); 6772 } 6773 6774 /** 6775 * Returns the list of all interfaces that could be used by network traffic that does not 6776 * explicitly specify a network. This includes the default network, but also all VPNs that are 6777 * currently connected. 6778 * 6779 * Must be called on the handler thread. 6780 */ getDefaultNetworks()6781 private Network[] getDefaultNetworks() { 6782 ensureRunningOnConnectivityServiceThread(); 6783 ArrayList<Network> defaultNetworks = new ArrayList<>(); 6784 NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 6785 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 6786 if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) { 6787 defaultNetworks.add(nai.network); 6788 } 6789 } 6790 return defaultNetworks.toArray(new Network[0]); 6791 } 6792 6793 /** 6794 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 6795 * properties tracked by NetworkStatsService on an active iface has changed. 6796 */ notifyIfacesChangedForNetworkStats()6797 private void notifyIfacesChangedForNetworkStats() { 6798 ensureRunningOnConnectivityServiceThread(); 6799 String activeIface = null; 6800 LinkProperties activeLinkProperties = getActiveLinkProperties(); 6801 if (activeLinkProperties != null) { 6802 activeIface = activeLinkProperties.getInterfaceName(); 6803 } 6804 try { 6805 mStatsService.forceUpdateIfaces( 6806 getDefaultNetworks(), getAllVpnInfo(), getAllNetworkState(), activeIface); 6807 } catch (Exception ignored) { 6808 } 6809 } 6810 6811 @Override addVpnAddress(String address, int prefixLength)6812 public boolean addVpnAddress(String address, int prefixLength) { 6813 int user = UserHandle.getUserId(Binder.getCallingUid()); 6814 synchronized (mVpns) { 6815 throwIfLockdownEnabled(); 6816 return mVpns.get(user).addAddress(address, prefixLength); 6817 } 6818 } 6819 6820 @Override removeVpnAddress(String address, int prefixLength)6821 public boolean removeVpnAddress(String address, int prefixLength) { 6822 int user = UserHandle.getUserId(Binder.getCallingUid()); 6823 synchronized (mVpns) { 6824 throwIfLockdownEnabled(); 6825 return mVpns.get(user).removeAddress(address, prefixLength); 6826 } 6827 } 6828 6829 @Override setUnderlyingNetworksForVpn(Network[] networks)6830 public boolean setUnderlyingNetworksForVpn(Network[] networks) { 6831 int user = UserHandle.getUserId(Binder.getCallingUid()); 6832 final boolean success; 6833 synchronized (mVpns) { 6834 throwIfLockdownEnabled(); 6835 success = mVpns.get(user).setUnderlyingNetworks(networks); 6836 } 6837 if (success) { 6838 mHandler.post(() -> { 6839 // Update VPN's capabilities based on updated underlying network set. 6840 updateAllVpnsCapabilities(); 6841 notifyIfacesChangedForNetworkStats(); 6842 }); 6843 } 6844 return success; 6845 } 6846 6847 @Override getCaptivePortalServerUrl()6848 public String getCaptivePortalServerUrl() { 6849 enforceConnectivityInternalPermission(); 6850 String settingUrl = mContext.getResources().getString( 6851 R.string.config_networkCaptivePortalServerUrl); 6852 6853 if (!TextUtils.isEmpty(settingUrl)) { 6854 return settingUrl; 6855 } 6856 6857 settingUrl = Settings.Global.getString(mContext.getContentResolver(), 6858 Settings.Global.CAPTIVE_PORTAL_HTTP_URL); 6859 if (!TextUtils.isEmpty(settingUrl)) { 6860 return settingUrl; 6861 } 6862 6863 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL; 6864 } 6865 6866 @Override startNattKeepalive(Network network, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr)6867 public void startNattKeepalive(Network network, int intervalSeconds, 6868 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { 6869 enforceKeepalivePermission(); 6870 mKeepaliveTracker.startNattKeepalive( 6871 getNetworkAgentInfoForNetwork(network), null /* fd */, 6872 intervalSeconds, cb, 6873 srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT); 6874 } 6875 6876 @Override startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr)6877 public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId, 6878 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, 6879 String dstAddr) { 6880 mKeepaliveTracker.startNattKeepalive( 6881 getNetworkAgentInfoForNetwork(network), fd, resourceId, 6882 intervalSeconds, cb, 6883 srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT); 6884 } 6885 6886 @Override startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds, ISocketKeepaliveCallback cb)6887 public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds, 6888 ISocketKeepaliveCallback cb) { 6889 enforceKeepalivePermission(); 6890 mKeepaliveTracker.startTcpKeepalive( 6891 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); 6892 } 6893 6894 @Override stopKeepalive(Network network, int slot)6895 public void stopKeepalive(Network network, int slot) { 6896 mHandler.sendMessage(mHandler.obtainMessage( 6897 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network)); 6898 } 6899 6900 @Override factoryReset()6901 public void factoryReset() { 6902 enforceConnectivityInternalPermission(); 6903 6904 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 6905 return; 6906 } 6907 6908 final int userId = UserHandle.getCallingUserId(); 6909 6910 Binder.withCleanCallingIdentity(() -> { 6911 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext); 6912 ipMemoryStore.factoryReset(); 6913 }); 6914 6915 // Turn airplane mode off 6916 setAirplaneMode(false); 6917 6918 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) { 6919 // Untether 6920 String pkgName = mContext.getOpPackageName(); 6921 for (String tether : getTetheredIfaces()) { 6922 untether(tether, pkgName); 6923 } 6924 } 6925 6926 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) { 6927 // Remove always-on package 6928 synchronized (mVpns) { 6929 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId); 6930 if (alwaysOnPackage != null) { 6931 setAlwaysOnVpnPackage(userId, null, false, null); 6932 setVpnPackageAuthorization(alwaysOnPackage, userId, false); 6933 } 6934 6935 // Turn Always-on VPN off 6936 if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) { 6937 final long ident = Binder.clearCallingIdentity(); 6938 try { 6939 mKeyStore.delete(Credentials.LOCKDOWN_VPN); 6940 mLockdownEnabled = false; 6941 setLockdownTracker(null); 6942 } finally { 6943 Binder.restoreCallingIdentity(ident); 6944 } 6945 } 6946 6947 // Turn VPN off 6948 VpnConfig vpnConfig = getVpnConfig(userId); 6949 if (vpnConfig != null) { 6950 if (vpnConfig.legacy) { 6951 prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId); 6952 } else { 6953 // Prevent this app (packagename = vpnConfig.user) from initiating 6954 // VPN connections in the future without user intervention. 6955 setVpnPackageAuthorization(vpnConfig.user, userId, false); 6956 6957 prepareVpn(null, VpnConfig.LEGACY_VPN, userId); 6958 } 6959 } 6960 } 6961 } 6962 6963 // restore private DNS settings to default mode (opportunistic) 6964 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) { 6965 Settings.Global.putString(mContext.getContentResolver(), 6966 Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC); 6967 } 6968 6969 Settings.Global.putString(mContext.getContentResolver(), 6970 Settings.Global.NETWORK_AVOID_BAD_WIFI, null); 6971 } 6972 6973 @Override getNetworkWatchlistConfigHash()6974 public byte[] getNetworkWatchlistConfigHash() { 6975 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 6976 if (nwm == null) { 6977 loge("Unable to get NetworkWatchlistManager"); 6978 return null; 6979 } 6980 // Redirect it to network watchlist service to access watchlist file and calculate hash. 6981 return nwm.getWatchlistConfigHash(); 6982 } 6983 6984 @VisibleForTesting createMultinetworkPolicyTracker(Context c, Handler h, Runnable r)6985 MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 6986 return new MultinetworkPolicyTracker(c, h, r); 6987 } 6988 6989 @VisibleForTesting makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj)6990 public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) { 6991 return new WakeupMessage(c, h, s, cmd, 0, 0, obj); 6992 } 6993 6994 @VisibleForTesting hasService(String name)6995 public boolean hasService(String name) { 6996 return ServiceManager.checkService(name) != null; 6997 } 6998 6999 @VisibleForTesting metricsLogger()7000 protected IpConnectivityMetrics.Logger metricsLogger() { 7001 return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), 7002 "no IpConnectivityMetrics service"); 7003 } 7004 logNetworkEvent(NetworkAgentInfo nai, int evtype)7005 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 7006 int[] transports = nai.networkCapabilities.getTransportTypes(); 7007 mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype)); 7008 } 7009 toBool(int encodedBoolean)7010 private static boolean toBool(int encodedBoolean) { 7011 return encodedBoolean != 0; // Only 0 means false. 7012 } 7013 encodeBool(boolean b)7014 private static int encodeBool(boolean b) { 7015 return b ? 1 : 0; 7016 } 7017 7018 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)7019 public void onShellCommand(FileDescriptor in, FileDescriptor out, 7020 FileDescriptor err, String[] args, ShellCallback callback, 7021 ResultReceiver resultReceiver) { 7022 (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); 7023 } 7024 7025 private class ShellCmd extends ShellCommand { 7026 7027 @Override onCommand(String cmd)7028 public int onCommand(String cmd) { 7029 if (cmd == null) { 7030 return handleDefaultCommands(cmd); 7031 } 7032 final PrintWriter pw = getOutPrintWriter(); 7033 try { 7034 switch (cmd) { 7035 case "airplane-mode": 7036 final String action = getNextArg(); 7037 if ("enable".equals(action)) { 7038 setAirplaneMode(true); 7039 return 0; 7040 } else if ("disable".equals(action)) { 7041 setAirplaneMode(false); 7042 return 0; 7043 } else if (action == null) { 7044 final ContentResolver cr = mContext.getContentResolver(); 7045 final int enabled = Settings.Global.getInt(cr, 7046 Settings.Global.AIRPLANE_MODE_ON); 7047 pw.println(enabled == 0 ? "disabled" : "enabled"); 7048 return 0; 7049 } else { 7050 onHelp(); 7051 return -1; 7052 } 7053 default: 7054 return handleDefaultCommands(cmd); 7055 } 7056 } catch (Exception e) { 7057 pw.println(e); 7058 } 7059 return -1; 7060 } 7061 7062 @Override onHelp()7063 public void onHelp() { 7064 PrintWriter pw = getOutPrintWriter(); 7065 pw.println("Connectivity service commands:"); 7066 pw.println(" help"); 7067 pw.println(" Print this help text."); 7068 pw.println(" airplane-mode [enable|disable]"); 7069 pw.println(" Turn airplane mode on or off."); 7070 pw.println(" airplane-mode"); 7071 pw.println(" Get airplane mode."); 7072 } 7073 } 7074 7075 @GuardedBy("mVpns") getVpnIfOwner()7076 private Vpn getVpnIfOwner() { 7077 final int uid = Binder.getCallingUid(); 7078 final int user = UserHandle.getUserId(uid); 7079 7080 final Vpn vpn = mVpns.get(user); 7081 if (vpn == null) { 7082 return null; 7083 } else { 7084 final VpnInfo info = vpn.getVpnInfo(); 7085 return (info == null || info.ownerUid != uid) ? null : vpn; 7086 } 7087 } 7088 7089 /** 7090 * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission 7091 * for testing. 7092 */ enforceActiveVpnOrNetworkStackPermission()7093 private Vpn enforceActiveVpnOrNetworkStackPermission() { 7094 if (checkNetworkStackPermission()) { 7095 return null; 7096 } 7097 synchronized (mVpns) { 7098 Vpn vpn = getVpnIfOwner(); 7099 if (vpn != null) { 7100 return vpn; 7101 } 7102 } 7103 throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK " 7104 + "permission"); 7105 } 7106 7107 /** 7108 * @param connectionInfo the connection to resolve. 7109 * @return {@code uid} if the connection is found and the app has permission to observe it 7110 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the 7111 * connection is not found. 7112 */ getConnectionOwnerUid(ConnectionInfo connectionInfo)7113 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { 7114 final Vpn vpn = enforceActiveVpnOrNetworkStackPermission(); 7115 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { 7116 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); 7117 } 7118 7119 final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol, 7120 connectionInfo.local, connectionInfo.remote); 7121 7122 /* Filter out Uids not associated with the VPN. */ 7123 if (vpn != null && !vpn.appliesToUid(uid)) { 7124 return INVALID_UID; 7125 } 7126 7127 return uid; 7128 } 7129 7130 @Override isCallerCurrentAlwaysOnVpnApp()7131 public boolean isCallerCurrentAlwaysOnVpnApp() { 7132 synchronized (mVpns) { 7133 Vpn vpn = getVpnIfOwner(); 7134 return vpn != null && vpn.getAlwaysOn(); 7135 } 7136 } 7137 7138 @Override isCallerCurrentAlwaysOnVpnLockdownApp()7139 public boolean isCallerCurrentAlwaysOnVpnLockdownApp() { 7140 synchronized (mVpns) { 7141 Vpn vpn = getVpnIfOwner(); 7142 return vpn != null && vpn.getLockdown(); 7143 } 7144 } 7145 7146 /** 7147 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. 7148 * 7149 * <p>The TestNetworkService must be run in the system server due to TUN creation. 7150 */ 7151 @Override startOrGetTestNetworkService()7152 public IBinder startOrGetTestNetworkService() { 7153 synchronized (mTNSLock) { 7154 TestNetworkService.enforceTestNetworkPermissions(mContext); 7155 7156 if (mTNS == null) { 7157 mTNS = new TestNetworkService(mContext, mNMS); 7158 } 7159 7160 return mTNS; 7161 } 7162 } 7163 } 7164