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