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