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.FEATURE_BLUETOOTH; 21 import static android.content.pm.PackageManager.FEATURE_WATCH; 22 import static android.content.pm.PackageManager.FEATURE_WIFI; 23 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 24 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 25 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; 26 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK; 27 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT; 28 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS; 29 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS; 30 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS; 31 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS; 32 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE; 33 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 34 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; 35 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 36 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 37 import static android.net.ConnectivityManager.TYPE_BLUETOOTH; 38 import static android.net.ConnectivityManager.TYPE_ETHERNET; 39 import static android.net.ConnectivityManager.TYPE_MOBILE; 40 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS; 41 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 42 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY; 43 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 44 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 45 import static android.net.ConnectivityManager.TYPE_MOBILE_IA; 46 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS; 47 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 48 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 49 import static android.net.ConnectivityManager.TYPE_NONE; 50 import static android.net.ConnectivityManager.TYPE_PROXY; 51 import static android.net.ConnectivityManager.TYPE_VPN; 52 import static android.net.ConnectivityManager.TYPE_WIFI; 53 import static android.net.ConnectivityManager.TYPE_WIFI_P2P; 54 import static android.net.ConnectivityManager.getNetworkTypeName; 55 import static android.net.ConnectivityManager.isNetworkTypeValid; 56 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 57 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 58 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 59 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 60 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 61 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 62 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 63 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 64 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 65 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 66 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 67 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 68 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 69 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 70 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 71 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 72 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 73 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 74 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 75 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 76 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 77 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 78 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 79 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 80 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 81 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 82 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; 83 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 84 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 85 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired; 86 import static android.os.Process.INVALID_UID; 87 import static android.os.Process.VPN_UID; 88 import static android.system.OsConstants.IPPROTO_TCP; 89 import static android.system.OsConstants.IPPROTO_UDP; 90 91 import static java.util.Map.Entry; 92 93 import android.Manifest; 94 import android.annotation.NonNull; 95 import android.annotation.Nullable; 96 import android.app.AppOpsManager; 97 import android.app.BroadcastOptions; 98 import android.app.PendingIntent; 99 import android.app.usage.NetworkStatsManager; 100 import android.content.BroadcastReceiver; 101 import android.content.ComponentName; 102 import android.content.ContentResolver; 103 import android.content.Context; 104 import android.content.Intent; 105 import android.content.IntentFilter; 106 import android.content.pm.PackageManager; 107 import android.database.ContentObserver; 108 import android.net.CaptivePortal; 109 import android.net.CaptivePortalData; 110 import android.net.ConnectionInfo; 111 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 112 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 113 import android.net.ConnectivityManager; 114 import android.net.ConnectivityManager.BlockedReason; 115 import android.net.ConnectivityManager.NetworkCallback; 116 import android.net.ConnectivityManager.RestrictBackgroundStatus; 117 import android.net.ConnectivityResources; 118 import android.net.ConnectivitySettingsManager; 119 import android.net.DataStallReportParcelable; 120 import android.net.DnsResolverServiceManager; 121 import android.net.ICaptivePortal; 122 import android.net.IConnectivityDiagnosticsCallback; 123 import android.net.IConnectivityManager; 124 import android.net.IDnsResolver; 125 import android.net.INetd; 126 import android.net.INetworkActivityListener; 127 import android.net.INetworkAgent; 128 import android.net.INetworkMonitor; 129 import android.net.INetworkMonitorCallbacks; 130 import android.net.INetworkOfferCallback; 131 import android.net.IOnCompleteListener; 132 import android.net.IQosCallback; 133 import android.net.ISocketKeepaliveCallback; 134 import android.net.InetAddresses; 135 import android.net.IpMemoryStore; 136 import android.net.IpPrefix; 137 import android.net.LinkProperties; 138 import android.net.MatchAllNetworkSpecifier; 139 import android.net.NativeNetworkConfig; 140 import android.net.NativeNetworkType; 141 import android.net.NattSocketKeepalive; 142 import android.net.Network; 143 import android.net.NetworkAgent; 144 import android.net.NetworkAgentConfig; 145 import android.net.NetworkCapabilities; 146 import android.net.NetworkInfo; 147 import android.net.NetworkInfo.DetailedState; 148 import android.net.NetworkMonitorManager; 149 import android.net.NetworkPolicyManager; 150 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 151 import android.net.NetworkProvider; 152 import android.net.NetworkRequest; 153 import android.net.NetworkScore; 154 import android.net.NetworkSpecifier; 155 import android.net.NetworkStack; 156 import android.net.NetworkState; 157 import android.net.NetworkStateSnapshot; 158 import android.net.NetworkTestResultParcelable; 159 import android.net.NetworkUtils; 160 import android.net.NetworkWatchlistManager; 161 import android.net.OemNetworkPreferences; 162 import android.net.PrivateDnsConfigParcel; 163 import android.net.ProxyInfo; 164 import android.net.QosCallbackException; 165 import android.net.QosFilter; 166 import android.net.QosSocketFilter; 167 import android.net.QosSocketInfo; 168 import android.net.RouteInfo; 169 import android.net.RouteInfoParcel; 170 import android.net.SocketKeepalive; 171 import android.net.TetheringManager; 172 import android.net.TransportInfo; 173 import android.net.UidRange; 174 import android.net.UidRangeParcel; 175 import android.net.UnderlyingNetworkInfo; 176 import android.net.Uri; 177 import android.net.VpnManager; 178 import android.net.VpnTransportInfo; 179 import android.net.metrics.IpConnectivityLog; 180 import android.net.metrics.NetworkEvent; 181 import android.net.netd.aidl.NativeUidRangeConfig; 182 import android.net.netlink.InetDiagMessage; 183 import android.net.networkstack.ModuleNetworkStackClient; 184 import android.net.networkstack.NetworkStackClientBase; 185 import android.net.resolv.aidl.DnsHealthEventParcel; 186 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; 187 import android.net.resolv.aidl.Nat64PrefixEventParcel; 188 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 189 import android.net.shared.PrivateDnsConfig; 190 import android.net.util.MultinetworkPolicyTracker; 191 import android.os.BatteryStatsManager; 192 import android.os.Binder; 193 import android.os.Build; 194 import android.os.Bundle; 195 import android.os.Handler; 196 import android.os.HandlerThread; 197 import android.os.IBinder; 198 import android.os.Looper; 199 import android.os.Message; 200 import android.os.Messenger; 201 import android.os.ParcelFileDescriptor; 202 import android.os.Parcelable; 203 import android.os.PersistableBundle; 204 import android.os.PowerManager; 205 import android.os.Process; 206 import android.os.RemoteCallbackList; 207 import android.os.RemoteException; 208 import android.os.ServiceSpecificException; 209 import android.os.SystemClock; 210 import android.os.SystemProperties; 211 import android.os.UserHandle; 212 import android.os.UserManager; 213 import android.provider.Settings; 214 import android.sysprop.NetworkProperties; 215 import android.telephony.TelephonyManager; 216 import android.text.TextUtils; 217 import android.util.ArrayMap; 218 import android.util.ArraySet; 219 import android.util.LocalLog; 220 import android.util.Log; 221 import android.util.Pair; 222 import android.util.SparseArray; 223 import android.util.SparseIntArray; 224 225 import com.android.connectivity.resources.R; 226 import com.android.internal.annotations.GuardedBy; 227 import com.android.internal.annotations.VisibleForTesting; 228 import com.android.internal.util.IndentingPrintWriter; 229 import com.android.internal.util.MessageUtils; 230 import com.android.modules.utils.BasicShellCommandHandler; 231 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 232 import com.android.net.module.util.CollectionUtils; 233 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; 234 import com.android.net.module.util.LinkPropertiesUtils.CompareResult; 235 import com.android.net.module.util.LocationPermissionChecker; 236 import com.android.net.module.util.NetworkCapabilitiesUtils; 237 import com.android.net.module.util.PermissionUtils; 238 import com.android.server.connectivity.AutodestructReference; 239 import com.android.server.connectivity.DnsManager; 240 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; 241 import com.android.server.connectivity.FullScore; 242 import com.android.server.connectivity.KeepaliveTracker; 243 import com.android.server.connectivity.LingerMonitor; 244 import com.android.server.connectivity.MockableSystemProperties; 245 import com.android.server.connectivity.NetworkAgentInfo; 246 import com.android.server.connectivity.NetworkDiagnostics; 247 import com.android.server.connectivity.NetworkNotificationManager; 248 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 249 import com.android.server.connectivity.NetworkOffer; 250 import com.android.server.connectivity.NetworkRanker; 251 import com.android.server.connectivity.PermissionMonitor; 252 import com.android.server.connectivity.ProfileNetworkPreferences; 253 import com.android.server.connectivity.ProxyTracker; 254 import com.android.server.connectivity.QosCallbackTracker; 255 256 import libcore.io.IoUtils; 257 258 import java.io.FileDescriptor; 259 import java.io.PrintWriter; 260 import java.net.Inet4Address; 261 import java.net.InetAddress; 262 import java.net.InetSocketAddress; 263 import java.net.UnknownHostException; 264 import java.util.ArrayList; 265 import java.util.Arrays; 266 import java.util.Collection; 267 import java.util.Collections; 268 import java.util.Comparator; 269 import java.util.ConcurrentModificationException; 270 import java.util.HashMap; 271 import java.util.HashSet; 272 import java.util.List; 273 import java.util.Map; 274 import java.util.Objects; 275 import java.util.Set; 276 import java.util.SortedSet; 277 import java.util.StringJoiner; 278 import java.util.TreeSet; 279 import java.util.concurrent.atomic.AtomicInteger; 280 281 /** 282 * @hide 283 */ 284 public class ConnectivityService extends IConnectivityManager.Stub 285 implements PendingIntent.OnFinished { 286 private static final String TAG = ConnectivityService.class.getSimpleName(); 287 288 private static final String DIAG_ARG = "--diag"; 289 public static final String SHORT_ARG = "--short"; 290 private static final String NETWORK_ARG = "networks"; 291 private static final String REQUEST_ARG = "requests"; 292 293 private static final boolean DBG = true; 294 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); 295 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 296 297 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 298 299 /** 300 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed 301 * by OEMs for configuration purposes, as this value is overridden by 302 * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL. 303 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose 304 * (preferably via runtime resource overlays). 305 */ 306 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL = 307 "http://connectivitycheck.gstatic.com/generate_204"; 308 309 // TODO: create better separation between radio types and network types 310 311 // how long to wait before switching back to a radio's default network 312 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 313 // system property that can override the above value 314 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 315 "android.telephony.apn-restore"; 316 317 // How long to wait before putting up a "This network doesn't have an Internet connection, 318 // connect anyway?" dialog after the user selects a network that doesn't validate. 319 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 320 321 // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing. 322 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 323 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 324 private static final int DEFAULT_NASCENT_DELAY_MS = 5_000; 325 326 // The maximum number of network request allowed per uid before an exception is thrown. 327 @VisibleForTesting 328 static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 329 330 // The maximum number of network request allowed for system UIDs before an exception is thrown. 331 @VisibleForTesting 332 static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250; 333 334 @VisibleForTesting 335 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 336 @VisibleForTesting 337 protected int mNascentDelayMs; 338 339 // How long to delay to removal of a pending intent based request. 340 // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 341 private final int mReleasePendingIntentDelayMs; 342 343 private MockableSystemProperties mSystemProperties; 344 345 @VisibleForTesting 346 protected final PermissionMonitor mPermissionMonitor; 347 348 @VisibleForTesting 349 final PerUidCounter mNetworkRequestCounter; 350 @VisibleForTesting 351 final PerUidCounter mSystemNetworkRequestCounter; 352 353 private volatile boolean mLockdownEnabled; 354 355 /** 356 * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in 357 * internal handler thread, they don't need a lock. 358 */ 359 private SparseIntArray mUidBlockedReasons = new SparseIntArray(); 360 361 private final Context mContext; 362 private final ConnectivityResources mResources; 363 // The Context is created for UserHandle.ALL. 364 private final Context mUserAllContext; 365 private final Dependencies mDeps; 366 // 0 is full bad, 100 is full good 367 private int mDefaultInetConditionPublished = 0; 368 369 @VisibleForTesting 370 protected IDnsResolver mDnsResolver; 371 @VisibleForTesting 372 protected INetd mNetd; 373 private NetworkStatsManager mStatsManager; 374 private NetworkPolicyManager mPolicyManager; 375 private final NetdCallback mNetdCallback; 376 377 /** 378 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple 379 * instances. 380 */ 381 @GuardedBy("mTNSLock") 382 private TestNetworkService mTNS; 383 384 private final Object mTNSLock = new Object(); 385 386 private String mCurrentTcpBufferSizes; 387 388 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 389 new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class }); 390 391 private enum ReapUnvalidatedNetworks { 392 // Tear down networks that have no chance (e.g. even if validated) of becoming 393 // the highest scoring network satisfying a NetworkRequest. This should be passed when 394 // all networks have been rematched against all NetworkRequests. 395 REAP, 396 // Don't reap networks. This should be passed when some networks have not yet been 397 // rematched against all NetworkRequests. 398 DONT_REAP 399 } 400 401 private enum UnneededFor { 402 LINGER, // Determine whether this network is unneeded and should be lingered. 403 TEARDOWN, // Determine whether this network is unneeded and should be torn down. 404 } 405 406 /** 407 * For per-app preferences, requests contain an int to signify which request 408 * should have priority. The priority is passed to netd which will use it 409 * together with UID ranges to generate the corresponding IP rule. This serves 410 * to direct device-originated data traffic of the specific UIDs to the correct 411 * default network for each app. 412 * Priorities passed to netd must be in the 0~999 range. Larger values code for 413 * a lower priority, {@see NativeUidRangeConfig} 414 * 415 * Requests that don't code for a per-app preference use PREFERENCE_PRIORITY_INVALID. 416 * The default request uses PREFERENCE_PRIORITY_DEFAULT. 417 */ 418 // Bound for the lowest valid priority. 419 static final int PREFERENCE_PRIORITY_LOWEST = 999; 420 // Used when sending to netd to code for "no priority". 421 static final int PREFERENCE_PRIORITY_NONE = 0; 422 // Priority for requests that don't code for a per-app preference. As it is 423 // out of the valid range, the corresponding priority should be 424 // PREFERENCE_PRIORITY_NONE when sending to netd. 425 @VisibleForTesting 426 static final int PREFERENCE_PRIORITY_INVALID = Integer.MAX_VALUE; 427 // Priority for the default internet request. Since this must always have the 428 // lowest priority, its value is larger than the largest acceptable value. As 429 // it is out of the valid range, the corresponding priority should be 430 // PREFERENCE_PRIORITY_NONE when sending to netd. 431 static final int PREFERENCE_PRIORITY_DEFAULT = 1000; 432 // As a security feature, VPNs have the top priority. 433 static final int PREFERENCE_PRIORITY_VPN = 0; // Netd supports only 0 for VPN. 434 // Priority of per-app OEM preference. See {@link #setOemNetworkPreference}. 435 @VisibleForTesting 436 static final int PREFERENCE_PRIORITY_OEM = 10; 437 // Priority of per-profile preference, such as used by enterprise networks. 438 // See {@link #setProfileNetworkPreference}. 439 @VisibleForTesting 440 static final int PREFERENCE_PRIORITY_PROFILE = 20; 441 // Priority of user setting to prefer mobile data even when networks with 442 // better scores are connected. 443 // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids} 444 @VisibleForTesting 445 static final int PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED = 30; 446 447 /** 448 * used internally to clear a wakelock when transitioning 449 * from one net to another. Clear happens when we get a new 450 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 451 * after a timeout if no network is found (typically 1 min). 452 */ 453 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 454 455 /** 456 * used internally to reload global proxy settings 457 */ 458 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 459 460 /** 461 * PAC manager has received new port. 462 */ 463 private static final int EVENT_PROXY_HAS_CHANGED = 16; 464 465 /** 466 * used internally when registering NetworkProviders 467 * obj = NetworkProviderInfo 468 */ 469 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; 470 471 /** 472 * used internally when registering NetworkAgents 473 * obj = Messenger 474 */ 475 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 476 477 /** 478 * used to add a network request 479 * includes a NetworkRequestInfo 480 */ 481 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 482 483 /** 484 * indicates a timeout period is over - check if we had a network yet or not 485 * and if not, call the timeout callback (but leave the request live until they 486 * cancel it. 487 * includes a NetworkRequestInfo 488 */ 489 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 490 491 /** 492 * used to add a network listener - no request 493 * includes a NetworkRequestInfo 494 */ 495 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 496 497 /** 498 * used to remove a network request, either a listener or a real request 499 * arg1 = UID of caller 500 * obj = NetworkRequest 501 */ 502 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 503 504 /** 505 * used internally when registering NetworkProviders 506 * obj = Messenger 507 */ 508 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; 509 510 /** 511 * used internally to expire a wakelock when transitioning 512 * from one net to another. Expire happens when we fail to find 513 * a new network (typically after 1 minute) - 514 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 515 * a replacement network. 516 */ 517 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 518 519 /** 520 * used to add a network request with a pending intent 521 * obj = NetworkRequestInfo 522 */ 523 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 524 525 /** 526 * used to remove a pending intent and its associated network request. 527 * arg1 = UID of caller 528 * obj = PendingIntent 529 */ 530 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 531 532 /** 533 * used to specify whether a network should be used even if unvalidated. 534 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 535 * arg2 = whether to remember this choice in the future (1 or 0) 536 * obj = network 537 */ 538 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 539 540 /** 541 * used to ask the user to confirm a connection to an unvalidated network. 542 * obj = network 543 */ 544 private static final int EVENT_PROMPT_UNVALIDATED = 29; 545 546 /** 547 * used internally to (re)configure always-on networks. 548 */ 549 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; 550 551 /** 552 * used to add a network listener with a pending intent 553 * obj = NetworkRequestInfo 554 */ 555 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 556 557 /** 558 * used to specify whether a network should not be penalized when it becomes unvalidated. 559 */ 560 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 561 562 /** 563 * used to trigger revalidation of a network. 564 */ 565 private static final int EVENT_REVALIDATE_NETWORK = 36; 566 567 // Handle changes in Private DNS settings. 568 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; 569 570 // Handle private DNS validation status updates. 571 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; 572 573 /** 574 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has 575 * been tested. 576 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor. 577 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link 578 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null. 579 */ 580 private static final int EVENT_NETWORK_TESTED = 41; 581 582 /** 583 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS 584 * config was resolved. 585 * obj = PrivateDnsConfig 586 * arg2 = netid 587 */ 588 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; 589 590 /** 591 * Request ConnectivityService display provisioning notification. 592 * arg1 = Whether to make the notification visible. 593 * arg2 = NetID. 594 * obj = Intent to be launched when notification selected by user, null if !arg1. 595 */ 596 private static final int EVENT_PROVISIONING_NOTIFICATION = 43; 597 598 /** 599 * Used to specify whether a network should be used even if connectivity is partial. 600 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for 601 * false) 602 * arg2 = whether to remember this choice in the future (1 for true or 0 for false) 603 * obj = network 604 */ 605 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44; 606 607 /** 608 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed. 609 * Both of the arguments are bitmasks, and the value of bits come from 610 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*. 611 * arg1 = A bitmask to describe which probes are completed. 612 * arg2 = A bitmask to describe which probes are successful. 613 */ 614 public static final int EVENT_PROBE_STATUS_CHANGED = 45; 615 616 /** 617 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed. 618 * arg1 = unused 619 * arg2 = netId 620 * obj = captive portal data 621 */ 622 private static final int EVENT_CAPPORT_DATA_CHANGED = 46; 623 624 /** 625 * Used by setRequireVpnForUids. 626 * arg1 = whether the specified UID ranges are required to use a VPN. 627 * obj = Array of UidRange objects. 628 */ 629 private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47; 630 631 /** 632 * Used internally when setting the default networks for OemNetworkPreferences. 633 * obj = Pair<OemNetworkPreferences, listener> 634 */ 635 private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48; 636 637 /** 638 * Used to indicate the system default network becomes active. 639 */ 640 private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49; 641 642 /** 643 * Used internally when setting a network preference for a user profile. 644 * obj = Pair<ProfileNetworkPreference, Listener> 645 */ 646 private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50; 647 648 /** 649 * Event to specify that reasons for why an uid is blocked changed. 650 * arg1 = uid 651 * arg2 = blockedReasons 652 */ 653 private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51; 654 655 /** 656 * Event to register a new network offer 657 * obj = NetworkOffer 658 */ 659 private static final int EVENT_REGISTER_NETWORK_OFFER = 52; 660 661 /** 662 * Event to unregister an existing network offer 663 * obj = INetworkOfferCallback 664 */ 665 private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53; 666 667 /** 668 * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed. 669 */ 670 private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54; 671 672 /** 673 * Event to set temporary allow bad wifi within a limited time to override 674 * {@code config_networkAvoidBadWifi}. 675 */ 676 private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55; 677 678 /** 679 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 680 * should be shown. 681 */ 682 private static final int PROVISIONING_NOTIFICATION_SHOW = 1; 683 684 /** 685 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 686 * should be hidden. 687 */ 688 private static final int PROVISIONING_NOTIFICATION_HIDE = 0; 689 690 /** 691 * The maximum alive time to allow bad wifi configuration for testing. 692 */ 693 private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L; 694 eventName(int what)695 private static String eventName(int what) { 696 return sMagicDecoderRing.get(what, Integer.toString(what)); 697 } 698 getDnsResolver(Context context)699 private static IDnsResolver getDnsResolver(Context context) { 700 final DnsResolverServiceManager dsm = context.getSystemService( 701 DnsResolverServiceManager.class); 702 return IDnsResolver.Stub.asInterface(dsm.getService()); 703 } 704 705 /** Handler thread used for all of the handlers below. */ 706 @VisibleForTesting 707 protected final HandlerThread mHandlerThread; 708 /** Handler used for internal events. */ 709 final private InternalHandler mHandler; 710 /** Handler used for incoming {@link NetworkStateTracker} events. */ 711 final private NetworkStateTrackerHandler mTrackerHandler; 712 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */ 713 @VisibleForTesting 714 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler; 715 716 private final DnsManager mDnsManager; 717 private final NetworkRanker mNetworkRanker; 718 719 private boolean mSystemReady; 720 private Intent mInitialBroadcast; 721 722 private PowerManager.WakeLock mNetTransitionWakeLock; 723 private final PowerManager.WakeLock mPendingIntentWakeLock; 724 725 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell 726 // the world when it changes. 727 @VisibleForTesting 728 protected final ProxyTracker mProxyTracker; 729 730 final private SettingsObserver mSettingsObserver; 731 732 private UserManager mUserManager; 733 734 // the set of network types that can only be enabled by system/sig apps 735 private List<Integer> mProtectedNetworks; 736 737 private Set<String> mWolSupportedInterfaces; 738 739 private final TelephonyManager mTelephonyManager; 740 private final AppOpsManager mAppOpsManager; 741 742 private final LocationPermissionChecker mLocationPermissionChecker; 743 744 private KeepaliveTracker mKeepaliveTracker; 745 private QosCallbackTracker mQosCallbackTracker; 746 private NetworkNotificationManager mNotifier; 747 private LingerMonitor mLingerMonitor; 748 749 // sequence number of NetworkRequests 750 private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID; 751 752 // Sequence number for NetworkProvider IDs. 753 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( 754 NetworkProvider.FIRST_PROVIDER_ID); 755 756 // NetworkRequest activity String log entries. 757 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 758 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 759 760 // NetworkInfo blocked and unblocked String log entries 761 private static final int MAX_NETWORK_INFO_LOGS = 40; 762 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 763 764 private static final int MAX_WAKELOCK_LOGS = 20; 765 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS); 766 private int mTotalWakelockAcquisitions = 0; 767 private int mTotalWakelockReleases = 0; 768 private long mTotalWakelockDurationMs = 0; 769 private long mMaxWakelockDurationMs = 0; 770 private long mLastWakeLockAcquireTimestamp = 0; 771 772 private final IpConnectivityLog mMetricsLog; 773 774 @GuardedBy("mBandwidthRequests") 775 private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10); 776 777 @VisibleForTesting 778 final MultinetworkPolicyTracker mMultinetworkPolicyTracker; 779 780 @VisibleForTesting 781 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks = 782 new HashMap<>(); 783 784 /** 785 * Implements support for the legacy "one network per network type" model. 786 * 787 * We used to have a static array of NetworkStateTrackers, one for each 788 * network type, but that doesn't work any more now that we can have, 789 * for example, more that one wifi network. This class stores all the 790 * NetworkAgentInfo objects that support a given type, but the legacy 791 * API will only see the first one. 792 * 793 * It serves two main purposes: 794 * 795 * 1. Provide information about "the network for a given type" (since this 796 * API only supports one). 797 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 798 * the first network for a given type changes, or if the default network 799 * changes. 800 */ 801 @VisibleForTesting 802 static class LegacyTypeTracker { 803 804 private static final boolean DBG = true; 805 private static final boolean VDBG = false; 806 807 /** 808 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 809 * Each list holds references to all NetworkAgentInfos that are used to 810 * satisfy requests for that network type. 811 * 812 * This array is built out at startup such that an unsupported network 813 * doesn't get an ArrayList instance, making this a tristate: 814 * unsupported, supported but not active and active. 815 * 816 * The actual lists are populated when we scan the network types that 817 * are supported on this device. 818 * 819 * Threading model: 820 * - addSupportedType() is only called in the constructor 821 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 822 * They are therefore not thread-safe with respect to each other. 823 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 824 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 825 * - getRestoreTimerForType(type) is also synchronized on mTypeLists. 826 * - dump is thread-safe with respect to concurrent add and remove calls. 827 */ 828 private final ArrayList<NetworkAgentInfo> mTypeLists[]; 829 @NonNull 830 private final ConnectivityService mService; 831 832 // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without 833 // an entry have no timer (equivalent to -1). Lazily loaded. 834 @NonNull 835 private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>(); 836 LegacyTypeTracker(@onNull ConnectivityService service)837 LegacyTypeTracker(@NonNull ConnectivityService service) { 838 mService = service; 839 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 840 } 841 loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)842 public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) { 843 final PackageManager pm = ctx.getPackageManager(); 844 if (pm.hasSystemFeature(FEATURE_WIFI)) { 845 addSupportedType(TYPE_WIFI); 846 } 847 if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) { 848 addSupportedType(TYPE_WIFI_P2P); 849 } 850 if (tm.isDataCapable()) { 851 // Telephony does not have granular support for these types: they are either all 852 // supported, or none is supported 853 addSupportedType(TYPE_MOBILE); 854 addSupportedType(TYPE_MOBILE_MMS); 855 addSupportedType(TYPE_MOBILE_SUPL); 856 addSupportedType(TYPE_MOBILE_DUN); 857 addSupportedType(TYPE_MOBILE_HIPRI); 858 addSupportedType(TYPE_MOBILE_FOTA); 859 addSupportedType(TYPE_MOBILE_IMS); 860 addSupportedType(TYPE_MOBILE_CBS); 861 addSupportedType(TYPE_MOBILE_IA); 862 addSupportedType(TYPE_MOBILE_EMERGENCY); 863 } 864 if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) { 865 addSupportedType(TYPE_BLUETOOTH); 866 } 867 if (pm.hasSystemFeature(FEATURE_WATCH)) { 868 // TYPE_PROXY is only used on Wear 869 addSupportedType(TYPE_PROXY); 870 } 871 // Ethernet is often not specified in the configs, although many devices can use it via 872 // USB host adapters. Add it as long as the ethernet service is here. 873 if (ctx.getSystemService(Context.ETHERNET_SERVICE) != null) { 874 addSupportedType(TYPE_ETHERNET); 875 } 876 877 // Always add TYPE_VPN as a supported type 878 addSupportedType(TYPE_VPN); 879 } 880 addSupportedType(int type)881 private void addSupportedType(int type) { 882 if (mTypeLists[type] != null) { 883 throw new IllegalStateException( 884 "legacy list for type " + type + "already initialized"); 885 } 886 mTypeLists[type] = new ArrayList<>(); 887 } 888 isTypeSupported(int type)889 public boolean isTypeSupported(int type) { 890 return isNetworkTypeValid(type) && mTypeLists[type] != null; 891 } 892 getNetworkForType(int type)893 public NetworkAgentInfo getNetworkForType(int type) { 894 synchronized (mTypeLists) { 895 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 896 return mTypeLists[type].get(0); 897 } 898 } 899 return null; 900 } 901 getRestoreTimerForType(int type)902 public int getRestoreTimerForType(int type) { 903 synchronized (mTypeLists) { 904 if (mRestoreTimers == null) { 905 mRestoreTimers = loadRestoreTimers(); 906 } 907 return mRestoreTimers.getOrDefault(type, -1); 908 } 909 } 910 loadRestoreTimers()911 private ArrayMap<Integer, Integer> loadRestoreTimers() { 912 final String[] configs = mService.mResources.get().getStringArray( 913 R.array.config_legacy_networktype_restore_timers); 914 final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length); 915 for (final String config : configs) { 916 final String[] splits = TextUtils.split(config, ","); 917 if (splits.length != 2) { 918 logwtf("Invalid restore timer token count: " + config); 919 continue; 920 } 921 try { 922 ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1])); 923 } catch (NumberFormatException e) { 924 logwtf("Invalid restore timer number format: " + config, e); 925 } 926 } 927 return ret; 928 } 929 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)930 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 931 boolean isDefaultNetwork) { 932 if (DBG) { 933 log("Sending " + state 934 + " broadcast for type " + type + " " + nai.toShortString() 935 + " isDefaultNetwork=" + isDefaultNetwork); 936 } 937 } 938 939 // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying 940 // network type, to preserve previous behaviour. maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)941 private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) { 942 if (vpnNai != mService.getLegacyLockdownNai()) return; 943 944 if (vpnNai.declaredUnderlyingNetworks == null 945 || vpnNai.declaredUnderlyingNetworks.length != 1) { 946 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: " 947 + Arrays.toString(vpnNai.declaredUnderlyingNetworks)); 948 return; 949 } 950 final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork( 951 vpnNai.declaredUnderlyingNetworks[0]); 952 if (underlyingNai == null) return; 953 954 final int type = underlyingNai.networkInfo.getType(); 955 final DetailedState state = DetailedState.CONNECTED; 956 maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */); 957 mService.sendLegacyNetworkBroadcast(underlyingNai, state, type); 958 } 959 960 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)961 public void add(int type, NetworkAgentInfo nai) { 962 if (!isTypeSupported(type)) { 963 return; // Invalid network type. 964 } 965 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 966 967 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 968 if (list.contains(nai)) { 969 return; 970 } 971 synchronized (mTypeLists) { 972 list.add(nai); 973 } 974 975 // Send a broadcast if this is the first network of its type or if it's the default. 976 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); 977 978 // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts 979 // to preserve previous behaviour. 980 final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED); 981 if ((list.size() == 1) || isDefaultNetwork) { 982 maybeLogBroadcast(nai, state, type, isDefaultNetwork); 983 mService.sendLegacyNetworkBroadcast(nai, state, type); 984 } 985 986 if (type == TYPE_VPN && state == DetailedState.CONNECTED) { 987 maybeSendLegacyLockdownBroadcast(nai); 988 } 989 } 990 991 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)992 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 993 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 994 if (list == null || list.isEmpty()) { 995 return; 996 } 997 final boolean wasFirstNetwork = list.get(0).equals(nai); 998 999 synchronized (mTypeLists) { 1000 if (!list.remove(nai)) { 1001 return; 1002 } 1003 } 1004 1005 if (wasFirstNetwork || wasDefault) { 1006 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault); 1007 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type); 1008 } 1009 1010 if (!list.isEmpty() && wasFirstNetwork) { 1011 if (DBG) log("Other network available for type " + type + 1012 ", sending connected broadcast"); 1013 final NetworkAgentInfo replacement = list.get(0); 1014 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type, 1015 mService.isDefaultNetwork(replacement)); 1016 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type); 1017 } 1018 } 1019 1020 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)1021 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 1022 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 1023 for (int type = 0; type < mTypeLists.length; type++) { 1024 remove(type, nai, wasDefault); 1025 } 1026 } 1027 1028 // send out another legacy broadcast - currently only used for suspend/unsuspend 1029 // toggle update(NetworkAgentInfo nai)1030 public void update(NetworkAgentInfo nai) { 1031 final boolean isDefault = mService.isDefaultNetwork(nai); 1032 final DetailedState state = nai.networkInfo.getDetailedState(); 1033 for (int type = 0; type < mTypeLists.length; type++) { 1034 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1035 final boolean contains = (list != null && list.contains(nai)); 1036 final boolean isFirst = contains && (nai == list.get(0)); 1037 if (isFirst || contains && isDefault) { 1038 maybeLogBroadcast(nai, state, type, isDefault); 1039 mService.sendLegacyNetworkBroadcast(nai, state, type); 1040 } 1041 } 1042 } 1043 dump(IndentingPrintWriter pw)1044 public void dump(IndentingPrintWriter pw) { 1045 pw.println("mLegacyTypeTracker:"); 1046 pw.increaseIndent(); 1047 pw.print("Supported types:"); 1048 for (int type = 0; type < mTypeLists.length; type++) { 1049 if (mTypeLists[type] != null) pw.print(" " + type); 1050 } 1051 pw.println(); 1052 pw.println("Current state:"); 1053 pw.increaseIndent(); 1054 synchronized (mTypeLists) { 1055 for (int type = 0; type < mTypeLists.length; type++) { 1056 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 1057 for (NetworkAgentInfo nai : mTypeLists[type]) { 1058 pw.println(type + " " + nai.toShortString()); 1059 } 1060 } 1061 } 1062 pw.decreaseIndent(); 1063 pw.decreaseIndent(); 1064 pw.println(); 1065 } 1066 } 1067 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this); 1068 1069 final LocalPriorityDump mPriorityDumper = new LocalPriorityDump(); 1070 /** 1071 * Helper class which parses out priority arguments and dumps sections according to their 1072 * priority. If priority arguments are omitted, function calls the legacy dump command. 1073 */ 1074 private class LocalPriorityDump { 1075 private static final String PRIORITY_ARG = "--dump-priority"; 1076 private static final String PRIORITY_ARG_HIGH = "HIGH"; 1077 private static final String PRIORITY_ARG_NORMAL = "NORMAL"; 1078 LocalPriorityDump()1079 LocalPriorityDump() {} 1080 dumpHigh(FileDescriptor fd, PrintWriter pw)1081 private void dumpHigh(FileDescriptor fd, PrintWriter pw) { 1082 doDump(fd, pw, new String[] {DIAG_ARG}); 1083 doDump(fd, pw, new String[] {SHORT_ARG}); 1084 } 1085 dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1086 private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { 1087 doDump(fd, pw, args); 1088 } 1089 dump(FileDescriptor fd, PrintWriter pw, String[] args)1090 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1091 if (args == null) { 1092 dumpNormal(fd, pw, args); 1093 return; 1094 } 1095 1096 String priority = null; 1097 for (int argIndex = 0; argIndex < args.length; argIndex++) { 1098 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) { 1099 argIndex++; 1100 priority = args[argIndex]; 1101 } 1102 } 1103 1104 if (PRIORITY_ARG_HIGH.equals(priority)) { 1105 dumpHigh(fd, pw); 1106 } else if (PRIORITY_ARG_NORMAL.equals(priority)) { 1107 dumpNormal(fd, pw, args); 1108 } else { 1109 // ConnectivityService publishes binder service using publishBinderService() with 1110 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send 1111 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the 1112 // legacy output for dumpsys connectivity. 1113 // TODO: Integrate into signal dump. 1114 dumpNormal(fd, pw, args); 1115 } 1116 } 1117 } 1118 1119 /** 1120 * Keeps track of the number of requests made under different uids. 1121 */ 1122 public static class PerUidCounter { 1123 private final int mMaxCountPerUid; 1124 1125 // Map from UID to number of NetworkRequests that UID has filed. 1126 @VisibleForTesting 1127 @GuardedBy("mUidToNetworkRequestCount") 1128 final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); 1129 1130 /** 1131 * Constructor 1132 * 1133 * @param maxCountPerUid the maximum count per uid allowed 1134 */ PerUidCounter(final int maxCountPerUid)1135 public PerUidCounter(final int maxCountPerUid) { 1136 mMaxCountPerUid = maxCountPerUid; 1137 } 1138 1139 /** 1140 * Increments the request count of the given uid. Throws an exception if the number 1141 * of open requests for the uid exceeds the value of maxCounterPerUid which is the value 1142 * passed into the constructor. see: {@link #PerUidCounter(int)}. 1143 * 1144 * @throws ServiceSpecificException with 1145 * {@link ConnectivityManager.Errors.TOO_MANY_REQUESTS} if the number of requests for 1146 * the uid exceed the allowed number. 1147 * 1148 * @param uid the uid that the request was made under 1149 */ incrementCountOrThrow(final int uid)1150 public void incrementCountOrThrow(final int uid) { 1151 synchronized (mUidToNetworkRequestCount) { 1152 incrementCountOrThrow(uid, 1 /* numToIncrement */); 1153 } 1154 } 1155 incrementCountOrThrow(final int uid, final int numToIncrement)1156 private void incrementCountOrThrow(final int uid, final int numToIncrement) { 1157 final int newRequestCount = 1158 mUidToNetworkRequestCount.get(uid, 0) + numToIncrement; 1159 if (newRequestCount >= mMaxCountPerUid 1160 // HACK : the system server is allowed to go over the request count limit 1161 // when it is creating requests on behalf of another app (but not itself, 1162 // so it can still detect its own request leaks). This only happens in the 1163 // per-app API flows in which case the old requests for that particular 1164 // UID will be removed soon. 1165 // TODO : instead of this hack, addPerAppDefaultNetworkRequests and other 1166 // users of transact() should unregister the requests to decrease the count 1167 // before they increase it again by creating a new NRI. Then remove the 1168 // transact() method. 1169 && (Process.myUid() == uid || Process.myUid() != Binder.getCallingUid())) { 1170 throw new ServiceSpecificException( 1171 ConnectivityManager.Errors.TOO_MANY_REQUESTS, 1172 "Uid " + uid + " exceeded its allotted requests limit"); 1173 } 1174 mUidToNetworkRequestCount.put(uid, newRequestCount); 1175 } 1176 1177 /** 1178 * Decrements the request count of the given uid. 1179 * 1180 * @param uid the uid that the request was made under 1181 */ decrementCount(final int uid)1182 public void decrementCount(final int uid) { 1183 synchronized (mUidToNetworkRequestCount) { 1184 decrementCount(uid, 1 /* numToDecrement */); 1185 } 1186 } 1187 decrementCount(final int uid, final int numToDecrement)1188 private void decrementCount(final int uid, final int numToDecrement) { 1189 final int newRequestCount = 1190 mUidToNetworkRequestCount.get(uid, 0) - numToDecrement; 1191 if (newRequestCount < 0) { 1192 logwtf("BUG: too small request count " + newRequestCount + " for UID " + uid); 1193 } else if (newRequestCount == 0) { 1194 mUidToNetworkRequestCount.delete(uid); 1195 } else { 1196 mUidToNetworkRequestCount.put(uid, newRequestCount); 1197 } 1198 } 1199 1200 /** 1201 * Used to adjust the request counter for the per-app API flows. Directly adjusting the 1202 * counter is not ideal however in the per-app flows, the nris can't be removed until they 1203 * are used to create the new nris upon set. Therefore the request count limit can be 1204 * artificially hit. This method is used as a workaround for this particular case so that 1205 * the request counts are accounted for correctly. 1206 * @param uid the uid to adjust counts for 1207 * @param numOfNewRequests the new request count to account for 1208 * @param r the runnable to execute 1209 */ transact(final int uid, final int numOfNewRequests, @NonNull final Runnable r)1210 public void transact(final int uid, final int numOfNewRequests, @NonNull final Runnable r) { 1211 // This should only be used on the handler thread as per all current and foreseen 1212 // use-cases. ensureRunningOnConnectivityServiceThread() can't be used because there is 1213 // no ref to the outer ConnectivityService. 1214 synchronized (mUidToNetworkRequestCount) { 1215 final int reqCountOverage = getCallingUidRequestCountOverage(uid, numOfNewRequests); 1216 decrementCount(uid, reqCountOverage); 1217 r.run(); 1218 incrementCountOrThrow(uid, reqCountOverage); 1219 } 1220 } 1221 getCallingUidRequestCountOverage(final int uid, final int numOfNewRequests)1222 private int getCallingUidRequestCountOverage(final int uid, final int numOfNewRequests) { 1223 final int newUidRequestCount = mUidToNetworkRequestCount.get(uid, 0) 1224 + numOfNewRequests; 1225 return newUidRequestCount >= MAX_NETWORK_REQUESTS_PER_SYSTEM_UID 1226 ? newUidRequestCount - (MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1) : 0; 1227 } 1228 } 1229 1230 /** 1231 * Dependencies of ConnectivityService, for injection in tests. 1232 */ 1233 @VisibleForTesting 1234 public static class Dependencies { getCallingUid()1235 public int getCallingUid() { 1236 return Binder.getCallingUid(); 1237 } 1238 1239 /** 1240 * Get system properties to use in ConnectivityService. 1241 */ getSystemProperties()1242 public MockableSystemProperties getSystemProperties() { 1243 return new MockableSystemProperties(); 1244 } 1245 1246 /** 1247 * Get the {@link ConnectivityResources} to use in ConnectivityService. 1248 */ getResources(@onNull Context ctx)1249 public ConnectivityResources getResources(@NonNull Context ctx) { 1250 return new ConnectivityResources(ctx); 1251 } 1252 1253 /** 1254 * Create a HandlerThread to use in ConnectivityService. 1255 */ makeHandlerThread()1256 public HandlerThread makeHandlerThread() { 1257 return new HandlerThread("ConnectivityServiceThread"); 1258 } 1259 1260 /** 1261 * Get a reference to the ModuleNetworkStackClient. 1262 */ getNetworkStack()1263 public NetworkStackClientBase getNetworkStack() { 1264 return ModuleNetworkStackClient.getInstance(null); 1265 } 1266 1267 /** 1268 * @see ProxyTracker 1269 */ makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1270 public ProxyTracker makeProxyTracker(@NonNull Context context, 1271 @NonNull Handler connServiceHandler) { 1272 return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED); 1273 } 1274 1275 /** 1276 * @see NetIdManager 1277 */ makeNetIdManager()1278 public NetIdManager makeNetIdManager() { 1279 return new NetIdManager(); 1280 } 1281 1282 /** 1283 * @see NetworkUtils#queryUserAccess(int, int) 1284 */ queryUserAccess(int uid, Network network, ConnectivityService cs)1285 public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) { 1286 return cs.queryUserAccess(uid, network); 1287 } 1288 1289 /** 1290 * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets 1291 * requires CAP_NET_ADMIN, which the unit tests do not have. 1292 */ getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1293 public int getConnectionOwnerUid(int protocol, InetSocketAddress local, 1294 InetSocketAddress remote) { 1295 return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote); 1296 } 1297 1298 /** 1299 * @see MultinetworkPolicyTracker 1300 */ makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1301 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( 1302 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { 1303 return new MultinetworkPolicyTracker(c, h, r); 1304 } 1305 1306 /** 1307 * @see BatteryStatsManager 1308 */ reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1309 public void reportNetworkInterfaceForTransports(Context context, String iface, 1310 int[] transportTypes) { 1311 final BatteryStatsManager batteryStats = 1312 context.getSystemService(BatteryStatsManager.class); 1313 batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes); 1314 } 1315 getCellular464XlatEnabled()1316 public boolean getCellular464XlatEnabled() { 1317 return NetworkProperties.isCellular464XlatEnabled().orElse(true); 1318 } 1319 1320 /** 1321 * @see PendingIntent#intentFilterEquals 1322 */ intentFilterEquals(PendingIntent a, PendingIntent b)1323 public boolean intentFilterEquals(PendingIntent a, PendingIntent b) { 1324 return a.intentFilterEquals(b); 1325 } 1326 1327 /** 1328 * @see LocationPermissionChecker 1329 */ makeLocationPermissionChecker(Context context)1330 public LocationPermissionChecker makeLocationPermissionChecker(Context context) { 1331 return new LocationPermissionChecker(context); 1332 } 1333 } 1334 ConnectivityService(Context context)1335 public ConnectivityService(Context context) { 1336 this(context, getDnsResolver(context), new IpConnectivityLog(), 1337 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), 1338 new Dependencies()); 1339 } 1340 1341 @VisibleForTesting ConnectivityService(Context context, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps)1342 protected ConnectivityService(Context context, IDnsResolver dnsresolver, 1343 IpConnectivityLog logger, INetd netd, Dependencies deps) { 1344 if (DBG) log("ConnectivityService starting up"); 1345 1346 mDeps = Objects.requireNonNull(deps, "missing Dependencies"); 1347 mSystemProperties = mDeps.getSystemProperties(); 1348 mNetIdManager = mDeps.makeNetIdManager(); 1349 mContext = Objects.requireNonNull(context, "missing Context"); 1350 mResources = deps.getResources(mContext); 1351 mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID); 1352 mSystemNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID); 1353 1354 mMetricsLog = logger; 1355 mNetworkRanker = new NetworkRanker(); 1356 final NetworkRequest defaultInternetRequest = createDefaultRequest(); 1357 mDefaultRequest = new NetworkRequestInfo( 1358 Process.myUid(), defaultInternetRequest, null, 1359 new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1360 null /* attributionTags */); 1361 mNetworkRequests.put(defaultInternetRequest, mDefaultRequest); 1362 mDefaultNetworkRequests.add(mDefaultRequest); 1363 mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest); 1364 1365 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( 1366 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); 1367 1368 // The default WiFi request is a background request so that apps using WiFi are 1369 // migrated to a better network (typically ethernet) when one comes up, instead 1370 // of staying on WiFi forever. 1371 mDefaultWifiRequest = createDefaultInternetRequestForTransport( 1372 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); 1373 1374 mDefaultVehicleRequest = createAlwaysOnRequestForCapability( 1375 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL, 1376 NetworkRequest.Type.BACKGROUND_REQUEST); 1377 1378 mHandlerThread = mDeps.makeHandlerThread(); 1379 mHandlerThread.start(); 1380 mHandler = new InternalHandler(mHandlerThread.getLooper()); 1381 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 1382 mConnectivityDiagnosticsHandler = 1383 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper()); 1384 1385 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 1386 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 1387 1388 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 1389 // TODO: Consider making the timer customizable. 1390 mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS; 1391 1392 mStatsManager = mContext.getSystemService(NetworkStatsManager.class); 1393 mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); 1394 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver"); 1395 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); 1396 1397 mNetd = netd; 1398 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1399 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 1400 mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); 1401 1402 // To ensure uid state is synchronized with Network Policy, register for 1403 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService 1404 // reading existing policy from disk. 1405 mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback); 1406 1407 final PowerManager powerManager = (PowerManager) context.getSystemService( 1408 Context.POWER_SERVICE); 1409 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1410 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1411 1412 mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager); 1413 mProtectedNetworks = new ArrayList<>(); 1414 int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks); 1415 for (int p : protectedNetworks) { 1416 if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) { 1417 mProtectedNetworks.add(p); 1418 } else { 1419 if (DBG) loge("Ignoring protectedNetwork " + p); 1420 } 1421 } 1422 1423 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 1424 1425 mPermissionMonitor = new PermissionMonitor(mContext, mNetd); 1426 1427 mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */); 1428 // Listen for user add/removes to inform PermissionMonitor. 1429 // Should run on mHandler to avoid any races. 1430 final IntentFilter userIntentFilter = new IntentFilter(); 1431 userIntentFilter.addAction(Intent.ACTION_USER_ADDED); 1432 userIntentFilter.addAction(Intent.ACTION_USER_REMOVED); 1433 mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter, 1434 null /* broadcastPermission */, mHandler); 1435 1436 // Listen to package add/removes for netd 1437 final IntentFilter packageIntentFilter = new IntentFilter(); 1438 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 1439 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1440 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 1441 packageIntentFilter.addDataScheme("package"); 1442 mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter, 1443 null /* broadcastPermission */, mHandler); 1444 1445 mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd); 1446 1447 mNetdCallback = new NetdCallback(); 1448 try { 1449 mNetd.registerUnsolicitedEventListener(mNetdCallback); 1450 } catch (RemoteException | ServiceSpecificException e) { 1451 loge("Error registering event listener :" + e); 1452 } 1453 1454 mSettingsObserver = new SettingsObserver(mContext, mHandler); 1455 registerSettingsCallbacks(); 1456 1457 mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler); 1458 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager); 1459 mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter); 1460 1461 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 1462 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 1463 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 1464 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 1465 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 1466 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 1467 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 1468 1469 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( 1470 mContext, mHandler, () -> updateAvoidBadWifi()); 1471 mMultinetworkPolicyTracker.start(); 1472 1473 mDnsManager = new DnsManager(mContext, mDnsResolver); 1474 registerPrivateDnsSettingsCallbacks(); 1475 1476 // This NAI is a sentinel used to offer no service to apps that are on a multi-layer 1477 // request that doesn't allow fallback to the default network. It should never be visible 1478 // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal 1479 // arguments like the handler or the DnsResolver. 1480 // TODO : remove this ; it is probably better handled with a sentinel request. 1481 mNoServiceNetwork = new NetworkAgentInfo(null, 1482 new Network(INetd.UNREACHABLE_NET_ID), 1483 new NetworkInfo(TYPE_NONE, 0, "", ""), 1484 new LinkProperties(), new NetworkCapabilities(), 1485 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, 1486 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, 1487 mLingerDelayMs, mQosCallbackTracker, mDeps); 1488 } 1489 createDefaultNetworkCapabilitiesForUid(int uid)1490 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { 1491 return createDefaultNetworkCapabilitiesForUidRange(new UidRange(uid, uid)); 1492 } 1493 createDefaultNetworkCapabilitiesForUidRange( @onNull final UidRange uids)1494 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRange( 1495 @NonNull final UidRange uids) { 1496 final NetworkCapabilities netCap = new NetworkCapabilities(); 1497 netCap.addCapability(NET_CAPABILITY_INTERNET); 1498 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 1499 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 1500 netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids))); 1501 return netCap; 1502 } 1503 createDefaultRequest()1504 private NetworkRequest createDefaultRequest() { 1505 return createDefaultInternetRequestForTransport( 1506 TYPE_NONE, NetworkRequest.Type.REQUEST); 1507 } 1508 createDefaultInternetRequestForTransport( int transportType, NetworkRequest.Type type)1509 private NetworkRequest createDefaultInternetRequestForTransport( 1510 int transportType, NetworkRequest.Type type) { 1511 final NetworkCapabilities netCap = new NetworkCapabilities(); 1512 netCap.addCapability(NET_CAPABILITY_INTERNET); 1513 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 1514 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 1515 if (transportType > TYPE_NONE) { 1516 netCap.addTransportType(transportType); 1517 } 1518 return createNetworkRequest(type, netCap); 1519 } 1520 createNetworkRequest( NetworkRequest.Type type, NetworkCapabilities netCap)1521 private NetworkRequest createNetworkRequest( 1522 NetworkRequest.Type type, NetworkCapabilities netCap) { 1523 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 1524 } 1525 createAlwaysOnRequestForCapability(int capability, NetworkRequest.Type type)1526 private NetworkRequest createAlwaysOnRequestForCapability(int capability, 1527 NetworkRequest.Type type) { 1528 final NetworkCapabilities netCap = new NetworkCapabilities(); 1529 netCap.clearAll(); 1530 netCap.addCapability(capability); 1531 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 1532 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 1533 } 1534 1535 // Used only for testing. 1536 // TODO: Delete this and either: 1537 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires 1538 // changing ContentResolver to make registerContentObserver non-final). 1539 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 1540 // by subclassing SettingsObserver. 1541 @VisibleForTesting updateAlwaysOnNetworks()1542 void updateAlwaysOnNetworks() { 1543 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1544 } 1545 1546 // See FakeSettingsProvider comment above. 1547 @VisibleForTesting updatePrivateDnsSettings()1548 void updatePrivateDnsSettings() { 1549 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1550 } 1551 1552 @VisibleForTesting updateMobileDataPreferredUids()1553 void updateMobileDataPreferredUids() { 1554 mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 1555 } 1556 handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id)1557 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id) { 1558 final boolean enable = mContext.getResources().getBoolean(id); 1559 handleAlwaysOnNetworkRequest(networkRequest, enable); 1560 } 1561 handleAlwaysOnNetworkRequest( NetworkRequest networkRequest, String settingName, boolean defaultValue)1562 private void handleAlwaysOnNetworkRequest( 1563 NetworkRequest networkRequest, String settingName, boolean defaultValue) { 1564 final boolean enable = toBool(Settings.Global.getInt( 1565 mContext.getContentResolver(), settingName, encodeBool(defaultValue))); 1566 handleAlwaysOnNetworkRequest(networkRequest, enable); 1567 } 1568 handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable)1569 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) { 1570 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); 1571 if (enable == isEnabled) { 1572 return; // Nothing to do. 1573 } 1574 1575 if (enable) { 1576 handleRegisterNetworkRequest(new NetworkRequestInfo( 1577 Process.myUid(), networkRequest, null, new Binder(), 1578 NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1579 null /* attributionTags */)); 1580 } else { 1581 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, 1582 /* callOnUnavailable */ false); 1583 } 1584 } 1585 handleConfigureAlwaysOnNetworks()1586 private void handleConfigureAlwaysOnNetworks() { 1587 handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest, 1588 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */); 1589 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, 1590 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */); 1591 final boolean vehicleAlwaysRequested = mResources.get().getBoolean( 1592 R.bool.config_vehicleInternalNetworkAlwaysRequested); 1593 handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested); 1594 } 1595 1596 // Note that registering observer for setting do not get initial callback when registering, 1597 // callers must fetch the initial value of the setting themselves if needed. registerSettingsCallbacks()1598 private void registerSettingsCallbacks() { 1599 // Watch for global HTTP proxy changes. 1600 mSettingsObserver.observe( 1601 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 1602 EVENT_APPLY_GLOBAL_HTTP_PROXY); 1603 1604 // Watch for whether or not to keep mobile data always on. 1605 mSettingsObserver.observe( 1606 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON), 1607 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1608 1609 // Watch for whether or not to keep wifi always on. 1610 mSettingsObserver.observe( 1611 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED), 1612 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1613 1614 // Watch for mobile data preferred uids changes. 1615 mSettingsObserver.observe( 1616 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS), 1617 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 1618 } 1619 registerPrivateDnsSettingsCallbacks()1620 private void registerPrivateDnsSettingsCallbacks() { 1621 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { 1622 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1623 } 1624 } 1625 nextNetworkRequestId()1626 private synchronized int nextNetworkRequestId() { 1627 // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if 1628 // doing that. 1629 return mNextNetworkRequestId++; 1630 } 1631 1632 @VisibleForTesting getNetworkAgentInfoForNetwork(Network network)1633 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 1634 if (network == null) { 1635 return null; 1636 } 1637 return getNetworkAgentInfoForNetId(network.getNetId()); 1638 } 1639 getNetworkAgentInfoForNetId(int netId)1640 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { 1641 synchronized (mNetworkForNetId) { 1642 return mNetworkForNetId.get(netId); 1643 } 1644 } 1645 1646 // TODO: determine what to do when more than one VPN applies to |uid|. getVpnForUid(int uid)1647 private NetworkAgentInfo getVpnForUid(int uid) { 1648 synchronized (mNetworkForNetId) { 1649 for (int i = 0; i < mNetworkForNetId.size(); i++) { 1650 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 1651 if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) { 1652 return nai; 1653 } 1654 } 1655 } 1656 return null; 1657 } 1658 getVpnUnderlyingNetworks(int uid)1659 private Network[] getVpnUnderlyingNetworks(int uid) { 1660 if (mLockdownEnabled) return null; 1661 final NetworkAgentInfo nai = getVpnForUid(uid); 1662 if (nai != null) return nai.declaredUnderlyingNetworks; 1663 return null; 1664 } 1665 getNetworkAgentInfoForUid(int uid)1666 private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) { 1667 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 1668 1669 final Network[] networks = getVpnUnderlyingNetworks(uid); 1670 if (networks != null) { 1671 // getUnderlyingNetworks() returns: 1672 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 1673 // empty array => the VPN explicitly said "no default network". 1674 // non-empty array => the VPN specified one or more default networks; we use the 1675 // first one. 1676 if (networks.length > 0) { 1677 nai = getNetworkAgentInfoForNetwork(networks[0]); 1678 } else { 1679 nai = null; 1680 } 1681 } 1682 return nai; 1683 } 1684 1685 /** 1686 * Check if UID should be blocked from using the specified network. 1687 */ isNetworkWithCapabilitiesBlocked(@ullable final NetworkCapabilities nc, final int uid, final boolean ignoreBlocked)1688 private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc, 1689 final int uid, final boolean ignoreBlocked) { 1690 // Networks aren't blocked when ignoring blocked status 1691 if (ignoreBlocked) { 1692 return false; 1693 } 1694 if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true; 1695 final long ident = Binder.clearCallingIdentity(); 1696 try { 1697 final boolean metered = nc == null ? true : nc.isMetered(); 1698 return mPolicyManager.isUidNetworkingBlocked(uid, metered); 1699 } finally { 1700 Binder.restoreCallingIdentity(ident); 1701 } 1702 } 1703 maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid)1704 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 1705 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 1706 return; 1707 } 1708 final boolean blocked; 1709 synchronized (mBlockedAppUids) { 1710 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 1711 blocked = true; 1712 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 1713 blocked = false; 1714 } else { 1715 return; 1716 } 1717 } 1718 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 1719 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid)); 1720 mNetworkInfoBlockingLogs.log(action + " " + uid); 1721 } 1722 maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked)1723 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) { 1724 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { 1725 return; 1726 } 1727 final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED"; 1728 final int requestId = nri.getActiveRequest() != null 1729 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId; 1730 mNetworkInfoBlockingLogs.log(String.format( 1731 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(), 1732 Integer.toHexString(blocked))); 1733 } 1734 1735 /** 1736 * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For 1737 * example, this may mark the network as {@link DetailedState#BLOCKED} based 1738 * on {@link #isNetworkWithCapabilitiesBlocked}. 1739 */ 1740 @NonNull filterNetworkInfo(@onNull NetworkInfo networkInfo, int type, @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked)1741 private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type, 1742 @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) { 1743 final NetworkInfo filtered = new NetworkInfo(networkInfo); 1744 // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network 1745 // but only exists if an app asks about them or requests them. Ensure the requesting app 1746 // gets the type it asks for. 1747 filtered.setType(type); 1748 if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) { 1749 filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */, 1750 null /* extraInfo */); 1751 } 1752 filterForLegacyLockdown(filtered); 1753 return filtered; 1754 } 1755 getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, boolean ignoreBlocked)1756 private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, 1757 boolean ignoreBlocked) { 1758 return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), 1759 nai.networkCapabilities, uid, ignoreBlocked); 1760 } 1761 1762 /** 1763 * Return NetworkInfo for the active (i.e., connected) network interface. 1764 * It is assumed that at most one network is active at a time. If more 1765 * than one is active, it is indeterminate which will be returned. 1766 * @return the info for the active network, or {@code null} if none is 1767 * active 1768 */ 1769 @Override getActiveNetworkInfo()1770 public NetworkInfo getActiveNetworkInfo() { 1771 enforceAccessPermission(); 1772 final int uid = mDeps.getCallingUid(); 1773 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 1774 if (nai == null) return null; 1775 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 1776 maybeLogBlockedNetworkInfo(networkInfo, uid); 1777 return networkInfo; 1778 } 1779 1780 @Override getActiveNetwork()1781 public Network getActiveNetwork() { 1782 enforceAccessPermission(); 1783 return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false); 1784 } 1785 1786 @Override getActiveNetworkForUid(int uid, boolean ignoreBlocked)1787 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 1788 PermissionUtils.enforceNetworkStackPermission(mContext); 1789 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 1790 } 1791 getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked)1792 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 1793 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 1794 if (vpnNai != null) { 1795 final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid); 1796 if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) { 1797 return vpnNai.network; 1798 } 1799 } 1800 1801 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 1802 if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, 1803 ignoreBlocked)) { 1804 return null; 1805 } 1806 return nai.network; 1807 } 1808 1809 @Override getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked)1810 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 1811 PermissionUtils.enforceNetworkStackPermission(mContext); 1812 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 1813 if (nai == null) return null; 1814 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 1815 } 1816 1817 /** Returns a NetworkInfo object for a network that doesn't exist. */ makeFakeNetworkInfo(int networkType, int uid)1818 private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) { 1819 final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */, 1820 getNetworkTypeName(networkType), "" /* subtypeName */); 1821 info.setIsAvailable(true); 1822 // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when 1823 // background data is restricted. 1824 final NetworkCapabilities nc = new NetworkCapabilities(); // Metered. 1825 final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false) 1826 ? DetailedState.BLOCKED 1827 : DetailedState.DISCONNECTED; 1828 info.setDetailedState(state, null /* reason */, null /* extraInfo */); 1829 filterForLegacyLockdown(info); 1830 return info; 1831 } 1832 getFilteredNetworkInfoForType(int networkType, int uid)1833 private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) { 1834 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 1835 return null; 1836 } 1837 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1838 if (nai == null) { 1839 return makeFakeNetworkInfo(networkType, uid); 1840 } 1841 return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid, 1842 false); 1843 } 1844 1845 @Override getNetworkInfo(int networkType)1846 public NetworkInfo getNetworkInfo(int networkType) { 1847 enforceAccessPermission(); 1848 final int uid = mDeps.getCallingUid(); 1849 if (getVpnUnderlyingNetworks(uid) != null) { 1850 // A VPN is active, so we may need to return one of its underlying networks. This 1851 // information is not available in LegacyTypeTracker, so we have to get it from 1852 // getNetworkAgentInfoForUid. 1853 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 1854 if (nai == null) return null; 1855 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 1856 if (networkInfo.getType() == networkType) { 1857 return networkInfo; 1858 } 1859 } 1860 return getFilteredNetworkInfoForType(networkType, uid); 1861 } 1862 1863 @Override getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked)1864 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 1865 enforceAccessPermission(); 1866 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1867 if (nai == null) return null; 1868 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 1869 } 1870 1871 @Override getAllNetworkInfo()1872 public NetworkInfo[] getAllNetworkInfo() { 1873 enforceAccessPermission(); 1874 final ArrayList<NetworkInfo> result = new ArrayList<>(); 1875 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 1876 networkType++) { 1877 NetworkInfo info = getNetworkInfo(networkType); 1878 if (info != null) { 1879 result.add(info); 1880 } 1881 } 1882 return result.toArray(new NetworkInfo[result.size()]); 1883 } 1884 1885 @Override getNetworkForType(int networkType)1886 public Network getNetworkForType(int networkType) { 1887 enforceAccessPermission(); 1888 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 1889 return null; 1890 } 1891 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1892 if (nai == null) { 1893 return null; 1894 } 1895 final int uid = mDeps.getCallingUid(); 1896 if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) { 1897 return null; 1898 } 1899 return nai.network; 1900 } 1901 1902 @Override getAllNetworks()1903 public Network[] getAllNetworks() { 1904 enforceAccessPermission(); 1905 synchronized (mNetworkForNetId) { 1906 final Network[] result = new Network[mNetworkForNetId.size()]; 1907 for (int i = 0; i < mNetworkForNetId.size(); i++) { 1908 result[i] = mNetworkForNetId.valueAt(i).network; 1909 } 1910 return result; 1911 } 1912 } 1913 1914 @Override getDefaultNetworkCapabilitiesForUser( int userId, String callingPackageName, @Nullable String callingAttributionTag)1915 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser( 1916 int userId, String callingPackageName, @Nullable String callingAttributionTag) { 1917 // The basic principle is: if an app's traffic could possibly go over a 1918 // network, without the app doing anything multinetwork-specific, 1919 // (hence, by "default"), then include that network's capabilities in 1920 // the array. 1921 // 1922 // In the normal case, app traffic only goes over the system's default 1923 // network connection, so that's the only network returned. 1924 // 1925 // With a VPN in force, some app traffic may go into the VPN, and thus 1926 // over whatever underlying networks the VPN specifies, while other app 1927 // traffic may go over the system default network (e.g.: a split-tunnel 1928 // VPN, or an app disallowed by the VPN), so the set of networks 1929 // returned includes the VPN's underlying networks and the system 1930 // default. 1931 enforceAccessPermission(); 1932 1933 HashMap<Network, NetworkCapabilities> result = new HashMap<>(); 1934 1935 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 1936 if (!nri.isBeingSatisfied()) { 1937 continue; 1938 } 1939 final NetworkAgentInfo nai = nri.getSatisfier(); 1940 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 1941 if (null != nc 1942 && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 1943 && !result.containsKey(nai.network)) { 1944 result.put( 1945 nai.network, 1946 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 1947 nc, false /* includeLocationSensitiveInfo */, 1948 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 1949 callingAttributionTag)); 1950 } 1951 } 1952 1953 // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null. 1954 final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid()); 1955 if (null != networks) { 1956 for (final Network network : networks) { 1957 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 1958 if (null != nc) { 1959 result.put( 1960 network, 1961 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 1962 nc, 1963 false /* includeLocationSensitiveInfo */, 1964 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 1965 callingAttributionTag)); 1966 } 1967 } 1968 } 1969 1970 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 1971 out = result.values().toArray(out); 1972 return out; 1973 } 1974 1975 @Override isNetworkSupported(int networkType)1976 public boolean isNetworkSupported(int networkType) { 1977 enforceAccessPermission(); 1978 return mLegacyTypeTracker.isTypeSupported(networkType); 1979 } 1980 1981 /** 1982 * Return LinkProperties for the active (i.e., connected) default 1983 * network interface for the calling uid. 1984 * @return the ip properties for the active network, or {@code null} if 1985 * none is active 1986 */ 1987 @Override getActiveLinkProperties()1988 public LinkProperties getActiveLinkProperties() { 1989 enforceAccessPermission(); 1990 final int uid = mDeps.getCallingUid(); 1991 NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 1992 if (nai == null) return null; 1993 return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties, 1994 Binder.getCallingPid(), uid); 1995 } 1996 1997 @Override getLinkPropertiesForType(int networkType)1998 public LinkProperties getLinkPropertiesForType(int networkType) { 1999 enforceAccessPermission(); 2000 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2001 final LinkProperties lp = getLinkProperties(nai); 2002 if (lp == null) return null; 2003 return linkPropertiesRestrictedForCallerPermissions( 2004 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2005 } 2006 2007 // TODO - this should be ALL networks 2008 @Override getLinkProperties(Network network)2009 public LinkProperties getLinkProperties(Network network) { 2010 enforceAccessPermission(); 2011 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network)); 2012 if (lp == null) return null; 2013 return linkPropertiesRestrictedForCallerPermissions( 2014 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2015 } 2016 2017 @Nullable getLinkProperties(@ullable NetworkAgentInfo nai)2018 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) { 2019 if (nai == null) { 2020 return null; 2021 } 2022 synchronized (nai) { 2023 return nai.linkProperties; 2024 } 2025 } 2026 getNetworkCapabilitiesInternal(Network network)2027 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) { 2028 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 2029 } 2030 getNetworkCapabilitiesInternal(NetworkAgentInfo nai)2031 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 2032 if (nai == null) return null; 2033 synchronized (nai) { 2034 return networkCapabilitiesRestrictedForCallerPermissions( 2035 nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid()); 2036 } 2037 } 2038 2039 @Override getNetworkCapabilities(Network network, String callingPackageName, @Nullable String callingAttributionTag)2040 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName, 2041 @Nullable String callingAttributionTag) { 2042 mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName); 2043 enforceAccessPermission(); 2044 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2045 getNetworkCapabilitiesInternal(network), 2046 false /* includeLocationSensitiveInfo */, 2047 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag); 2048 } 2049 2050 @VisibleForTesting networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid)2051 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( 2052 NetworkCapabilities nc, int callerPid, int callerUid) { 2053 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 2054 if (!checkSettingsPermission(callerPid, callerUid)) { 2055 newNc.setUids(null); 2056 newNc.setSSID(null); 2057 } 2058 if (newNc.getNetworkSpecifier() != null) { 2059 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); 2060 } 2061 newNc.setAdministratorUids(new int[0]); 2062 if (!checkAnyPermissionOf( 2063 callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) { 2064 newNc.setSubscriptionIds(Collections.emptySet()); 2065 } 2066 2067 return newNc; 2068 } 2069 2070 /** 2071 * Wrapper used to cache the permission check results performed for the corresponding 2072 * app. This avoid performing multiple permission checks for different fields in 2073 * NetworkCapabilities. 2074 * Note: This wrapper does not support any sort of invalidation and thus must not be 2075 * persistent or long-lived. It may only be used for the time necessary to 2076 * compute the redactions required by one particular NetworkCallback or 2077 * synchronous call. 2078 */ 2079 private class RedactionPermissionChecker { 2080 private final int mCallingPid; 2081 private final int mCallingUid; 2082 @NonNull private final String mCallingPackageName; 2083 @Nullable private final String mCallingAttributionTag; 2084 2085 private Boolean mHasLocationPermission = null; 2086 private Boolean mHasLocalMacAddressPermission = null; 2087 private Boolean mHasSettingsPermission = null; 2088 RedactionPermissionChecker(int callingPid, int callingUid, @NonNull String callingPackageName, @Nullable String callingAttributionTag)2089 RedactionPermissionChecker(int callingPid, int callingUid, 2090 @NonNull String callingPackageName, @Nullable String callingAttributionTag) { 2091 mCallingPid = callingPid; 2092 mCallingUid = callingUid; 2093 mCallingPackageName = callingPackageName; 2094 mCallingAttributionTag = callingAttributionTag; 2095 } 2096 hasLocationPermissionInternal()2097 private boolean hasLocationPermissionInternal() { 2098 final long token = Binder.clearCallingIdentity(); 2099 try { 2100 return mLocationPermissionChecker.checkLocationPermission( 2101 mCallingPackageName, mCallingAttributionTag, mCallingUid, 2102 null /* message */); 2103 } finally { 2104 Binder.restoreCallingIdentity(token); 2105 } 2106 } 2107 2108 /** 2109 * Returns whether the app holds location permission or not (might return cached result 2110 * if the permission was already checked before). 2111 */ hasLocationPermission()2112 public boolean hasLocationPermission() { 2113 if (mHasLocationPermission == null) { 2114 // If there is no cached result, perform the check now. 2115 mHasLocationPermission = hasLocationPermissionInternal(); 2116 } 2117 return mHasLocationPermission; 2118 } 2119 2120 /** 2121 * Returns whether the app holds local mac address permission or not (might return cached 2122 * result if the permission was already checked before). 2123 */ hasLocalMacAddressPermission()2124 public boolean hasLocalMacAddressPermission() { 2125 if (mHasLocalMacAddressPermission == null) { 2126 // If there is no cached result, perform the check now. 2127 mHasLocalMacAddressPermission = 2128 checkLocalMacAddressPermission(mCallingPid, mCallingUid); 2129 } 2130 return mHasLocalMacAddressPermission; 2131 } 2132 2133 /** 2134 * Returns whether the app holds settings permission or not (might return cached 2135 * result if the permission was already checked before). 2136 */ hasSettingsPermission()2137 public boolean hasSettingsPermission() { 2138 if (mHasSettingsPermission == null) { 2139 // If there is no cached result, perform the check now. 2140 mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid); 2141 } 2142 return mHasSettingsPermission; 2143 } 2144 } 2145 shouldRedact(@etworkCapabilities.RedactionType long redactions, @NetworkCapabilities.NetCapability long redaction)2146 private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions, 2147 @NetworkCapabilities.NetCapability long redaction) { 2148 return (redactions & redaction) != 0; 2149 } 2150 2151 /** 2152 * Use the provided |applicableRedactions| to check the receiving app's 2153 * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask 2154 * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities 2155 * before being sent to the corresponding app. 2156 */ retrieveRequiredRedactions( @etworkCapabilities.RedactionType long applicableRedactions, @NonNull RedactionPermissionChecker redactionPermissionChecker, boolean includeLocationSensitiveInfo)2157 private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions( 2158 @NetworkCapabilities.RedactionType long applicableRedactions, 2159 @NonNull RedactionPermissionChecker redactionPermissionChecker, 2160 boolean includeLocationSensitiveInfo) { 2161 long redactions = applicableRedactions; 2162 if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) { 2163 if (includeLocationSensitiveInfo 2164 && redactionPermissionChecker.hasLocationPermission()) { 2165 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION; 2166 } 2167 } 2168 if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) { 2169 if (redactionPermissionChecker.hasLocalMacAddressPermission()) { 2170 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS; 2171 } 2172 } 2173 if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) { 2174 if (redactionPermissionChecker.hasSettingsPermission()) { 2175 redactions &= ~REDACT_FOR_NETWORK_SETTINGS; 2176 } 2177 } 2178 return redactions; 2179 } 2180 2181 @VisibleForTesting 2182 @Nullable createWithLocationInfoSanitizedIfNecessaryWhenParceled( @ullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, int callingPid, int callingUid, @NonNull String callingPkgName, @Nullable String callingAttributionTag)2183 NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2184 @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, 2185 int callingPid, int callingUid, @NonNull String callingPkgName, 2186 @Nullable String callingAttributionTag) { 2187 if (nc == null) { 2188 return null; 2189 } 2190 // Avoid doing location permission check if the transport info has no location sensitive 2191 // data. 2192 final RedactionPermissionChecker redactionPermissionChecker = 2193 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName, 2194 callingAttributionTag); 2195 final long redactions = retrieveRequiredRedactions( 2196 nc.getApplicableRedactions(), redactionPermissionChecker, 2197 includeLocationSensitiveInfo); 2198 final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions); 2199 // Reset owner uid if not destined for the owner app. 2200 if (callingUid != nc.getOwnerUid()) { 2201 newNc.setOwnerUid(INVALID_UID); 2202 return newNc; 2203 } 2204 // Allow VPNs to see ownership of their own VPN networks - not location sensitive. 2205 if (nc.hasTransport(TRANSPORT_VPN)) { 2206 // Owner UIDs already checked above. No need to re-check. 2207 return newNc; 2208 } 2209 // If the calling does not want location sensitive data & target SDK >= S, then mask info. 2210 // Else include the owner UID iff the calling has location permission to provide backwards 2211 // compatibility for older apps. 2212 if (!includeLocationSensitiveInfo 2213 && isTargetSdkAtleast( 2214 Build.VERSION_CODES.S, callingUid, callingPkgName)) { 2215 newNc.setOwnerUid(INVALID_UID); 2216 return newNc; 2217 } 2218 // Reset owner uid if the app has no location permission. 2219 if (!redactionPermissionChecker.hasLocationPermission()) { 2220 newNc.setOwnerUid(INVALID_UID); 2221 } 2222 return newNc; 2223 } 2224 linkPropertiesRestrictedForCallerPermissions( LinkProperties lp, int callerPid, int callerUid)2225 private LinkProperties linkPropertiesRestrictedForCallerPermissions( 2226 LinkProperties lp, int callerPid, int callerUid) { 2227 if (lp == null) return new LinkProperties(); 2228 2229 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls. 2230 final boolean needsSanitization = 2231 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null); 2232 if (!needsSanitization) { 2233 return new LinkProperties(lp); 2234 } 2235 2236 if (checkSettingsPermission(callerPid, callerUid)) { 2237 return new LinkProperties(lp, true /* parcelSensitiveFields */); 2238 } 2239 2240 final LinkProperties newLp = new LinkProperties(lp); 2241 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the 2242 // object gets parceled. 2243 newLp.setCaptivePortalApiUrl(null); 2244 newLp.setCaptivePortalData(null); 2245 return newLp; 2246 } 2247 restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, int callerUid, String callerPackageName)2248 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, 2249 int callerUid, String callerPackageName) { 2250 // There is no need to track the effective UID of the request here. If the caller 2251 // lacks the settings permission, the effective UID is the same as the calling ID. 2252 if (!checkSettingsPermission()) { 2253 // Unprivileged apps can only pass in null or their own UID. 2254 if (nc.getUids() == null) { 2255 // If the caller passes in null, the callback will also match networks that do not 2256 // apply to its UID, similarly to what it would see if it called getAllNetworks. 2257 // In this case, redact everything in the request immediately. This ensures that the 2258 // app is not able to get any redacted information by filing an unredacted request 2259 // and observing whether the request matches something. 2260 if (nc.getNetworkSpecifier() != null) { 2261 nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact()); 2262 } 2263 } else { 2264 nc.setSingleUid(callerUid); 2265 } 2266 } 2267 nc.setRequestorUidAndPackageName(callerUid, callerPackageName); 2268 nc.setAdministratorUids(new int[0]); 2269 2270 // Clear owner UID; this can never come from an app. 2271 nc.setOwnerUid(INVALID_UID); 2272 } 2273 restrictBackgroundRequestForCaller(NetworkCapabilities nc)2274 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) { 2275 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) { 2276 nc.addCapability(NET_CAPABILITY_FOREGROUND); 2277 } 2278 } 2279 2280 @Override getRestrictBackgroundStatusByCaller()2281 public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() { 2282 enforceAccessPermission(); 2283 final int callerUid = Binder.getCallingUid(); 2284 final long token = Binder.clearCallingIdentity(); 2285 try { 2286 return mPolicyManager.getRestrictBackgroundStatus(callerUid); 2287 } finally { 2288 Binder.restoreCallingIdentity(token); 2289 } 2290 } 2291 2292 // TODO: Consider delete this function or turn it into a no-op method. 2293 @Override getAllNetworkState()2294 public NetworkState[] getAllNetworkState() { 2295 // This contains IMSI details, so make sure the caller is privileged. 2296 PermissionUtils.enforceNetworkStackPermission(mContext); 2297 2298 final ArrayList<NetworkState> result = new ArrayList<>(); 2299 for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) { 2300 // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the 2301 // NetworkAgentInfo. 2302 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork()); 2303 if (nai != null && nai.networkInfo.isConnected()) { 2304 result.add(new NetworkState(new NetworkInfo(nai.networkInfo), 2305 snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(), 2306 snapshot.getNetwork(), snapshot.getSubscriberId())); 2307 } 2308 } 2309 return result.toArray(new NetworkState[result.size()]); 2310 } 2311 2312 @Override 2313 @NonNull getAllNetworkStateSnapshots()2314 public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() { 2315 // This contains IMSI details, so make sure the caller is privileged. 2316 enforceNetworkStackOrSettingsPermission(); 2317 2318 final ArrayList<NetworkStateSnapshot> result = new ArrayList<>(); 2319 for (Network network : getAllNetworks()) { 2320 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2321 // TODO: Consider include SUSPENDED networks, which should be considered as 2322 // temporary shortage of connectivity of a connected network. 2323 if (nai != null && nai.networkInfo.isConnected()) { 2324 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the 2325 // NetworkCapabilities, which may contain UIDs of apps to which the 2326 // network applies. Should the UIDs be cleared so as not to leak or 2327 // interfere ? 2328 result.add(nai.getNetworkStateSnapshot()); 2329 } 2330 } 2331 return result; 2332 } 2333 2334 @Override isActiveNetworkMetered()2335 public boolean isActiveNetworkMetered() { 2336 enforceAccessPermission(); 2337 2338 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork()); 2339 if (caps != null) { 2340 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 2341 } else { 2342 // Always return the most conservative value 2343 return true; 2344 } 2345 } 2346 2347 /** 2348 * Ensures that the system cannot call a particular method. 2349 */ disallowedBecauseSystemCaller()2350 private boolean disallowedBecauseSystemCaller() { 2351 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling 2352 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost 2353 // for devices launched with Q and above. However, existing devices upgrading to Q and 2354 // above must continued to be supported for few more releases. 2355 if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt( 2356 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) { 2357 log("This method exists only for app backwards compatibility" 2358 + " and must not be called by system services."); 2359 return true; 2360 } 2361 return false; 2362 } 2363 getAppUid(final String app, final UserHandle user)2364 private int getAppUid(final String app, final UserHandle user) { 2365 final PackageManager pm = 2366 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 2367 final long token = Binder.clearCallingIdentity(); 2368 try { 2369 return pm.getPackageUid(app, 0 /* flags */); 2370 } catch (PackageManager.NameNotFoundException e) { 2371 return -1; 2372 } finally { 2373 Binder.restoreCallingIdentity(token); 2374 } 2375 } 2376 verifyCallingUidAndPackage(String packageName, int callingUid)2377 private void verifyCallingUidAndPackage(String packageName, int callingUid) { 2378 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 2379 if (getAppUid(packageName, user) != callingUid) { 2380 throw new SecurityException(packageName + " does not belong to uid " + callingUid); 2381 } 2382 } 2383 2384 /** 2385 * Ensure that a network route exists to deliver traffic to the specified 2386 * host via the specified network interface. 2387 * @param networkType the type of the network over which traffic to the 2388 * specified host is to be routed 2389 * @param hostAddress the IP address of the host to which the route is 2390 * desired 2391 * @return {@code true} on success, {@code false} on failure 2392 */ 2393 @Override requestRouteToHostAddress(int networkType, byte[] hostAddress, String callingPackageName, String callingAttributionTag)2394 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, 2395 String callingPackageName, String callingAttributionTag) { 2396 if (disallowedBecauseSystemCaller()) { 2397 return false; 2398 } 2399 verifyCallingUidAndPackage(callingPackageName, mDeps.getCallingUid()); 2400 enforceChangePermission(callingPackageName, callingAttributionTag); 2401 if (mProtectedNetworks.contains(networkType)) { 2402 enforceConnectivityRestrictedNetworksPermission(); 2403 } 2404 2405 InetAddress addr; 2406 try { 2407 addr = InetAddress.getByAddress(hostAddress); 2408 } catch (UnknownHostException e) { 2409 if (DBG) log("requestRouteToHostAddress got " + e.toString()); 2410 return false; 2411 } 2412 2413 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 2414 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 2415 return false; 2416 } 2417 2418 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2419 if (nai == null) { 2420 if (mLegacyTypeTracker.isTypeSupported(networkType) == false) { 2421 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 2422 } else { 2423 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 2424 } 2425 return false; 2426 } 2427 2428 DetailedState netState; 2429 synchronized (nai) { 2430 netState = nai.networkInfo.getDetailedState(); 2431 } 2432 2433 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 2434 if (VDBG) { 2435 log("requestRouteToHostAddress on down network " 2436 + "(" + networkType + ") - dropped" 2437 + " netState=" + netState); 2438 } 2439 return false; 2440 } 2441 2442 final int uid = mDeps.getCallingUid(); 2443 final long token = Binder.clearCallingIdentity(); 2444 try { 2445 LinkProperties lp; 2446 int netId; 2447 synchronized (nai) { 2448 lp = nai.linkProperties; 2449 netId = nai.network.getNetId(); 2450 } 2451 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 2452 if (DBG) { 2453 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok); 2454 } 2455 return ok; 2456 } finally { 2457 Binder.restoreCallingIdentity(token); 2458 } 2459 } 2460 addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid)2461 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 2462 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 2463 if (bestRoute == null) { 2464 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 2465 } else { 2466 String iface = bestRoute.getInterface(); 2467 if (bestRoute.getGateway().equals(addr)) { 2468 // if there is no better route, add the implied hostroute for our gateway 2469 bestRoute = RouteInfo.makeHostRoute(addr, iface); 2470 } else { 2471 // if we will connect to this through another route, add a direct route 2472 // to it's gateway 2473 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 2474 } 2475 } 2476 if (DBG) log("Adding legacy route " + bestRoute + 2477 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 2478 2479 final String dst = bestRoute.getDestinationLinkAddress().toString(); 2480 final String nextHop = bestRoute.hasGateway() 2481 ? bestRoute.getGateway().getHostAddress() : ""; 2482 try { 2483 mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid); 2484 } catch (RemoteException | ServiceSpecificException e) { 2485 if (DBG) loge("Exception trying to add a route: " + e); 2486 return false; 2487 } 2488 return true; 2489 } 2490 2491 class DnsResolverUnsolicitedEventCallback extends 2492 IDnsResolverUnsolicitedEventListener.Stub { 2493 @Override onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event)2494 public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { 2495 try { 2496 mHandler.sendMessage(mHandler.obtainMessage( 2497 EVENT_PRIVATE_DNS_VALIDATION_UPDATE, 2498 new PrivateDnsValidationUpdate(event.netId, 2499 InetAddresses.parseNumericAddress(event.ipAddress), 2500 event.hostname, event.validation))); 2501 } catch (IllegalArgumentException e) { 2502 loge("Error parsing ip address in validation event"); 2503 } 2504 } 2505 2506 @Override onDnsHealthEvent(final DnsHealthEventParcel event)2507 public void onDnsHealthEvent(final DnsHealthEventParcel event) { 2508 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); 2509 // Netd event only allow registrants from system. Each NetworkMonitor thread is under 2510 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd 2511 // event callback for certain nai. e.g. cellular. Register here to pass to 2512 // NetworkMonitor instead. 2513 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allow one 2514 // callback from each caller type. Need to re-factor NetdEventListenerService to allow 2515 // multiple NetworkMonitor registrants. 2516 if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { 2517 nai.networkMonitor().notifyDnsResponse(event.healthResult); 2518 } 2519 } 2520 2521 @Override onNat64PrefixEvent(final Nat64PrefixEventParcel event)2522 public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { 2523 mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, 2524 event.prefixAddress, event.prefixLength)); 2525 } 2526 2527 @Override getInterfaceVersion()2528 public int getInterfaceVersion() { 2529 return this.VERSION; 2530 } 2531 2532 @Override getInterfaceHash()2533 public String getInterfaceHash() { 2534 return this.HASH; 2535 } 2536 } 2537 2538 @VisibleForTesting 2539 protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = 2540 new DnsResolverUnsolicitedEventCallback(); 2541 registerDnsResolverUnsolicitedEventListener()2542 private void registerDnsResolverUnsolicitedEventListener() { 2543 try { 2544 mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); 2545 } catch (Exception e) { 2546 loge("Error registering DnsResolver unsolicited event callback: " + e); 2547 } 2548 } 2549 2550 private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() { 2551 @Override 2552 public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 2553 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED, 2554 uid, blockedReasons)); 2555 } 2556 }; 2557 handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons)2558 private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 2559 maybeNotifyNetworkBlockedForNewState(uid, blockedReasons); 2560 setUidBlockedReasons(uid, blockedReasons); 2561 } 2562 checkAnyPermissionOf(String... permissions)2563 private boolean checkAnyPermissionOf(String... permissions) { 2564 for (String permission : permissions) { 2565 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { 2566 return true; 2567 } 2568 } 2569 return false; 2570 } 2571 checkAnyPermissionOf(int pid, int uid, String... permissions)2572 private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) { 2573 for (String permission : permissions) { 2574 if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) { 2575 return true; 2576 } 2577 } 2578 return false; 2579 } 2580 enforceAnyPermissionOf(String... permissions)2581 private void enforceAnyPermissionOf(String... permissions) { 2582 if (!checkAnyPermissionOf(permissions)) { 2583 throw new SecurityException("Requires one of the following permissions: " 2584 + String.join(", ", permissions) + "."); 2585 } 2586 } 2587 enforceInternetPermission()2588 private void enforceInternetPermission() { 2589 mContext.enforceCallingOrSelfPermission( 2590 android.Manifest.permission.INTERNET, 2591 "ConnectivityService"); 2592 } 2593 enforceAccessPermission()2594 private void enforceAccessPermission() { 2595 mContext.enforceCallingOrSelfPermission( 2596 android.Manifest.permission.ACCESS_NETWORK_STATE, 2597 "ConnectivityService"); 2598 } 2599 2600 /** 2601 * Performs a strict and comprehensive check of whether a calling package is allowed to 2602 * change the state of network, as the condition differs for pre-M, M+, and 2603 * privileged/preinstalled apps. The caller is expected to have either the 2604 * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these 2605 * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and 2606 * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal 2607 * permission and cannot be revoked. See http://b/23597341 2608 * 2609 * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation 2610 * of this app will be updated to the current time. 2611 */ enforceChangePermission(String callingPkg, String callingAttributionTag)2612 private void enforceChangePermission(String callingPkg, String callingAttributionTag) { 2613 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) 2614 == PackageManager.PERMISSION_GRANTED) { 2615 return; 2616 } 2617 2618 if (callingPkg == null) { 2619 throw new SecurityException("Calling package name is null."); 2620 } 2621 2622 final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class); 2623 final int uid = mDeps.getCallingUid(); 2624 final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid, 2625 callingPkg, callingAttributionTag, null /* message */); 2626 2627 if (mode == AppOpsManager.MODE_ALLOWED) { 2628 return; 2629 } 2630 2631 if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission( 2632 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) { 2633 return; 2634 } 2635 2636 throw new SecurityException(callingPkg + " was not granted either of these permissions:" 2637 + android.Manifest.permission.CHANGE_NETWORK_STATE + "," 2638 + android.Manifest.permission.WRITE_SETTINGS + "."); 2639 } 2640 enforceSettingsPermission()2641 private void enforceSettingsPermission() { 2642 enforceAnyPermissionOf( 2643 android.Manifest.permission.NETWORK_SETTINGS, 2644 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2645 } 2646 enforceNetworkFactoryPermission()2647 private void enforceNetworkFactoryPermission() { 2648 enforceAnyPermissionOf( 2649 android.Manifest.permission.NETWORK_FACTORY, 2650 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2651 } 2652 enforceNetworkFactoryOrSettingsPermission()2653 private void enforceNetworkFactoryOrSettingsPermission() { 2654 enforceAnyPermissionOf( 2655 android.Manifest.permission.NETWORK_SETTINGS, 2656 android.Manifest.permission.NETWORK_FACTORY, 2657 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2658 } 2659 enforceNetworkFactoryOrTestNetworksPermission()2660 private void enforceNetworkFactoryOrTestNetworksPermission() { 2661 enforceAnyPermissionOf( 2662 android.Manifest.permission.MANAGE_TEST_NETWORKS, 2663 android.Manifest.permission.NETWORK_FACTORY, 2664 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2665 } 2666 checkSettingsPermission()2667 private boolean checkSettingsPermission() { 2668 return checkAnyPermissionOf( 2669 android.Manifest.permission.NETWORK_SETTINGS, 2670 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2671 } 2672 checkSettingsPermission(int pid, int uid)2673 private boolean checkSettingsPermission(int pid, int uid) { 2674 return PERMISSION_GRANTED == mContext.checkPermission( 2675 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 2676 || PERMISSION_GRANTED == mContext.checkPermission( 2677 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid); 2678 } 2679 enforceNetworkStackOrSettingsPermission()2680 private void enforceNetworkStackOrSettingsPermission() { 2681 enforceAnyPermissionOf( 2682 android.Manifest.permission.NETWORK_SETTINGS, 2683 android.Manifest.permission.NETWORK_STACK, 2684 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2685 } 2686 enforceNetworkStackSettingsOrSetup()2687 private void enforceNetworkStackSettingsOrSetup() { 2688 enforceAnyPermissionOf( 2689 android.Manifest.permission.NETWORK_SETTINGS, 2690 android.Manifest.permission.NETWORK_SETUP_WIZARD, 2691 android.Manifest.permission.NETWORK_STACK, 2692 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2693 } 2694 enforceAirplaneModePermission()2695 private void enforceAirplaneModePermission() { 2696 enforceAnyPermissionOf( 2697 android.Manifest.permission.NETWORK_AIRPLANE_MODE, 2698 android.Manifest.permission.NETWORK_SETTINGS, 2699 android.Manifest.permission.NETWORK_SETUP_WIZARD, 2700 android.Manifest.permission.NETWORK_STACK, 2701 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2702 } 2703 enforceOemNetworkPreferencesPermission()2704 private void enforceOemNetworkPreferencesPermission() { 2705 mContext.enforceCallingOrSelfPermission( 2706 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, 2707 "ConnectivityService"); 2708 } 2709 enforceManageTestNetworksPermission()2710 private void enforceManageTestNetworksPermission() { 2711 mContext.enforceCallingOrSelfPermission( 2712 android.Manifest.permission.MANAGE_TEST_NETWORKS, 2713 "ConnectivityService"); 2714 } 2715 checkNetworkStackPermission()2716 private boolean checkNetworkStackPermission() { 2717 return checkAnyPermissionOf( 2718 android.Manifest.permission.NETWORK_STACK, 2719 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2720 } 2721 checkNetworkStackPermission(int pid, int uid)2722 private boolean checkNetworkStackPermission(int pid, int uid) { 2723 return checkAnyPermissionOf(pid, uid, 2724 android.Manifest.permission.NETWORK_STACK, 2725 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 2726 } 2727 checkNetworkSignalStrengthWakeupPermission(int pid, int uid)2728 private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { 2729 return checkAnyPermissionOf(pid, uid, 2730 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, 2731 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 2732 android.Manifest.permission.NETWORK_SETTINGS); 2733 } 2734 enforceConnectivityRestrictedNetworksPermission()2735 private void enforceConnectivityRestrictedNetworksPermission() { 2736 try { 2737 mContext.enforceCallingOrSelfPermission( 2738 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS, 2739 "ConnectivityService"); 2740 return; 2741 } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ } 2742 // TODO: Remove this fallback check after all apps have declared 2743 // CONNECTIVITY_USE_RESTRICTED_NETWORKS. 2744 mContext.enforceCallingOrSelfPermission( 2745 android.Manifest.permission.CONNECTIVITY_INTERNAL, 2746 "ConnectivityService"); 2747 } 2748 enforceKeepalivePermission()2749 private void enforceKeepalivePermission() { 2750 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 2751 } 2752 checkLocalMacAddressPermission(int pid, int uid)2753 private boolean checkLocalMacAddressPermission(int pid, int uid) { 2754 return PERMISSION_GRANTED == mContext.checkPermission( 2755 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid); 2756 } 2757 sendConnectedBroadcast(NetworkInfo info)2758 private void sendConnectedBroadcast(NetworkInfo info) { 2759 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 2760 } 2761 sendInetConditionBroadcast(NetworkInfo info)2762 private void sendInetConditionBroadcast(NetworkInfo info) { 2763 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 2764 } 2765 makeGeneralIntent(NetworkInfo info, String bcastType)2766 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 2767 Intent intent = new Intent(bcastType); 2768 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 2769 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 2770 if (info.isFailover()) { 2771 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 2772 info.setFailover(false); 2773 } 2774 if (info.getReason() != null) { 2775 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 2776 } 2777 if (info.getExtraInfo() != null) { 2778 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 2779 info.getExtraInfo()); 2780 } 2781 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 2782 return intent; 2783 } 2784 sendGeneralBroadcast(NetworkInfo info, String bcastType)2785 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 2786 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 2787 } 2788 sendStickyBroadcast(Intent intent)2789 private void sendStickyBroadcast(Intent intent) { 2790 synchronized (this) { 2791 if (!mSystemReady 2792 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 2793 mInitialBroadcast = new Intent(intent); 2794 } 2795 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2796 if (VDBG) { 2797 log("sendStickyBroadcast: action=" + intent.getAction()); 2798 } 2799 2800 Bundle options = null; 2801 final long ident = Binder.clearCallingIdentity(); 2802 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 2803 final NetworkInfo ni = intent.getParcelableExtra( 2804 ConnectivityManager.EXTRA_NETWORK_INFO); 2805 final BroadcastOptions opts = BroadcastOptions.makeBasic(); 2806 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 2807 options = opts.toBundle(); 2808 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 2809 } 2810 try { 2811 mUserAllContext.sendStickyBroadcast(intent, options); 2812 } finally { 2813 Binder.restoreCallingIdentity(ident); 2814 } 2815 } 2816 } 2817 2818 /** 2819 * Called by SystemServer through ConnectivityManager when the system is ready. 2820 */ 2821 @Override systemReady()2822 public void systemReady() { 2823 if (mDeps.getCallingUid() != Process.SYSTEM_UID) { 2824 throw new SecurityException("Calling Uid is not system uid."); 2825 } 2826 systemReadyInternal(); 2827 } 2828 2829 /** 2830 * Called when ConnectivityService can initialize remaining components. 2831 */ 2832 @VisibleForTesting systemReadyInternal()2833 public void systemReadyInternal() { 2834 // Since mApps in PermissionMonitor needs to be populated first to ensure that 2835 // listening network request which is sent by MultipathPolicyTracker won't be added 2836 // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must 2837 // be called after PermissionMonitor#startMonitoring(). 2838 // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the 2839 // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady() 2840 // to ensure the tracking will be initialized correctly. 2841 mPermissionMonitor.startMonitoring(); 2842 mProxyTracker.loadGlobalProxy(); 2843 registerDnsResolverUnsolicitedEventListener(); 2844 2845 synchronized (this) { 2846 mSystemReady = true; 2847 if (mInitialBroadcast != null) { 2848 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 2849 mInitialBroadcast = null; 2850 } 2851 } 2852 2853 // Create network requests for always-on networks. 2854 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); 2855 2856 // Update mobile data preference if necessary. 2857 // Note that empty uid list can be skip here only because no uid rules applied before system 2858 // ready. Normally, the empty uid list means to clear the uids rules on netd. 2859 if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) { 2860 updateMobileDataPreferredUids(); 2861 } 2862 } 2863 2864 /** 2865 * Start listening for default data network activity state changes. 2866 */ 2867 @Override registerNetworkActivityListener(@onNull INetworkActivityListener l)2868 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 2869 mNetworkActivityTracker.registerNetworkActivityListener(l); 2870 } 2871 2872 /** 2873 * Stop listening for default data network activity state changes. 2874 */ 2875 @Override unregisterNetworkActivityListener(@onNull INetworkActivityListener l)2876 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 2877 mNetworkActivityTracker.unregisterNetworkActivityListener(l); 2878 } 2879 2880 /** 2881 * Check whether the default network radio is currently active. 2882 */ 2883 @Override isDefaultNetworkActive()2884 public boolean isDefaultNetworkActive() { 2885 return mNetworkActivityTracker.isDefaultNetworkActive(); 2886 } 2887 2888 /** 2889 * Reads the network specific MTU size from resources. 2890 * and set it on it's iface. 2891 */ updateMtu(LinkProperties newLp, LinkProperties oldLp)2892 private void updateMtu(LinkProperties newLp, LinkProperties oldLp) { 2893 final String iface = newLp.getInterfaceName(); 2894 final int mtu = newLp.getMtu(); 2895 if (oldLp == null && mtu == 0) { 2896 // Silently ignore unset MTU value. 2897 return; 2898 } 2899 if (oldLp != null && newLp.isIdenticalMtu(oldLp)) { 2900 if (VDBG) log("identical MTU - not setting"); 2901 return; 2902 } 2903 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) { 2904 if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface); 2905 return; 2906 } 2907 2908 // Cannot set MTU without interface name 2909 if (TextUtils.isEmpty(iface)) { 2910 loge("Setting MTU size with null iface."); 2911 return; 2912 } 2913 2914 try { 2915 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); 2916 mNetd.interfaceSetMtu(iface, mtu); 2917 } catch (RemoteException | ServiceSpecificException e) { 2918 loge("exception in interfaceSetMtu()" + e); 2919 } 2920 } 2921 2922 @VisibleForTesting 2923 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 2924 updateTcpBufferSizes(String tcpBufferSizes)2925 private void updateTcpBufferSizes(String tcpBufferSizes) { 2926 String[] values = null; 2927 if (tcpBufferSizes != null) { 2928 values = tcpBufferSizes.split(","); 2929 } 2930 2931 if (values == null || values.length != 6) { 2932 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 2933 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 2934 values = tcpBufferSizes.split(","); 2935 } 2936 2937 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 2938 2939 try { 2940 if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes); 2941 2942 String rmemValues = String.join(" ", values[0], values[1], values[2]); 2943 String wmemValues = String.join(" ", values[3], values[4], values[5]); 2944 mNetd.setTcpRWmemorySize(rmemValues, wmemValues); 2945 mCurrentTcpBufferSizes = tcpBufferSizes; 2946 } catch (RemoteException | ServiceSpecificException e) { 2947 loge("Can't set TCP buffer sizes:" + e); 2948 } 2949 } 2950 2951 @Override getRestoreDefaultNetworkDelay(int networkType)2952 public int getRestoreDefaultNetworkDelay(int networkType) { 2953 String restoreDefaultNetworkDelayStr = mSystemProperties.get( 2954 NETWORK_RESTORE_DELAY_PROP_NAME); 2955 if(restoreDefaultNetworkDelayStr != null && 2956 restoreDefaultNetworkDelayStr.length() != 0) { 2957 try { 2958 return Integer.parseInt(restoreDefaultNetworkDelayStr); 2959 } catch (NumberFormatException e) { 2960 } 2961 } 2962 // if the system property isn't set, use the value for the apn type 2963 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 2964 2965 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 2966 ret = mLegacyTypeTracker.getRestoreTimerForType(networkType); 2967 } 2968 return ret; 2969 } 2970 dumpNetworkDiagnostics(IndentingPrintWriter pw)2971 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 2972 final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>(); 2973 final long DIAG_TIME_MS = 5000; 2974 for (NetworkAgentInfo nai : networksSortedById()) { 2975 PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network); 2976 // Start gathering diagnostic information. 2977 netDiags.add(new NetworkDiagnostics( 2978 nai.network, 2979 new LinkProperties(nai.linkProperties), // Must be a copy. 2980 privateDnsCfg, 2981 DIAG_TIME_MS)); 2982 } 2983 2984 for (NetworkDiagnostics netDiag : netDiags) { 2985 pw.println(); 2986 netDiag.waitForMeasurements(); 2987 netDiag.dump(pw); 2988 } 2989 } 2990 2991 @Override dump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2992 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, 2993 @Nullable String[] args) { 2994 if (!checkDumpPermission(mContext, TAG, writer)) return; 2995 2996 mPriorityDumper.dump(fd, writer, args); 2997 } 2998 checkDumpPermission(Context context, String tag, PrintWriter pw)2999 private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) { 3000 if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 3001 != PackageManager.PERMISSION_GRANTED) { 3002 pw.println("Permission Denial: can't dump " + tag + " from from pid=" 3003 + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid() 3004 + " due to missing android.permission.DUMP permission"); 3005 return false; 3006 } else { 3007 return true; 3008 } 3009 } 3010 doDump(FileDescriptor fd, PrintWriter writer, String[] args)3011 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) { 3012 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 3013 3014 if (CollectionUtils.contains(args, DIAG_ARG)) { 3015 dumpNetworkDiagnostics(pw); 3016 return; 3017 } else if (CollectionUtils.contains(args, NETWORK_ARG)) { 3018 dumpNetworks(pw); 3019 return; 3020 } else if (CollectionUtils.contains(args, REQUEST_ARG)) { 3021 dumpNetworkRequests(pw); 3022 return; 3023 } 3024 3025 pw.print("NetworkProviders for:"); 3026 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 3027 pw.print(" " + npi.name); 3028 } 3029 pw.println(); 3030 pw.println(); 3031 3032 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 3033 pw.print("Active default network: "); 3034 if (defaultNai == null) { 3035 pw.println("none"); 3036 } else { 3037 pw.println(defaultNai.network.getNetId()); 3038 } 3039 pw.println(); 3040 3041 pw.print("Current per-app default networks: "); 3042 pw.increaseIndent(); 3043 dumpPerAppNetworkPreferences(pw); 3044 pw.decreaseIndent(); 3045 pw.println(); 3046 3047 pw.println("Current Networks:"); 3048 pw.increaseIndent(); 3049 dumpNetworks(pw); 3050 pw.decreaseIndent(); 3051 pw.println(); 3052 3053 pw.println("Status for known UIDs:"); 3054 pw.increaseIndent(); 3055 final int size = mUidBlockedReasons.size(); 3056 for (int i = 0; i < size; i++) { 3057 // Don't crash if the array is modified while dumping in bugreports. 3058 try { 3059 final int uid = mUidBlockedReasons.keyAt(i); 3060 final int blockedReasons = mUidBlockedReasons.valueAt(i); 3061 pw.println("UID=" + uid + " blockedReasons=" 3062 + Integer.toHexString(blockedReasons)); 3063 } catch (ArrayIndexOutOfBoundsException e) { 3064 pw.println(" ArrayIndexOutOfBoundsException"); 3065 } catch (ConcurrentModificationException e) { 3066 pw.println(" ConcurrentModificationException"); 3067 } 3068 } 3069 pw.println(); 3070 pw.decreaseIndent(); 3071 3072 pw.println("Network Requests:"); 3073 pw.increaseIndent(); 3074 dumpNetworkRequests(pw); 3075 pw.decreaseIndent(); 3076 pw.println(); 3077 3078 mLegacyTypeTracker.dump(pw); 3079 3080 pw.println(); 3081 mKeepaliveTracker.dump(pw); 3082 3083 pw.println(); 3084 dumpAvoidBadWifiSettings(pw); 3085 3086 pw.println(); 3087 3088 if (!CollectionUtils.contains(args, SHORT_ARG)) { 3089 pw.println(); 3090 pw.println("mNetworkRequestInfoLogs (most recent first):"); 3091 pw.increaseIndent(); 3092 mNetworkRequestInfoLogs.reverseDump(pw); 3093 pw.decreaseIndent(); 3094 3095 pw.println(); 3096 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 3097 pw.increaseIndent(); 3098 mNetworkInfoBlockingLogs.reverseDump(pw); 3099 pw.decreaseIndent(); 3100 3101 pw.println(); 3102 pw.println("NetTransition WakeLock activity (most recent first):"); 3103 pw.increaseIndent(); 3104 pw.println("total acquisitions: " + mTotalWakelockAcquisitions); 3105 pw.println("total releases: " + mTotalWakelockReleases); 3106 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s"); 3107 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s"); 3108 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) { 3109 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 3110 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); 3111 } 3112 mWakelockLogs.reverseDump(pw); 3113 3114 pw.println(); 3115 pw.println("bandwidth update requests (by uid):"); 3116 pw.increaseIndent(); 3117 synchronized (mBandwidthRequests) { 3118 for (int i = 0; i < mBandwidthRequests.size(); i++) { 3119 pw.println("[" + mBandwidthRequests.keyAt(i) 3120 + "]: " + mBandwidthRequests.valueAt(i)); 3121 } 3122 } 3123 pw.decreaseIndent(); 3124 pw.decreaseIndent(); 3125 3126 pw.println(); 3127 pw.println("mOemNetworkPreferencesLogs (most recent first):"); 3128 pw.increaseIndent(); 3129 mOemNetworkPreferencesLogs.reverseDump(pw); 3130 pw.decreaseIndent(); 3131 } 3132 3133 pw.println(); 3134 3135 pw.println(); 3136 pw.println("Permission Monitor:"); 3137 pw.increaseIndent(); 3138 mPermissionMonitor.dump(pw); 3139 pw.decreaseIndent(); 3140 3141 pw.println(); 3142 pw.println("Legacy network activity:"); 3143 pw.increaseIndent(); 3144 mNetworkActivityTracker.dump(pw); 3145 pw.decreaseIndent(); 3146 } 3147 dumpNetworks(IndentingPrintWriter pw)3148 private void dumpNetworks(IndentingPrintWriter pw) { 3149 for (NetworkAgentInfo nai : networksSortedById()) { 3150 pw.println(nai.toString()); 3151 pw.increaseIndent(); 3152 pw.println(String.format( 3153 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d", 3154 nai.numForegroundNetworkRequests(), 3155 nai.numNetworkRequests() - nai.numRequestNetworkRequests(), 3156 nai.numBackgroundNetworkRequests(), 3157 nai.numNetworkRequests())); 3158 pw.increaseIndent(); 3159 for (int i = 0; i < nai.numNetworkRequests(); i++) { 3160 pw.println(nai.requestAt(i).toString()); 3161 } 3162 pw.decreaseIndent(); 3163 pw.println("Inactivity Timers:"); 3164 pw.increaseIndent(); 3165 nai.dumpInactivityTimers(pw); 3166 pw.decreaseIndent(); 3167 pw.decreaseIndent(); 3168 } 3169 } 3170 dumpPerAppNetworkPreferences(IndentingPrintWriter pw)3171 private void dumpPerAppNetworkPreferences(IndentingPrintWriter pw) { 3172 pw.println("Per-App Network Preference:"); 3173 pw.increaseIndent(); 3174 if (0 == mOemNetworkPreferences.getNetworkPreferences().size()) { 3175 pw.println("none"); 3176 } else { 3177 pw.println(mOemNetworkPreferences.toString()); 3178 } 3179 pw.decreaseIndent(); 3180 3181 for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) { 3182 if (mDefaultRequest == defaultRequest) { 3183 continue; 3184 } 3185 3186 final boolean isActive = null != defaultRequest.getSatisfier(); 3187 pw.println("Is per-app network active:"); 3188 pw.increaseIndent(); 3189 pw.println(isActive); 3190 if (isActive) { 3191 pw.println("Active network: " + defaultRequest.getSatisfier().network.netId); 3192 } 3193 pw.println("Tracked UIDs:"); 3194 pw.increaseIndent(); 3195 if (0 == defaultRequest.mRequests.size()) { 3196 pw.println("none, this should never occur."); 3197 } else { 3198 pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges()); 3199 } 3200 pw.decreaseIndent(); 3201 pw.decreaseIndent(); 3202 } 3203 } 3204 dumpNetworkRequests(IndentingPrintWriter pw)3205 private void dumpNetworkRequests(IndentingPrintWriter pw) { 3206 for (NetworkRequestInfo nri : requestsSortedById()) { 3207 pw.println(nri.toString()); 3208 } 3209 } 3210 3211 /** 3212 * Return an array of all current NetworkAgentInfos sorted by network id. 3213 */ networksSortedById()3214 private NetworkAgentInfo[] networksSortedById() { 3215 NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; 3216 networks = mNetworkAgentInfos.toArray(networks); 3217 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId())); 3218 return networks; 3219 } 3220 3221 /** 3222 * Return an array of all current NetworkRequest sorted by request id. 3223 */ 3224 @VisibleForTesting requestsSortedById()3225 NetworkRequestInfo[] requestsSortedById() { 3226 NetworkRequestInfo[] requests = new NetworkRequestInfo[0]; 3227 requests = getNrisFromGlobalRequests().toArray(requests); 3228 // Sort the array based off the NRI containing the min requestId in its requests. 3229 Arrays.sort(requests, 3230 Comparator.comparingInt(nri -> Collections.min(nri.mRequests, 3231 Comparator.comparingInt(req -> req.requestId)).requestId 3232 ) 3233 ); 3234 return requests; 3235 } 3236 isLiveNetworkAgent(NetworkAgentInfo nai, int what)3237 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 3238 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 3239 if (officialNai != null && officialNai.equals(nai)) return true; 3240 if (officialNai != null || VDBG) { 3241 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 3242 " - " + nai); 3243 } 3244 return false; 3245 } 3246 3247 // must be stateless - things change under us. 3248 private class NetworkStateTrackerHandler extends Handler { NetworkStateTrackerHandler(Looper looper)3249 public NetworkStateTrackerHandler(Looper looper) { 3250 super(looper); 3251 } 3252 maybeHandleNetworkAgentMessage(Message msg)3253 private void maybeHandleNetworkAgentMessage(Message msg) { 3254 final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj; 3255 final NetworkAgentInfo nai = arg.first; 3256 if (!mNetworkAgentInfos.contains(nai)) { 3257 if (VDBG) { 3258 log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); 3259 } 3260 return; 3261 } 3262 3263 switch (msg.what) { 3264 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 3265 NetworkCapabilities networkCapabilities = (NetworkCapabilities) arg.second; 3266 if (networkCapabilities.hasConnectivityManagedCapability()) { 3267 Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); 3268 } 3269 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 3270 // Make sure the original object is not mutated. NetworkAgent normally 3271 // makes a copy of the capabilities when sending the message through 3272 // the Messenger, but if this ever changes, not making a defensive copy 3273 // here will give attack vectors to clients using this code path. 3274 networkCapabilities = new NetworkCapabilities(networkCapabilities); 3275 networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid); 3276 } 3277 processCapabilitiesFromAgent(nai, networkCapabilities); 3278 updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities); 3279 break; 3280 } 3281 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 3282 LinkProperties newLp = (LinkProperties) arg.second; 3283 processLinkPropertiesFromAgent(nai, newLp); 3284 handleUpdateLinkProperties(nai, newLp); 3285 break; 3286 } 3287 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 3288 NetworkInfo info = (NetworkInfo) arg.second; 3289 updateNetworkInfo(nai, info); 3290 break; 3291 } 3292 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 3293 updateNetworkScore(nai, (NetworkScore) arg.second); 3294 break; 3295 } 3296 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 3297 if (nai.everConnected) { 3298 loge("ERROR: cannot call explicitlySelected on already-connected network"); 3299 // Note that if the NAI had been connected, this would affect the 3300 // score, and therefore would require re-mixing the score and performing 3301 // a rematch. 3302 } 3303 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1); 3304 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2); 3305 // Mark the network as temporarily accepting partial connectivity so that it 3306 // will be validated (and possibly become default) even if it only provides 3307 // partial internet access. Note that if user connects to partial connectivity 3308 // and choose "don't ask again", then wifi disconnected by some reasons(maybe 3309 // out of wifi coverage) and if the same wifi is available again, the device 3310 // will auto connect to this wifi even though the wifi has "no internet". 3311 // TODO: Evaluate using a separate setting in IpMemoryStore. 3312 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2); 3313 break; 3314 } 3315 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { 3316 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2); 3317 break; 3318 } 3319 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { 3320 // TODO: prevent loops, e.g., if a network declares itself as underlying. 3321 final List<Network> underlying = (List<Network>) arg.second; 3322 3323 if (isLegacyLockdownNai(nai) 3324 && (underlying == null || underlying.size() != 1)) { 3325 Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString() 3326 + " must have exactly one underlying network: " + underlying); 3327 } 3328 3329 final Network[] oldUnderlying = nai.declaredUnderlyingNetworks; 3330 nai.declaredUnderlyingNetworks = (underlying != null) 3331 ? underlying.toArray(new Network[0]) : null; 3332 3333 if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) { 3334 if (DBG) { 3335 log(nai.toShortString() + " changed underlying networks to " 3336 + Arrays.toString(nai.declaredUnderlyingNetworks)); 3337 } 3338 updateCapabilitiesForNetwork(nai); 3339 notifyIfacesChangedForNetworkStats(); 3340 } 3341 break; 3342 } 3343 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: { 3344 if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 3345 nai.teardownDelayMs = msg.arg1; 3346 } else { 3347 logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1); 3348 } 3349 break; 3350 } 3351 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: { 3352 nai.setLingerDuration((int) arg.second); 3353 break; 3354 } 3355 } 3356 } 3357 maybeHandleNetworkMonitorMessage(Message msg)3358 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 3359 switch (msg.what) { 3360 default: 3361 return false; 3362 case EVENT_PROBE_STATUS_CHANGED: { 3363 final Integer netId = (Integer) msg.obj; 3364 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 3365 if (nai == null) { 3366 break; 3367 } 3368 final boolean probePrivateDnsCompleted = 3369 ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0); 3370 final boolean privateDnsBroken = 3371 ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0); 3372 if (probePrivateDnsCompleted) { 3373 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) { 3374 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken); 3375 updateCapabilitiesForNetwork(nai); 3376 } 3377 // Only show the notification when the private DNS is broken and the 3378 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid. 3379 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) { 3380 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN); 3381 } 3382 nai.networkAgentConfig.hasShownBroken = privateDnsBroken; 3383 } else if (nai.networkCapabilities.isPrivateDnsBroken()) { 3384 // If probePrivateDnsCompleted is false but nai.networkCapabilities says 3385 // private DNS is broken, it means this network is being reevaluated. 3386 // Either probing private DNS is not necessary any more or it hasn't been 3387 // done yet. In either case, the networkCapabilities should be updated to 3388 // reflect the new status. 3389 nai.networkCapabilities.setPrivateDnsBroken(false); 3390 updateCapabilitiesForNetwork(nai); 3391 nai.networkAgentConfig.hasShownBroken = false; 3392 } 3393 break; 3394 } 3395 case EVENT_NETWORK_TESTED: { 3396 final NetworkTestedResults results = (NetworkTestedResults) msg.obj; 3397 3398 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId); 3399 if (nai == null) break; 3400 3401 handleNetworkTested(nai, results.mTestResult, 3402 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl); 3403 break; 3404 } 3405 case EVENT_PROVISIONING_NOTIFICATION: { 3406 final int netId = msg.arg2; 3407 final boolean visible = toBool(msg.arg1); 3408 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 3409 // If captive portal status has changed, update capabilities or disconnect. 3410 if (nai != null && (visible != nai.lastCaptivePortalDetected)) { 3411 nai.lastCaptivePortalDetected = visible; 3412 nai.everCaptivePortalDetected |= visible; 3413 if (nai.lastCaptivePortalDetected && 3414 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID 3415 == getCaptivePortalMode()) { 3416 if (DBG) log("Avoiding captive portal network: " + nai.toShortString()); 3417 nai.onPreventAutomaticReconnect(); 3418 teardownUnneededNetwork(nai); 3419 break; 3420 } 3421 updateCapabilitiesForNetwork(nai); 3422 } 3423 if (!visible) { 3424 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other 3425 // notifications belong to the same network may be cleared unexpectedly. 3426 mNotifier.clearNotification(netId, NotificationType.SIGN_IN); 3427 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH); 3428 } else { 3429 if (nai == null) { 3430 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 3431 break; 3432 } 3433 if (!nai.networkAgentConfig.provisioningNotificationDisabled) { 3434 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 3435 (PendingIntent) msg.obj, 3436 nai.networkAgentConfig.explicitlySelected); 3437 } 3438 } 3439 break; 3440 } 3441 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { 3442 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 3443 if (nai == null) break; 3444 3445 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); 3446 break; 3447 } 3448 case EVENT_CAPPORT_DATA_CHANGED: { 3449 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 3450 if (nai == null) break; 3451 handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj); 3452 break; 3453 } 3454 } 3455 return true; 3456 } 3457 handleNetworkTested( @onNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl)3458 private void handleNetworkTested( 3459 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) { 3460 final boolean wasPartial = nai.partialConnectivity; 3461 nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0); 3462 final boolean partialConnectivityChanged = 3463 (wasPartial != nai.partialConnectivity); 3464 3465 final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0); 3466 final boolean wasValidated = nai.lastValidated; 3467 final boolean wasDefault = isDefaultNetwork(nai); 3468 3469 if (DBG) { 3470 final String logMsg = !TextUtils.isEmpty(redirectUrl) 3471 ? " with redirect to " + redirectUrl 3472 : ""; 3473 log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg); 3474 } 3475 if (valid != nai.lastValidated) { 3476 final int oldScore = nai.getCurrentScore(); 3477 nai.lastValidated = valid; 3478 nai.everValidated |= valid; 3479 updateCapabilities(oldScore, nai, nai.networkCapabilities); 3480 if (valid) { 3481 handleFreshlyValidatedNetwork(nai); 3482 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and 3483 // LOST_INTERNET notifications if network becomes valid. 3484 mNotifier.clearNotification(nai.network.getNetId(), 3485 NotificationType.NO_INTERNET); 3486 mNotifier.clearNotification(nai.network.getNetId(), 3487 NotificationType.LOST_INTERNET); 3488 mNotifier.clearNotification(nai.network.getNetId(), 3489 NotificationType.PARTIAL_CONNECTIVITY); 3490 mNotifier.clearNotification(nai.network.getNetId(), 3491 NotificationType.PRIVATE_DNS_BROKEN); 3492 // If network becomes valid, the hasShownBroken should be reset for 3493 // that network so that the notification will be fired when the private 3494 // DNS is broken again. 3495 nai.networkAgentConfig.hasShownBroken = false; 3496 } 3497 } else if (partialConnectivityChanged) { 3498 updateCapabilitiesForNetwork(nai); 3499 } 3500 updateInetCondition(nai); 3501 // Let the NetworkAgent know the state of its network 3502 // TODO: Evaluate to update partial connectivity to status to NetworkAgent. 3503 nai.onValidationStatusChanged( 3504 valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK, 3505 redirectUrl); 3506 3507 // If NetworkMonitor detects partial connectivity before 3508 // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification 3509 // immediately. Re-notify partial connectivity silently if no internet 3510 // notification already there. 3511 if (!wasPartial && nai.partialConnectivity) { 3512 // Remove delayed message if there is a pending message. 3513 mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network); 3514 handlePromptUnvalidated(nai.network); 3515 } 3516 3517 if (wasValidated && !nai.lastValidated) { 3518 handleNetworkUnvalidated(nai); 3519 } 3520 } 3521 getCaptivePortalMode()3522 private int getCaptivePortalMode() { 3523 return Settings.Global.getInt(mContext.getContentResolver(), 3524 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, 3525 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 3526 } 3527 maybeHandleNetworkAgentInfoMessage(Message msg)3528 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 3529 switch (msg.what) { 3530 default: 3531 return false; 3532 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 3533 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 3534 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 3535 handleLingerComplete(nai); 3536 } 3537 break; 3538 } 3539 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: { 3540 handleNetworkAgentRegistered(msg); 3541 break; 3542 } 3543 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: { 3544 handleNetworkAgentDisconnected(msg); 3545 break; 3546 } 3547 } 3548 return true; 3549 } 3550 3551 @Override handleMessage(Message msg)3552 public void handleMessage(Message msg) { 3553 if (!maybeHandleNetworkMonitorMessage(msg) 3554 && !maybeHandleNetworkAgentInfoMessage(msg)) { 3555 maybeHandleNetworkAgentMessage(msg); 3556 } 3557 } 3558 } 3559 3560 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub { 3561 private final int mNetId; 3562 private final AutodestructReference<NetworkAgentInfo> mNai; 3563 NetworkMonitorCallbacks(NetworkAgentInfo nai)3564 private NetworkMonitorCallbacks(NetworkAgentInfo nai) { 3565 mNetId = nai.network.getNetId(); 3566 mNai = new AutodestructReference<>(nai); 3567 } 3568 3569 @Override onNetworkMonitorCreated(INetworkMonitor networkMonitor)3570 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 3571 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, 3572 new Pair<>(mNai.getAndDestroy(), networkMonitor))); 3573 } 3574 3575 @Override notifyNetworkTested(int testResult, @Nullable String redirectUrl)3576 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { 3577 // Legacy version of notifyNetworkTestedWithExtras. 3578 // Would only be called if the system has a NetworkStack module older than the 3579 // framework, which does not happen in practice. 3580 Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken"); 3581 } 3582 3583 @Override notifyNetworkTestedWithExtras(NetworkTestResultParcelable p)3584 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) { 3585 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use 3586 // the same looper so messages will be processed in sequence. 3587 final Message msg = mTrackerHandler.obtainMessage( 3588 EVENT_NETWORK_TESTED, 3589 new NetworkTestedResults( 3590 mNetId, p.result, p.timestampMillis, p.redirectUrl)); 3591 mTrackerHandler.sendMessage(msg); 3592 3593 // Invoke ConnectivityReport generation for this Network test event. 3594 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId); 3595 if (nai == null) return; 3596 3597 final PersistableBundle extras = new PersistableBundle(); 3598 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, p.result); 3599 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded); 3600 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted); 3601 3602 ConnectivityReportEvent reportEvent = 3603 new ConnectivityReportEvent(p.timestampMillis, nai, extras); 3604 final Message m = mConnectivityDiagnosticsHandler.obtainMessage( 3605 ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, reportEvent); 3606 mConnectivityDiagnosticsHandler.sendMessage(m); 3607 } 3608 3609 @Override notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config)3610 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) { 3611 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 3612 EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 3613 0, mNetId, PrivateDnsConfig.fromParcel(config))); 3614 } 3615 3616 @Override notifyProbeStatusChanged(int probesCompleted, int probesSucceeded)3617 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) { 3618 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 3619 EVENT_PROBE_STATUS_CHANGED, 3620 probesCompleted, probesSucceeded, new Integer(mNetId))); 3621 } 3622 3623 @Override notifyCaptivePortalDataChanged(CaptivePortalData data)3624 public void notifyCaptivePortalDataChanged(CaptivePortalData data) { 3625 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 3626 EVENT_CAPPORT_DATA_CHANGED, 3627 0, mNetId, data)); 3628 } 3629 3630 @Override showProvisioningNotification(String action, String packageName)3631 public void showProvisioningNotification(String action, String packageName) { 3632 final Intent intent = new Intent(action); 3633 intent.setPackage(packageName); 3634 3635 final PendingIntent pendingIntent; 3636 // Only the system server can register notifications with package "android" 3637 final long token = Binder.clearCallingIdentity(); 3638 try { 3639 pendingIntent = PendingIntent.getBroadcast( 3640 mContext, 3641 0 /* requestCode */, 3642 intent, 3643 PendingIntent.FLAG_IMMUTABLE); 3644 } finally { 3645 Binder.restoreCallingIdentity(token); 3646 } 3647 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 3648 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW, 3649 mNetId, pendingIntent)); 3650 } 3651 3652 @Override hideProvisioningNotification()3653 public void hideProvisioningNotification() { 3654 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 3655 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); 3656 } 3657 3658 @Override notifyDataStallSuspected(DataStallReportParcelable p)3659 public void notifyDataStallSuspected(DataStallReportParcelable p) { 3660 ConnectivityService.this.notifyDataStallSuspected(p, mNetId); 3661 } 3662 3663 @Override getInterfaceVersion()3664 public int getInterfaceVersion() { 3665 return this.VERSION; 3666 } 3667 3668 @Override getInterfaceHash()3669 public String getInterfaceHash() { 3670 return this.HASH; 3671 } 3672 } 3673 notifyDataStallSuspected(DataStallReportParcelable p, int netId)3674 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) { 3675 log("Data stall detected with methods: " + p.detectionMethod); 3676 3677 final PersistableBundle extras = new PersistableBundle(); 3678 int detectionMethod = 0; 3679 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 3680 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); 3681 detectionMethod |= DETECTION_METHOD_DNS_EVENTS; 3682 } 3683 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 3684 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); 3685 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, 3686 p.tcpMetricsCollectionPeriodMillis); 3687 detectionMethod |= DETECTION_METHOD_TCP_METRICS; 3688 } 3689 3690 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( 3691 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId, 3692 new Pair<>(p.timestampMillis, extras)); 3693 3694 // NetworkStateTrackerHandler currently doesn't take any actions based on data 3695 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid 3696 // the cost of going through two handlers. 3697 mConnectivityDiagnosticsHandler.sendMessage(msg); 3698 } 3699 hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod)3700 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) { 3701 return (p.detectionMethod & detectionMethod) != 0; 3702 } 3703 networkRequiresPrivateDnsValidation(NetworkAgentInfo nai)3704 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { 3705 return isPrivateDnsValidationRequired(nai.networkCapabilities); 3706 } 3707 handleFreshlyValidatedNetwork(NetworkAgentInfo nai)3708 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { 3709 if (nai == null) return; 3710 // If the Private DNS mode is opportunistic, reprogram the DNS servers 3711 // in order to restart a validation pass from within netd. 3712 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 3713 if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) { 3714 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 3715 } 3716 } 3717 handlePrivateDnsSettingsChanged()3718 private void handlePrivateDnsSettingsChanged() { 3719 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 3720 3721 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 3722 handlePerNetworkPrivateDnsConfig(nai, cfg); 3723 if (networkRequiresPrivateDnsValidation(nai)) { 3724 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 3725 } 3726 } 3727 } 3728 handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)3729 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 3730 // Private DNS only ever applies to networks that might provide 3731 // Internet access and therefore also require validation. 3732 if (!networkRequiresPrivateDnsValidation(nai)) return; 3733 3734 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or 3735 // schedule DNS resolutions. If a DNS resolution is required the 3736 // result will be sent back to us. 3737 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel()); 3738 3739 // With Private DNS bypass support, we can proceed to update the 3740 // Private DNS config immediately, even if we're in strict mode 3741 // and have not yet resolved the provider name into a set of IPs. 3742 updatePrivateDns(nai, cfg); 3743 } 3744 updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)3745 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 3746 mDnsManager.updatePrivateDns(nai.network, newCfg); 3747 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 3748 } 3749 handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)3750 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 3751 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 3752 if (nai == null) { 3753 return; 3754 } 3755 mDnsManager.updatePrivateDnsValidation(update); 3756 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 3757 } 3758 handleNat64PrefixEvent(int netId, int operation, String prefixAddress, int prefixLength)3759 private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, 3760 int prefixLength) { 3761 NetworkAgentInfo nai = mNetworkForNetId.get(netId); 3762 if (nai == null) return; 3763 3764 log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", 3765 netId, operation, prefixAddress, prefixLength)); 3766 3767 IpPrefix prefix = null; 3768 if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { 3769 try { 3770 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), 3771 prefixLength); 3772 } catch (IllegalArgumentException e) { 3773 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); 3774 return; 3775 } 3776 } 3777 3778 nai.clatd.setNat64PrefixFromDns(prefix); 3779 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 3780 } 3781 handleCapportApiDataUpdate(@onNull final NetworkAgentInfo nai, @Nullable final CaptivePortalData data)3782 private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai, 3783 @Nullable final CaptivePortalData data) { 3784 nai.capportApiData = data; 3785 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo 3786 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 3787 } 3788 3789 /** 3790 * Updates the inactivity state from the network requests inside the NAI. 3791 * @param nai the agent info to update 3792 * @param now the timestamp of the event causing this update 3793 * @return whether the network was inactive as a result of this update 3794 */ updateInactivityState(@onNull final NetworkAgentInfo nai, final long now)3795 private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) { 3796 // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm. 3797 // 2. If the network was inactive and there are now requests, unset inactive. 3798 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 3799 // one lingered request, set inactive. 3800 nai.updateInactivityTimer(); 3801 if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) { 3802 if (DBG) log("Unsetting inactive " + nai.toShortString()); 3803 nai.unsetInactive(); 3804 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 3805 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) { 3806 if (DBG) { 3807 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 3808 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms"); 3809 } 3810 nai.setInactive(); 3811 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 3812 return true; 3813 } 3814 return false; 3815 } 3816 handleNetworkAgentRegistered(Message msg)3817 private void handleNetworkAgentRegistered(Message msg) { 3818 final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 3819 if (!mNetworkAgentInfos.contains(nai)) { 3820 return; 3821 } 3822 3823 if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) { 3824 if (VDBG) log("NetworkAgent registered"); 3825 } else { 3826 loge("Error connecting NetworkAgent"); 3827 mNetworkAgentInfos.remove(nai); 3828 if (nai != null) { 3829 final boolean wasDefault = isDefaultNetwork(nai); 3830 synchronized (mNetworkForNetId) { 3831 mNetworkForNetId.remove(nai.network.getNetId()); 3832 } 3833 mNetIdManager.releaseNetId(nai.network.getNetId()); 3834 // Just in case. 3835 mLegacyTypeTracker.remove(nai, wasDefault); 3836 } 3837 } 3838 } 3839 handleNetworkAgentDisconnected(Message msg)3840 private void handleNetworkAgentDisconnected(Message msg) { 3841 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 3842 if (mNetworkAgentInfos.contains(nai)) { 3843 disconnectAndDestroyNetwork(nai); 3844 } 3845 } 3846 3847 // Destroys a network, remove references to it from the internal state managed by 3848 // ConnectivityService, free its interfaces and clean up. 3849 // Must be called on the Handler thread. disconnectAndDestroyNetwork(NetworkAgentInfo nai)3850 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 3851 ensureRunningOnConnectivityServiceThread(); 3852 if (DBG) { 3853 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests()); 3854 } 3855 // Clear all notifications of this network. 3856 mNotifier.clearNotification(nai.network.getNetId()); 3857 // A network agent has disconnected. 3858 // TODO - if we move the logic to the network agent (have them disconnect 3859 // because they lost all their requests or because their score isn't good) 3860 // then they would disconnect organically, report their new state and then 3861 // disconnect the channel. 3862 if (nai.networkInfo.isConnected()) { 3863 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 3864 null, null); 3865 } 3866 final boolean wasDefault = isDefaultNetwork(nai); 3867 if (wasDefault) { 3868 mDefaultInetConditionPublished = 0; 3869 } 3870 notifyIfacesChangedForNetworkStats(); 3871 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 3872 // by other networks that are already connected. Perhaps that can be done by 3873 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 3874 // of rematchAllNetworksAndRequests 3875 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 3876 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK); 3877 3878 mQosCallbackTracker.handleNetworkReleased(nai.network); 3879 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 3880 // Disable wakeup packet monitoring for each interface. 3881 wakeupModifyInterface(iface, nai.networkCapabilities, false); 3882 } 3883 nai.networkMonitor().notifyNetworkDisconnected(); 3884 mNetworkAgentInfos.remove(nai); 3885 nai.clatd.update(); 3886 synchronized (mNetworkForNetId) { 3887 // Remove the NetworkAgent, but don't mark the netId as 3888 // available until we've told netd to delete it below. 3889 mNetworkForNetId.remove(nai.network.getNetId()); 3890 } 3891 propagateUnderlyingNetworkCapabilities(nai.network); 3892 // Remove all previously satisfied requests. 3893 for (int i = 0; i < nai.numNetworkRequests(); i++) { 3894 final NetworkRequest request = nai.requestAt(i); 3895 final NetworkRequestInfo nri = mNetworkRequests.get(request); 3896 final NetworkAgentInfo currentNetwork = nri.getSatisfier(); 3897 if (currentNetwork != null 3898 && currentNetwork.network.getNetId() == nai.network.getNetId()) { 3899 // uid rules for this network will be removed in destroyNativeNetwork(nai). 3900 // TODO : setting the satisfier is in fact the job of the rematch. Teach the 3901 // rematch not to keep disconnected agents instead of setting it here ; this 3902 // will also allow removing updating the offers below. 3903 nri.setSatisfier(null, null); 3904 for (final NetworkOfferInfo noi : mNetworkOffers) { 3905 informOffer(nri, noi.offer, mNetworkRanker); 3906 } 3907 3908 if (mDefaultRequest == nri) { 3909 // TODO : make battery stats aware that since 2013 multiple interfaces may be 3910 // active at the same time. For now keep calling this with the default 3911 // network, because while incorrect this is the closest to the old (also 3912 // incorrect) behavior. 3913 mNetworkActivityTracker.updateDataActivityTracking( 3914 null /* newNetwork */, nai); 3915 ensureNetworkTransitionWakelock(nai.toShortString()); 3916 } 3917 } 3918 } 3919 nai.clearInactivityState(); 3920 // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after. 3921 // Currently, deleting it breaks tests that check for the default network disconnecting. 3922 // Find out why, fix the rematch code, and delete this. 3923 mLegacyTypeTracker.remove(nai, wasDefault); 3924 rematchAllNetworksAndRequests(); 3925 mLingerMonitor.noteDisconnect(nai); 3926 3927 // Immediate teardown. 3928 if (nai.teardownDelayMs == 0) { 3929 destroyNetwork(nai); 3930 return; 3931 } 3932 3933 // Delayed teardown. 3934 try { 3935 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM); 3936 } catch (RemoteException e) { 3937 Log.d(TAG, "Error marking network restricted during teardown: " + e); 3938 } 3939 mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs); 3940 } 3941 destroyNetwork(NetworkAgentInfo nai)3942 private void destroyNetwork(NetworkAgentInfo nai) { 3943 if (nai.created) { 3944 // Tell netd to clean up the configuration for this network 3945 // (routing rules, DNS, etc). 3946 // This may be slow as it requires a lot of netd shelling out to ip and 3947 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 3948 // after we've rematched networks with requests (which might change the default 3949 // network or service a new request from an app), so network traffic isn't interrupted 3950 // for an unnecessarily long time. 3951 destroyNativeNetwork(nai); 3952 mDnsManager.removeNetwork(nai.network); 3953 } 3954 mNetIdManager.releaseNetId(nai.network.getNetId()); 3955 nai.onNetworkDestroyed(); 3956 } 3957 createNativeNetwork(@onNull NetworkAgentInfo nai)3958 private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) { 3959 try { 3960 // This should never fail. Specifying an already in use NetID will cause failure. 3961 final NativeNetworkConfig config; 3962 if (nai.isVPN()) { 3963 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) { 3964 Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString()); 3965 return false; 3966 } 3967 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL, 3968 INetd.PERMISSION_NONE, 3969 (nai.networkAgentConfig == null || !nai.networkAgentConfig.allowBypass), 3970 getVpnType(nai)); 3971 } else { 3972 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL, 3973 getNetworkPermission(nai.networkCapabilities), /*secure=*/ false, 3974 VpnManager.TYPE_VPN_NONE); 3975 } 3976 mNetd.networkCreate(config); 3977 mDnsResolver.createNetworkCache(nai.network.getNetId()); 3978 mDnsManager.updateTransportsForNetwork(nai.network.getNetId(), 3979 nai.networkCapabilities.getTransportTypes()); 3980 return true; 3981 } catch (RemoteException | ServiceSpecificException e) { 3982 loge("Error creating network " + nai.toShortString() + ": " + e.getMessage()); 3983 return false; 3984 } 3985 } 3986 destroyNativeNetwork(@onNull NetworkAgentInfo nai)3987 private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 3988 try { 3989 mNetd.networkDestroy(nai.network.getNetId()); 3990 } catch (RemoteException | ServiceSpecificException e) { 3991 loge("Exception destroying network(networkDestroy): " + e); 3992 } 3993 try { 3994 mDnsResolver.destroyNetworkCache(nai.network.getNetId()); 3995 } catch (RemoteException | ServiceSpecificException e) { 3996 loge("Exception destroying network: " + e); 3997 } 3998 } 3999 4000 // If this method proves to be too slow then we can maintain a separate 4001 // pendingIntent => NetworkRequestInfo map. 4002 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. findExistingNetworkRequestInfo(PendingIntent pendingIntent)4003 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 4004 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 4005 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 4006 if (existingPendingIntent != null && 4007 mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) { 4008 return entry.getValue(); 4009 } 4010 } 4011 return null; 4012 } 4013 handleRegisterNetworkRequestWithIntent(@onNull final Message msg)4014 private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) { 4015 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 4016 // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests. 4017 ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent"); 4018 final NetworkRequestInfo existingRequest = 4019 findExistingNetworkRequestInfo(nri.mPendingIntent); 4020 if (existingRequest != null) { // remove the existing request. 4021 if (DBG) { 4022 log("Replacing " + existingRequest.mRequests.get(0) + " with " 4023 + nri.mRequests.get(0) + " because their intents matched."); 4024 } 4025 handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(), 4026 /* callOnUnavailable */ false); 4027 } 4028 handleRegisterNetworkRequest(nri); 4029 } 4030 handleRegisterNetworkRequest(@onNull final NetworkRequestInfo nri)4031 private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) { 4032 handleRegisterNetworkRequests(Collections.singleton(nri)); 4033 } 4034 handleRegisterNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)4035 private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 4036 ensureRunningOnConnectivityServiceThread(); 4037 for (final NetworkRequestInfo nri : nris) { 4038 mNetworkRequestInfoLogs.log("REGISTER " + nri); 4039 for (final NetworkRequest req : nri.mRequests) { 4040 mNetworkRequests.put(req, nri); 4041 // TODO: Consider update signal strength for other types. 4042 if (req.isListen()) { 4043 for (final NetworkAgentInfo network : mNetworkAgentInfos) { 4044 if (req.networkCapabilities.hasSignalStrength() 4045 && network.satisfiesImmutableCapabilitiesOf(req)) { 4046 updateSignalStrengthThresholds(network, "REGISTER", req); 4047 } 4048 } 4049 } 4050 } 4051 // If this NRI has a satisfier already, it is replacing an older request that 4052 // has been removed. Track it. 4053 final NetworkRequest activeRequest = nri.getActiveRequest(); 4054 if (null != activeRequest) { 4055 // If there is an active request, then for sure there is a satisfier. 4056 nri.getSatisfier().addRequest(activeRequest); 4057 } 4058 } 4059 4060 rematchAllNetworksAndRequests(); 4061 4062 // Requests that have not been matched to a network will not have been sent to the 4063 // providers, because the old satisfier and the new satisfier are the same (null in this 4064 // case). Send these requests to the providers. 4065 for (final NetworkRequestInfo nri : nris) { 4066 for (final NetworkOfferInfo noi : mNetworkOffers) { 4067 informOffer(nri, noi.offer, mNetworkRanker); 4068 } 4069 } 4070 } 4071 handleReleaseNetworkRequestWithIntent(@onNull final PendingIntent pendingIntent, final int callingUid)4072 private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent, 4073 final int callingUid) { 4074 final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 4075 if (nri != null) { 4076 // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests. 4077 ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent"); 4078 handleReleaseNetworkRequest( 4079 nri.mRequests.get(0), 4080 callingUid, 4081 /* callOnUnavailable */ false); 4082 } 4083 } 4084 4085 // Determines whether the network is the best (or could become the best, if it validated), for 4086 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 4087 // on the value of reason: 4088 // 4089 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 4090 // then it should be torn down. 4091 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 4092 // then it should be lingered. unneeded(NetworkAgentInfo nai, UnneededFor reason)4093 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 4094 ensureRunningOnConnectivityServiceThread(); 4095 4096 if (!nai.everConnected || nai.isVPN() || nai.isInactive() 4097 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) { 4098 return false; 4099 } 4100 4101 final int numRequests; 4102 switch (reason) { 4103 case TEARDOWN: 4104 numRequests = nai.numRequestNetworkRequests(); 4105 break; 4106 case LINGER: 4107 numRequests = nai.numForegroundNetworkRequests(); 4108 break; 4109 default: 4110 Log.wtf(TAG, "Invalid reason. Cannot happen."); 4111 return true; 4112 } 4113 4114 if (numRequests > 0) return false; 4115 4116 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 4117 if (reason == UnneededFor.LINGER 4118 && !nri.isMultilayerRequest() 4119 && nri.mRequests.get(0).isBackgroundRequest()) { 4120 // Background requests don't affect lingering. 4121 continue; 4122 } 4123 4124 if (isNetworkPotentialSatisfier(nai, nri)) { 4125 return false; 4126 } 4127 } 4128 return true; 4129 } 4130 isNetworkPotentialSatisfier( @onNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri)4131 private boolean isNetworkPotentialSatisfier( 4132 @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) { 4133 // listen requests won't keep up a network satisfying it. If this is not a multilayer 4134 // request, return immediately. For multilayer requests, check to see if any of the 4135 // multilayer requests may have a potential satisfier. 4136 if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen() 4137 || nri.mRequests.get(0).isListenForBest())) { 4138 return false; 4139 } 4140 for (final NetworkRequest req : nri.mRequests) { 4141 // This multilayer listen request is satisfied therefore no further requests need to be 4142 // evaluated deeming this network not a potential satisfier. 4143 if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) { 4144 return false; 4145 } 4146 // As non-multilayer listen requests have already returned, the below would only happen 4147 // for a multilayer request therefore continue to the next request if available. 4148 if (req.isListen() || req.isListenForBest()) { 4149 continue; 4150 } 4151 // If this Network is already the highest scoring Network for a request, or if 4152 // there is hope for it to become one if it validated, then it is needed. 4153 if (candidate.satisfies(req)) { 4154 // As soon as a network is found that satisfies a request, return. Specifically for 4155 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request 4156 // is important so as to not evaluate lower priority requests further in 4157 // nri.mRequests. 4158 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest()) 4159 ? nri.getSatisfier() : null; 4160 // Note that this catches two important cases: 4161 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 4162 // is currently satisfying the request. This is desirable when 4163 // cellular ends up validating but WiFi does not. 4164 // 2. Unvalidated WiFi will not be reaped when validated cellular 4165 // is currently satisfying the request. This is desirable when 4166 // WiFi ends up validating and out scoring cellular. 4167 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable()); 4168 } 4169 } 4170 4171 return false; 4172 } 4173 getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)4174 private NetworkRequestInfo getNriForAppRequest( 4175 NetworkRequest request, int callingUid, String requestedOperation) { 4176 // Looking up the app passed param request in mRequests isn't possible since it may return 4177 // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to 4178 // do the lookup since that will also find per-app default managed requests. 4179 // Additionally, this lookup needs to be relatively fast (hence the lookup optimization) 4180 // to avoid potential race conditions when validating a package->uid mapping when sending 4181 // the callback on the very low-chance that an application shuts down prior to the callback 4182 // being sent. 4183 final NetworkRequestInfo nri = mNetworkRequests.get(request) != null 4184 ? mNetworkRequests.get(request) : getNriForAppRequest(request); 4185 4186 if (nri != null) { 4187 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 4188 log(String.format("UID %d attempted to %s for unowned request %s", 4189 callingUid, requestedOperation, nri)); 4190 return null; 4191 } 4192 } 4193 4194 return nri; 4195 } 4196 ensureNotMultilayerRequest(@onNull final NetworkRequestInfo nri, final String callingMethod)4197 private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri, 4198 final String callingMethod) { 4199 if (nri.isMultilayerRequest()) { 4200 throw new IllegalStateException( 4201 callingMethod + " does not support multilayer requests."); 4202 } 4203 } 4204 handleTimedOutNetworkRequest(@onNull final NetworkRequestInfo nri)4205 private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) { 4206 ensureRunningOnConnectivityServiceThread(); 4207 // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a 4208 // single NetworkRequest and thus does not apply to multilayer requests. 4209 ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest"); 4210 if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { 4211 return; 4212 } 4213 if (nri.isBeingSatisfied()) { 4214 return; 4215 } 4216 if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) { 4217 log("releasing " + nri.mRequests.get(0) + " (timeout)"); 4218 } 4219 handleRemoveNetworkRequest(nri); 4220 callCallbackForRequest( 4221 nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 4222 } 4223 handleReleaseNetworkRequest(@onNull final NetworkRequest request, final int callingUid, final boolean callOnUnavailable)4224 private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request, 4225 final int callingUid, 4226 final boolean callOnUnavailable) { 4227 final NetworkRequestInfo nri = 4228 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 4229 if (nri == null) { 4230 return; 4231 } 4232 if (VDBG || (DBG && request.isRequest())) { 4233 log("releasing " + request + " (release request)"); 4234 } 4235 handleRemoveNetworkRequest(nri); 4236 if (callOnUnavailable) { 4237 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 4238 } 4239 } 4240 handleRemoveNetworkRequest(@onNull final NetworkRequestInfo nri)4241 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) { 4242 ensureRunningOnConnectivityServiceThread(); 4243 for (final NetworkRequest req : nri.mRequests) { 4244 if (null == mNetworkRequests.remove(req)) { 4245 logw("Attempted removal of untracked request " + req + " for nri " + nri); 4246 continue; 4247 } 4248 if (req.isListen()) { 4249 removeListenRequestFromNetworks(req); 4250 } 4251 } 4252 nri.unlinkDeathRecipient(); 4253 if (mDefaultNetworkRequests.remove(nri)) { 4254 // If this request was one of the defaults, then the UID rules need to be updated 4255 // WARNING : if the app(s) for which this network request is the default are doing 4256 // traffic, this will kill their connected sockets, even if an equivalent request 4257 // is going to be reinstated right away ; unconnected traffic will go on the default 4258 // until the new default is set, which will happen very soon. 4259 // TODO : The only way out of this is to diff old defaults and new defaults, and only 4260 // remove ranges for those requests that won't have a replacement 4261 final NetworkAgentInfo satisfier = nri.getSatisfier(); 4262 if (null != satisfier) { 4263 try { 4264 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 4265 satisfier.network.getNetId(), 4266 toUidRangeStableParcels(nri.getUids()), 4267 nri.getPriorityForNetd())); 4268 } catch (RemoteException e) { 4269 loge("Exception setting network preference default network", e); 4270 } 4271 } 4272 } 4273 nri.decrementRequestCount(); 4274 mNetworkRequestInfoLogs.log("RELEASE " + nri); 4275 4276 if (null != nri.getActiveRequest()) { 4277 if (!nri.getActiveRequest().isListen()) { 4278 removeSatisfiedNetworkRequestFromNetwork(nri); 4279 } else { 4280 nri.setSatisfier(null, null); 4281 } 4282 } 4283 4284 // For all outstanding offers, cancel any of the layers of this NRI that used to be 4285 // needed for this offer. 4286 for (final NetworkOfferInfo noi : mNetworkOffers) { 4287 for (final NetworkRequest req : nri.mRequests) { 4288 if (req.isRequest() && noi.offer.neededFor(req)) { 4289 noi.offer.onNetworkUnneeded(req); 4290 } 4291 } 4292 } 4293 } 4294 handleRemoveNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)4295 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 4296 for (final NetworkRequestInfo nri : nris) { 4297 if (mDefaultRequest == nri) { 4298 // Make sure we never remove the default request. 4299 continue; 4300 } 4301 handleRemoveNetworkRequest(nri); 4302 } 4303 } 4304 removeListenRequestFromNetworks(@onNull final NetworkRequest req)4305 private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) { 4306 // listens don't have a singular affected Network. Check all networks to see 4307 // if this listen request applies and remove it. 4308 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 4309 nai.removeRequest(req.requestId); 4310 if (req.networkCapabilities.hasSignalStrength() 4311 && nai.satisfiesImmutableCapabilitiesOf(req)) { 4312 updateSignalStrengthThresholds(nai, "RELEASE", req); 4313 } 4314 } 4315 } 4316 4317 /** 4318 * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and 4319 * manage the necessary upkeep (linger, teardown networks, etc.) when doing so. 4320 * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo 4321 */ removeSatisfiedNetworkRequestFromNetwork(@onNull final NetworkRequestInfo nri)4322 private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) { 4323 boolean wasKept = false; 4324 final NetworkAgentInfo nai = nri.getSatisfier(); 4325 if (nai != null) { 4326 final int requestLegacyType = nri.getActiveRequest().legacyType; 4327 final boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 4328 nai.removeRequest(nri.getActiveRequest().requestId); 4329 if (VDBG || DDBG) { 4330 log(" Removing from current network " + nai.toShortString() 4331 + ", leaving " + nai.numNetworkRequests() + " requests."); 4332 } 4333 // If there are still lingered requests on this network, don't tear it down, 4334 // but resume lingering instead. 4335 final long now = SystemClock.elapsedRealtime(); 4336 if (updateInactivityState(nai, now)) { 4337 notifyNetworkLosing(nai, now); 4338 } 4339 if (unneeded(nai, UnneededFor.TEARDOWN)) { 4340 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting"); 4341 teardownUnneededNetwork(nai); 4342 } else { 4343 wasKept = true; 4344 } 4345 nri.setSatisfier(null, null); 4346 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 4347 // Went from foreground to background. 4348 updateCapabilitiesForNetwork(nai); 4349 } 4350 4351 // Maintain the illusion. When this request arrived, we might have pretended 4352 // that a network connected to serve it, even though the network was already 4353 // connected. Now that this request has gone away, we might have to pretend 4354 // that the network disconnected. LegacyTypeTracker will generate that 4355 // phantom disconnect for this type. 4356 if (requestLegacyType != TYPE_NONE) { 4357 boolean doRemove = true; 4358 if (wasKept) { 4359 // check if any of the remaining requests for this network are for the 4360 // same legacy type - if so, don't remove the nai 4361 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4362 NetworkRequest otherRequest = nai.requestAt(i); 4363 if (otherRequest.legacyType == requestLegacyType 4364 && otherRequest.isRequest()) { 4365 if (DBG) log(" still have other legacy request - leaving"); 4366 doRemove = false; 4367 } 4368 } 4369 } 4370 4371 if (doRemove) { 4372 mLegacyTypeTracker.remove(requestLegacyType, nai, false); 4373 } 4374 } 4375 } 4376 } 4377 getRequestCounter(NetworkRequestInfo nri)4378 private PerUidCounter getRequestCounter(NetworkRequestInfo nri) { 4379 return checkAnyPermissionOf( 4380 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) 4381 ? mSystemNetworkRequestCounter : mNetworkRequestCounter; 4382 } 4383 4384 @Override setAcceptUnvalidated(Network network, boolean accept, boolean always)4385 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 4386 enforceNetworkStackSettingsOrSetup(); 4387 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 4388 encodeBool(accept), encodeBool(always), network)); 4389 } 4390 4391 @Override setAcceptPartialConnectivity(Network network, boolean accept, boolean always)4392 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { 4393 enforceNetworkStackSettingsOrSetup(); 4394 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY, 4395 encodeBool(accept), encodeBool(always), network)); 4396 } 4397 4398 @Override setAvoidUnvalidated(Network network)4399 public void setAvoidUnvalidated(Network network) { 4400 enforceNetworkStackSettingsOrSetup(); 4401 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 4402 } 4403 4404 @Override setTestAllowBadWifiUntil(long timeMs)4405 public void setTestAllowBadWifiUntil(long timeMs) { 4406 enforceSettingsPermission(); 4407 if (!Build.isDebuggable()) { 4408 throw new IllegalStateException("Does not support in non-debuggable build"); 4409 } 4410 4411 if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) { 4412 throw new IllegalArgumentException("It should not exceed " 4413 + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now"); 4414 } 4415 4416 mHandler.sendMessage( 4417 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs)); 4418 } 4419 handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)4420 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 4421 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 4422 " accept=" + accept + " always=" + always); 4423 4424 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4425 if (nai == null) { 4426 // Nothing to do. 4427 return; 4428 } 4429 4430 if (nai.everValidated) { 4431 // The network validated while the dialog box was up. Take no action. 4432 return; 4433 } 4434 4435 if (!nai.networkAgentConfig.explicitlySelected) { 4436 Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 4437 } 4438 4439 if (accept != nai.networkAgentConfig.acceptUnvalidated) { 4440 nai.networkAgentConfig.acceptUnvalidated = accept; 4441 // If network becomes partial connectivity and user already accepted to use this 4442 // network, we should respect the user's option and don't need to popup the 4443 // PARTIAL_CONNECTIVITY notification to user again. 4444 nai.networkAgentConfig.acceptPartialConnectivity = accept; 4445 nai.updateScoreForNetworkAgentUpdate(); 4446 rematchAllNetworksAndRequests(); 4447 } 4448 4449 if (always) { 4450 nai.onSaveAcceptUnvalidated(accept); 4451 } 4452 4453 if (!accept) { 4454 // Tell the NetworkAgent to not automatically reconnect to the network. 4455 nai.onPreventAutomaticReconnect(); 4456 // Teardown the network. 4457 teardownUnneededNetwork(nai); 4458 } 4459 4460 } 4461 handleSetAcceptPartialConnectivity(Network network, boolean accept, boolean always)4462 private void handleSetAcceptPartialConnectivity(Network network, boolean accept, 4463 boolean always) { 4464 if (DBG) { 4465 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept 4466 + " always=" + always); 4467 } 4468 4469 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4470 if (nai == null) { 4471 // Nothing to do. 4472 return; 4473 } 4474 4475 if (nai.lastValidated) { 4476 // The network validated while the dialog box was up. Take no action. 4477 return; 4478 } 4479 4480 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) { 4481 nai.networkAgentConfig.acceptPartialConnectivity = accept; 4482 } 4483 4484 // TODO: Use the current design or save the user choice into IpMemoryStore. 4485 if (always) { 4486 nai.onSaveAcceptUnvalidated(accept); 4487 } 4488 4489 if (!accept) { 4490 // Tell the NetworkAgent to not automatically reconnect to the network. 4491 nai.onPreventAutomaticReconnect(); 4492 // Tear down the network. 4493 teardownUnneededNetwork(nai); 4494 } else { 4495 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely 4496 // result in a partial connectivity result which will be processed by 4497 // maybeHandleNetworkMonitorMessage. 4498 // 4499 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored 4500 // per network. Therefore, NetworkMonitor may still do https probe. 4501 nai.networkMonitor().setAcceptPartialConnectivity(); 4502 } 4503 } 4504 handleSetAvoidUnvalidated(Network network)4505 private void handleSetAvoidUnvalidated(Network network) { 4506 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4507 if (nai == null || nai.lastValidated) { 4508 // Nothing to do. The network either disconnected or revalidated. 4509 return; 4510 } 4511 if (!nai.avoidUnvalidated) { 4512 nai.avoidUnvalidated = true; 4513 nai.updateScoreForNetworkAgentUpdate(); 4514 rematchAllNetworksAndRequests(); 4515 } 4516 } 4517 scheduleUnvalidatedPrompt(NetworkAgentInfo nai)4518 private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { 4519 if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); 4520 mHandler.sendMessageDelayed( 4521 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network), 4522 PROMPT_UNVALIDATED_DELAY_MS); 4523 } 4524 4525 @Override startCaptivePortalApp(Network network)4526 public void startCaptivePortalApp(Network network) { 4527 enforceNetworkStackOrSettingsPermission(); 4528 mHandler.post(() -> { 4529 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4530 if (nai == null) return; 4531 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 4532 nai.networkMonitor().launchCaptivePortalApp(); 4533 }); 4534 } 4535 4536 /** 4537 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this 4538 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. 4539 * @param network Network on which the captive portal was detected. 4540 * @param appExtras Bundle to use as intent extras for the captive portal application. 4541 * Must be treated as opaque to avoid preventing the captive portal app to 4542 * update its arguments. 4543 */ 4544 @Override startCaptivePortalAppInternal(Network network, Bundle appExtras)4545 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { 4546 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 4547 "ConnectivityService"); 4548 4549 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); 4550 appIntent.putExtras(appExtras); 4551 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, 4552 new CaptivePortal(new CaptivePortalImpl(network).asBinder())); 4553 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); 4554 4555 final long token = Binder.clearCallingIdentity(); 4556 try { 4557 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT); 4558 } finally { 4559 Binder.restoreCallingIdentity(token); 4560 } 4561 } 4562 4563 private class CaptivePortalImpl extends ICaptivePortal.Stub { 4564 private final Network mNetwork; 4565 CaptivePortalImpl(Network network)4566 private CaptivePortalImpl(Network network) { 4567 mNetwork = network; 4568 } 4569 4570 @Override appResponse(final int response)4571 public void appResponse(final int response) { 4572 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { 4573 enforceSettingsPermission(); 4574 } 4575 4576 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 4577 if (nm == null) return; 4578 nm.notifyCaptivePortalAppFinished(response); 4579 } 4580 4581 @Override appRequest(final int request)4582 public void appRequest(final int request) { 4583 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 4584 if (nm == null) return; 4585 4586 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) { 4587 checkNetworkStackPermission(); 4588 nm.forceReevaluation(mDeps.getCallingUid()); 4589 } 4590 } 4591 4592 @Nullable getNetworkMonitorManager(final Network network)4593 private NetworkMonitorManager getNetworkMonitorManager(final Network network) { 4594 // getNetworkAgentInfoForNetwork is thread-safe 4595 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4596 if (nai == null) return null; 4597 4598 // nai.networkMonitor() is thread-safe 4599 return nai.networkMonitor(); 4600 } 4601 } 4602 avoidBadWifi()4603 public boolean avoidBadWifi() { 4604 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 4605 } 4606 4607 /** 4608 * Return whether the device should maintain continuous, working connectivity by switching away 4609 * from WiFi networks having no connectivity. 4610 * @see MultinetworkPolicyTracker#getAvoidBadWifi() 4611 */ shouldAvoidBadWifi()4612 public boolean shouldAvoidBadWifi() { 4613 if (!checkNetworkStackPermission()) { 4614 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); 4615 } 4616 return avoidBadWifi(); 4617 } 4618 updateAvoidBadWifi()4619 private void updateAvoidBadWifi() { 4620 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 4621 nai.updateScoreForNetworkAgentUpdate(); 4622 } 4623 rematchAllNetworksAndRequests(); 4624 } 4625 4626 // TODO: Evaluate whether this is of interest to other consumers of 4627 // MultinetworkPolicyTracker and worth moving out of here. dumpAvoidBadWifiSettings(IndentingPrintWriter pw)4628 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 4629 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 4630 if (!configRestrict) { 4631 pw.println("Bad Wi-Fi avoidance: unrestricted"); 4632 return; 4633 } 4634 4635 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 4636 pw.increaseIndent(); 4637 pw.println("Config restrict: " + configRestrict); 4638 4639 final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 4640 String description; 4641 // Can't use a switch statement because strings are legal case labels, but null is not. 4642 if ("0".equals(value)) { 4643 description = "get stuck"; 4644 } else if (value == null) { 4645 description = "prompt"; 4646 } else if ("1".equals(value)) { 4647 description = "avoid"; 4648 } else { 4649 description = value + " (?)"; 4650 } 4651 pw.println("User setting: " + description); 4652 pw.println("Network overrides:"); 4653 pw.increaseIndent(); 4654 for (NetworkAgentInfo nai : networksSortedById()) { 4655 if (nai.avoidUnvalidated) { 4656 pw.println(nai.toShortString()); 4657 } 4658 } 4659 pw.decreaseIndent(); 4660 pw.decreaseIndent(); 4661 } 4662 4663 // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to 4664 // unify the method. getSettingsPackageName(@onNull final PackageManager pm)4665 private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) { 4666 final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS); 4667 final ComponentName settingsComponent = settingsIntent.resolveActivity(pm); 4668 return settingsComponent != null 4669 ? settingsComponent.getPackageName() : "com.android.settings"; 4670 } 4671 showNetworkNotification(NetworkAgentInfo nai, NotificationType type)4672 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) { 4673 final String action; 4674 final boolean highPriority; 4675 switch (type) { 4676 case NO_INTERNET: 4677 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 4678 // High priority because it is only displayed for explicitly selected networks. 4679 highPriority = true; 4680 break; 4681 case PRIVATE_DNS_BROKEN: 4682 action = Settings.ACTION_WIRELESS_SETTINGS; 4683 // High priority because we should let user know why there is no internet. 4684 highPriority = true; 4685 break; 4686 case LOST_INTERNET: 4687 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 4688 // High priority because it could help the user avoid unexpected data usage. 4689 highPriority = true; 4690 break; 4691 case PARTIAL_CONNECTIVITY: 4692 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY; 4693 // Don't bother the user with a high-priority notification if the network was not 4694 // explicitly selected by the user. 4695 highPriority = nai.networkAgentConfig.explicitlySelected; 4696 break; 4697 default: 4698 Log.wtf(TAG, "Unknown notification type " + type); 4699 return; 4700 } 4701 4702 Intent intent = new Intent(action); 4703 if (type != NotificationType.PRIVATE_DNS_BROKEN) { 4704 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network); 4705 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4706 // Some OEMs have their own Settings package. Thus, need to get the current using 4707 // Settings package name instead of just use default name "com.android.settings". 4708 final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager()); 4709 intent.setClassName(settingsPkgName, 4710 settingsPkgName + ".wifi.WifiNoInternetDialog"); 4711 } 4712 4713 PendingIntent pendingIntent = PendingIntent.getActivity( 4714 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 4715 0 /* requestCode */, 4716 intent, 4717 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 4718 4719 mNotifier.showNotification( 4720 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority); 4721 } 4722 shouldPromptUnvalidated(NetworkAgentInfo nai)4723 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) { 4724 // Don't prompt if the network is validated, and don't prompt on captive portals 4725 // because we're already prompting the user to sign in. 4726 if (nai.everValidated || nai.everCaptivePortalDetected) { 4727 return false; 4728 } 4729 4730 // If a network has partial connectivity, always prompt unless the user has already accepted 4731 // partial connectivity and selected don't ask again. This ensures that if the device 4732 // automatically connects to a network that has partial Internet access, the user will 4733 // always be able to use it, either because they've already chosen "don't ask again" or 4734 // because we have prompt them. 4735 if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) { 4736 return true; 4737 } 4738 4739 // If a network has no Internet access, only prompt if the network was explicitly selected 4740 // and if the user has not already told us to use the network regardless of whether it 4741 // validated or not. 4742 if (nai.networkAgentConfig.explicitlySelected 4743 && !nai.networkAgentConfig.acceptUnvalidated) { 4744 return true; 4745 } 4746 4747 return false; 4748 } 4749 handlePromptUnvalidated(Network network)4750 private void handlePromptUnvalidated(Network network) { 4751 if (VDBG || DDBG) log("handlePromptUnvalidated " + network); 4752 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4753 4754 if (nai == null || !shouldPromptUnvalidated(nai)) { 4755 return; 4756 } 4757 4758 // Stop automatically reconnecting to this network in the future. Automatically connecting 4759 // to a network that provides no or limited connectivity is not useful, because the user 4760 // cannot use that network except through the notification shown by this method, and the 4761 // notification is only shown if the network is explicitly selected by the user. 4762 nai.onPreventAutomaticReconnect(); 4763 4764 // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when 4765 // NetworkMonitor detects the network is partial connectivity. Need to change the design to 4766 // popup the notification immediately when the network is partial connectivity. 4767 if (nai.partialConnectivity) { 4768 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); 4769 } else { 4770 showNetworkNotification(nai, NotificationType.NO_INTERNET); 4771 } 4772 } 4773 handleNetworkUnvalidated(NetworkAgentInfo nai)4774 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 4775 NetworkCapabilities nc = nai.networkCapabilities; 4776 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc); 4777 4778 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 4779 return; 4780 } 4781 4782 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 4783 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 4784 } 4785 } 4786 4787 @Override getMultipathPreference(Network network)4788 public int getMultipathPreference(Network network) { 4789 enforceAccessPermission(); 4790 4791 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 4792 if (nai != null && nai.networkCapabilities 4793 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 4794 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 4795 } 4796 4797 final NetworkPolicyManager netPolicyManager = 4798 mContext.getSystemService(NetworkPolicyManager.class); 4799 4800 final long token = Binder.clearCallingIdentity(); 4801 final int networkPreference; 4802 try { 4803 networkPreference = netPolicyManager.getMultipathPreference(network); 4804 } finally { 4805 Binder.restoreCallingIdentity(token); 4806 } 4807 if (networkPreference != 0) { 4808 return networkPreference; 4809 } 4810 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 4811 } 4812 4813 @Override getDefaultRequest()4814 public NetworkRequest getDefaultRequest() { 4815 return mDefaultRequest.mRequests.get(0); 4816 } 4817 4818 private class InternalHandler extends Handler { InternalHandler(Looper looper)4819 public InternalHandler(Looper looper) { 4820 super(looper); 4821 } 4822 4823 @Override handleMessage(Message msg)4824 public void handleMessage(Message msg) { 4825 switch (msg.what) { 4826 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 4827 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 4828 handleReleaseNetworkTransitionWakelock(msg.what); 4829 break; 4830 } 4831 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 4832 mProxyTracker.loadDeprecatedGlobalHttpProxy(); 4833 break; 4834 } 4835 case EVENT_PROXY_HAS_CHANGED: { 4836 final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj; 4837 handleApplyDefaultProxy(arg.second); 4838 break; 4839 } 4840 case EVENT_REGISTER_NETWORK_PROVIDER: { 4841 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); 4842 break; 4843 } 4844 case EVENT_UNREGISTER_NETWORK_PROVIDER: { 4845 handleUnregisterNetworkProvider((Messenger) msg.obj); 4846 break; 4847 } 4848 case EVENT_REGISTER_NETWORK_OFFER: { 4849 handleRegisterNetworkOffer((NetworkOffer) msg.obj); 4850 break; 4851 } 4852 case EVENT_UNREGISTER_NETWORK_OFFER: { 4853 final NetworkOfferInfo offer = 4854 findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj); 4855 if (null != offer) { 4856 handleUnregisterNetworkOffer(offer); 4857 } 4858 break; 4859 } 4860 case EVENT_REGISTER_NETWORK_AGENT: { 4861 final Pair<NetworkAgentInfo, INetworkMonitor> arg = 4862 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; 4863 handleRegisterNetworkAgent(arg.first, arg.second); 4864 break; 4865 } 4866 case EVENT_REGISTER_NETWORK_REQUEST: 4867 case EVENT_REGISTER_NETWORK_LISTENER: { 4868 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 4869 break; 4870 } 4871 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 4872 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 4873 handleRegisterNetworkRequestWithIntent(msg); 4874 break; 4875 } 4876 case EVENT_TIMEOUT_NETWORK_REQUEST: { 4877 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 4878 handleTimedOutNetworkRequest(nri); 4879 break; 4880 } 4881 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 4882 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 4883 break; 4884 } 4885 case EVENT_RELEASE_NETWORK_REQUEST: { 4886 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1, 4887 /* callOnUnavailable */ false); 4888 break; 4889 } 4890 case EVENT_SET_ACCEPT_UNVALIDATED: { 4891 Network network = (Network) msg.obj; 4892 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 4893 break; 4894 } 4895 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: { 4896 Network network = (Network) msg.obj; 4897 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1), 4898 toBool(msg.arg2)); 4899 break; 4900 } 4901 case EVENT_SET_AVOID_UNVALIDATED: { 4902 handleSetAvoidUnvalidated((Network) msg.obj); 4903 break; 4904 } 4905 case EVENT_PROMPT_UNVALIDATED: { 4906 handlePromptUnvalidated((Network) msg.obj); 4907 break; 4908 } 4909 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { 4910 handleConfigureAlwaysOnNetworks(); 4911 break; 4912 } 4913 // Sent by KeepaliveTracker to process an app request on the state machine thread. 4914 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: { 4915 mKeepaliveTracker.handleStartKeepalive(msg); 4916 break; 4917 } 4918 // Sent by KeepaliveTracker to process an app request on the state machine thread. 4919 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: { 4920 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 4921 int slot = msg.arg1; 4922 int reason = msg.arg2; 4923 mKeepaliveTracker.handleStopKeepalive(nai, slot, reason); 4924 break; 4925 } 4926 case EVENT_REVALIDATE_NETWORK: { 4927 handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2)); 4928 break; 4929 } 4930 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 4931 handlePrivateDnsSettingsChanged(); 4932 break; 4933 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 4934 handlePrivateDnsValidationUpdate( 4935 (PrivateDnsValidationUpdate) msg.obj); 4936 break; 4937 case EVENT_UID_BLOCKED_REASON_CHANGED: 4938 handleUidBlockedReasonChanged(msg.arg1, msg.arg2); 4939 break; 4940 case EVENT_SET_REQUIRE_VPN_FOR_UIDS: 4941 handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); 4942 break; 4943 case EVENT_SET_OEM_NETWORK_PREFERENCE: { 4944 final Pair<OemNetworkPreferences, IOnCompleteListener> arg = 4945 (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj; 4946 handleSetOemNetworkPreference(arg.first, arg.second); 4947 break; 4948 } 4949 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: { 4950 final Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener> arg = 4951 (Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener>) 4952 msg.obj; 4953 handleSetProfileNetworkPreference(arg.first, arg.second); 4954 break; 4955 } 4956 case EVENT_REPORT_NETWORK_ACTIVITY: 4957 mNetworkActivityTracker.handleReportNetworkActivity(); 4958 break; 4959 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED: 4960 handleMobileDataPreferredUidsChanged(); 4961 break; 4962 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL: 4963 final long timeMs = ((Long) msg.obj).longValue(); 4964 mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs); 4965 break; 4966 } 4967 } 4968 } 4969 4970 @Override 4971 @Deprecated getLastTetherError(String iface)4972 public int getLastTetherError(String iface) { 4973 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 4974 Context.TETHERING_SERVICE); 4975 return tm.getLastTetherError(iface); 4976 } 4977 4978 @Override 4979 @Deprecated getTetherableIfaces()4980 public String[] getTetherableIfaces() { 4981 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 4982 Context.TETHERING_SERVICE); 4983 return tm.getTetherableIfaces(); 4984 } 4985 4986 @Override 4987 @Deprecated getTetheredIfaces()4988 public String[] getTetheredIfaces() { 4989 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 4990 Context.TETHERING_SERVICE); 4991 return tm.getTetheredIfaces(); 4992 } 4993 4994 4995 @Override 4996 @Deprecated getTetheringErroredIfaces()4997 public String[] getTetheringErroredIfaces() { 4998 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 4999 Context.TETHERING_SERVICE); 5000 5001 return tm.getTetheringErroredIfaces(); 5002 } 5003 5004 @Override 5005 @Deprecated getTetherableUsbRegexs()5006 public String[] getTetherableUsbRegexs() { 5007 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5008 Context.TETHERING_SERVICE); 5009 5010 return tm.getTetherableUsbRegexs(); 5011 } 5012 5013 @Override 5014 @Deprecated getTetherableWifiRegexs()5015 public String[] getTetherableWifiRegexs() { 5016 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5017 Context.TETHERING_SERVICE); 5018 return tm.getTetherableWifiRegexs(); 5019 } 5020 5021 // Called when we lose the default network and have no replacement yet. 5022 // This will automatically be cleared after X seconds or a new default network 5023 // becomes CONNECTED, whichever happens first. The timer is started by the 5024 // first caller and not restarted by subsequent callers. ensureNetworkTransitionWakelock(String forWhom)5025 private void ensureNetworkTransitionWakelock(String forWhom) { 5026 synchronized (this) { 5027 if (mNetTransitionWakeLock.isHeld()) { 5028 return; 5029 } 5030 mNetTransitionWakeLock.acquire(); 5031 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 5032 mTotalWakelockAcquisitions++; 5033 } 5034 mWakelockLogs.log("ACQUIRE for " + forWhom); 5035 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 5036 final int lockTimeout = mResources.get().getInteger( 5037 R.integer.config_networkTransitionTimeout); 5038 mHandler.sendMessageDelayed(msg, lockTimeout); 5039 } 5040 5041 // Called when we gain a new default network to release the network transition wakelock in a 5042 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 5043 // message is cancelled. scheduleReleaseNetworkTransitionWakelock()5044 private void scheduleReleaseNetworkTransitionWakelock() { 5045 synchronized (this) { 5046 if (!mNetTransitionWakeLock.isHeld()) { 5047 return; // expiry message released the lock first. 5048 } 5049 } 5050 // Cancel self timeout on wakelock hold. 5051 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 5052 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 5053 mHandler.sendMessageDelayed(msg, 1000); 5054 } 5055 5056 // Called when either message of ensureNetworkTransitionWakelock or 5057 // scheduleReleaseNetworkTransitionWakelock is processed. handleReleaseNetworkTransitionWakelock(int eventId)5058 private void handleReleaseNetworkTransitionWakelock(int eventId) { 5059 String event = eventName(eventId); 5060 synchronized (this) { 5061 if (!mNetTransitionWakeLock.isHeld()) { 5062 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 5063 Log.w(TAG, "expected Net Transition WakeLock to be held"); 5064 return; 5065 } 5066 mNetTransitionWakeLock.release(); 5067 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 5068 mTotalWakelockDurationMs += lockDuration; 5069 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 5070 mTotalWakelockReleases++; 5071 } 5072 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 5073 } 5074 5075 // 100 percent is full good, 0 is full bad. 5076 @Override reportInetCondition(int networkType, int percentage)5077 public void reportInetCondition(int networkType, int percentage) { 5078 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 5079 if (nai == null) return; 5080 reportNetworkConnectivity(nai.network, percentage > 50); 5081 } 5082 5083 @Override reportNetworkConnectivity(Network network, boolean hasConnectivity)5084 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 5085 enforceAccessPermission(); 5086 enforceInternetPermission(); 5087 final int uid = mDeps.getCallingUid(); 5088 final int connectivityInfo = encodeBool(hasConnectivity); 5089 5090 // Handle ConnectivityDiagnostics event before attempting to revalidate the network. This 5091 // forces an ordering of ConnectivityDiagnostics events in the case where hasConnectivity 5092 // does not match the known connectivity of the network - this causes NetworkMonitor to 5093 // revalidate the network and generate a ConnectivityDiagnostics ConnectivityReport event. 5094 final NetworkAgentInfo nai; 5095 if (network == null) { 5096 nai = getDefaultNetwork(); 5097 } else { 5098 nai = getNetworkAgentInfoForNetwork(network); 5099 } 5100 if (nai != null) { 5101 mConnectivityDiagnosticsHandler.sendMessage( 5102 mConnectivityDiagnosticsHandler.obtainMessage( 5103 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 5104 connectivityInfo, 0, nai)); 5105 } 5106 5107 mHandler.sendMessage( 5108 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network)); 5109 } 5110 handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)5111 private void handleReportNetworkConnectivity( 5112 Network network, int uid, boolean hasConnectivity) { 5113 final NetworkAgentInfo nai; 5114 if (network == null) { 5115 nai = getDefaultNetwork(); 5116 } else { 5117 nai = getNetworkAgentInfoForNetwork(network); 5118 } 5119 if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING || 5120 nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 5121 return; 5122 } 5123 // Revalidate if the app report does not match our current validated state. 5124 if (hasConnectivity == nai.lastValidated) { 5125 return; 5126 } 5127 if (DBG) { 5128 int netid = nai.network.getNetId(); 5129 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 5130 } 5131 // Validating a network that has not yet connected could result in a call to 5132 // rematchNetworkAndRequests() which is not meant to work on such networks. 5133 if (!nai.everConnected) { 5134 return; 5135 } 5136 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 5137 if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) { 5138 return; 5139 } 5140 nai.networkMonitor().forceReevaluation(uid); 5141 } 5142 5143 // TODO: call into netd. queryUserAccess(int uid, Network network)5144 private boolean queryUserAccess(int uid, Network network) { 5145 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5146 if (nai == null) return false; 5147 5148 // Any UID can use its default network. 5149 if (nai == getDefaultNetworkForUid(uid)) return true; 5150 5151 // Privileged apps can use any network. 5152 if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) { 5153 return true; 5154 } 5155 5156 // An unprivileged UID can use a VPN iff the VPN applies to it. 5157 if (nai.isVPN()) { 5158 return nai.networkCapabilities.appliesToUid(uid); 5159 } 5160 5161 // An unprivileged UID can bypass the VPN that applies to it only if it can protect its 5162 // sockets, i.e., if it is the owner. 5163 final NetworkAgentInfo vpn = getVpnForUid(uid); 5164 if (vpn != null && !vpn.networkAgentConfig.allowBypass 5165 && uid != vpn.networkCapabilities.getOwnerUid()) { 5166 return false; 5167 } 5168 5169 // The UID's permission must be at least sufficient for the network. Since the restricted 5170 // permission was already checked above, that just leaves background networks. 5171 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { 5172 return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid); 5173 } 5174 5175 // Unrestricted network. Anyone gets to use it. 5176 return true; 5177 } 5178 5179 /** 5180 * Returns information about the proxy a certain network is using. If given a null network, it 5181 * it will return the proxy for the bound network for the caller app or the default proxy if 5182 * none. 5183 * 5184 * @param network the network we want to get the proxy information for. 5185 * @return Proxy information if a network has a proxy configured, or otherwise null. 5186 */ 5187 @Override getProxyForNetwork(Network network)5188 public ProxyInfo getProxyForNetwork(Network network) { 5189 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy(); 5190 if (globalProxy != null) return globalProxy; 5191 if (network == null) { 5192 // Get the network associated with the calling UID. 5193 final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(), 5194 true); 5195 if (activeNetwork == null) { 5196 return null; 5197 } 5198 return getLinkPropertiesProxyInfo(activeNetwork); 5199 } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) { 5200 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 5201 // caller may not have. 5202 return getLinkPropertiesProxyInfo(network); 5203 } 5204 // No proxy info available if the calling UID does not have network access. 5205 return null; 5206 } 5207 5208 getLinkPropertiesProxyInfo(Network network)5209 private ProxyInfo getLinkPropertiesProxyInfo(Network network) { 5210 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5211 if (nai == null) return null; 5212 synchronized (nai) { 5213 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy(); 5214 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy); 5215 } 5216 } 5217 5218 @Override setGlobalProxy(@ullable final ProxyInfo proxyProperties)5219 public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) { 5220 PermissionUtils.enforceNetworkStackPermission(mContext); 5221 mProxyTracker.setGlobalProxy(proxyProperties); 5222 } 5223 5224 @Override 5225 @Nullable getGlobalProxy()5226 public ProxyInfo getGlobalProxy() { 5227 return mProxyTracker.getGlobalProxy(); 5228 } 5229 handleApplyDefaultProxy(ProxyInfo proxy)5230 private void handleApplyDefaultProxy(ProxyInfo proxy) { 5231 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 5232 && Uri.EMPTY.equals(proxy.getPacFileUrl())) { 5233 proxy = null; 5234 } 5235 mProxyTracker.setDefaultProxy(proxy); 5236 } 5237 5238 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called 5239 // when any network changes proxy. 5240 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a 5241 // multi-network world where an app might be bound to a non-default network. updateProxy(LinkProperties newLp, LinkProperties oldLp)5242 private void updateProxy(LinkProperties newLp, LinkProperties oldLp) { 5243 ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy(); 5244 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 5245 5246 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 5247 mProxyTracker.sendProxyBroadcast(); 5248 } 5249 } 5250 5251 private static class SettingsObserver extends ContentObserver { 5252 final private HashMap<Uri, Integer> mUriEventMap; 5253 final private Context mContext; 5254 final private Handler mHandler; 5255 SettingsObserver(Context context, Handler handler)5256 SettingsObserver(Context context, Handler handler) { 5257 super(null); 5258 mUriEventMap = new HashMap<>(); 5259 mContext = context; 5260 mHandler = handler; 5261 } 5262 observe(Uri uri, int what)5263 void observe(Uri uri, int what) { 5264 mUriEventMap.put(uri, what); 5265 final ContentResolver resolver = mContext.getContentResolver(); 5266 resolver.registerContentObserver(uri, false, this); 5267 } 5268 5269 @Override onChange(boolean selfChange)5270 public void onChange(boolean selfChange) { 5271 Log.wtf(TAG, "Should never be reached."); 5272 } 5273 5274 @Override onChange(boolean selfChange, Uri uri)5275 public void onChange(boolean selfChange, Uri uri) { 5276 final Integer what = mUriEventMap.get(uri); 5277 if (what != null) { 5278 mHandler.obtainMessage(what).sendToTarget(); 5279 } else { 5280 loge("No matching event to send for URI=" + uri); 5281 } 5282 } 5283 } 5284 log(String s)5285 private static void log(String s) { 5286 Log.d(TAG, s); 5287 } 5288 logw(String s)5289 private static void logw(String s) { 5290 Log.w(TAG, s); 5291 } 5292 logwtf(String s)5293 private static void logwtf(String s) { 5294 Log.wtf(TAG, s); 5295 } 5296 logwtf(String s, Throwable t)5297 private static void logwtf(String s, Throwable t) { 5298 Log.wtf(TAG, s, t); 5299 } 5300 loge(String s)5301 private static void loge(String s) { 5302 Log.e(TAG, s); 5303 } 5304 loge(String s, Throwable t)5305 private static void loge(String s, Throwable t) { 5306 Log.e(TAG, s, t); 5307 } 5308 5309 /** 5310 * Return the information of all ongoing VPNs. 5311 * 5312 * <p>This method is used to update NetworkStatsService. 5313 * 5314 * <p>Must be called on the handler thread. 5315 */ getAllVpnInfo()5316 private UnderlyingNetworkInfo[] getAllVpnInfo() { 5317 ensureRunningOnConnectivityServiceThread(); 5318 if (mLockdownEnabled) { 5319 return new UnderlyingNetworkInfo[0]; 5320 } 5321 List<UnderlyingNetworkInfo> infoList = new ArrayList<>(); 5322 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 5323 UnderlyingNetworkInfo info = createVpnInfo(nai); 5324 if (info != null) { 5325 infoList.add(info); 5326 } 5327 } 5328 return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]); 5329 } 5330 5331 /** 5332 * @return VPN information for accounting, or null if we can't retrieve all required 5333 * information, e.g underlying ifaces. 5334 */ createVpnInfo(NetworkAgentInfo nai)5335 private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) { 5336 Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; 5337 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 5338 // the underlyingNetworks list. 5339 // TODO: stop using propagateUnderlyingCapabilities here, for example, by always 5340 // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array. 5341 if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) { 5342 final NetworkAgentInfo defaultNai = getDefaultNetworkForUid( 5343 nai.networkCapabilities.getOwnerUid()); 5344 if (defaultNai != null) { 5345 underlyingNetworks = new Network[] { defaultNai.network }; 5346 } 5347 } 5348 5349 if (CollectionUtils.isEmpty(underlyingNetworks)) return null; 5350 5351 List<String> interfaces = new ArrayList<>(); 5352 for (Network network : underlyingNetworks) { 5353 NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network); 5354 if (underlyingNai == null) continue; 5355 LinkProperties lp = underlyingNai.linkProperties; 5356 for (String iface : lp.getAllInterfaceNames()) { 5357 if (!TextUtils.isEmpty(iface)) { 5358 interfaces.add(iface); 5359 } 5360 } 5361 } 5362 5363 if (interfaces.isEmpty()) return null; 5364 5365 // Must be non-null or NetworkStatsService will crash. 5366 // Cannot happen in production code because Vpn only registers the NetworkAgent after the 5367 // tun or ipsec interface is created. 5368 // TODO: Remove this check. 5369 if (nai.linkProperties.getInterfaceName() == null) return null; 5370 5371 return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(), 5372 nai.linkProperties.getInterfaceName(), interfaces); 5373 } 5374 5375 // TODO This needs to be the default network that applies to the NAI. underlyingNetworksOrDefault(final int ownerUid, Network[] underlyingNetworks)5376 private Network[] underlyingNetworksOrDefault(final int ownerUid, 5377 Network[] underlyingNetworks) { 5378 final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid)); 5379 if (underlyingNetworks == null && defaultNetwork != null) { 5380 // null underlying networks means to track the default. 5381 underlyingNetworks = new Network[] { defaultNetwork }; 5382 } 5383 return underlyingNetworks; 5384 } 5385 5386 // Returns true iff |network| is an underlying network of |nai|. hasUnderlyingNetwork(NetworkAgentInfo nai, Network network)5387 private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) { 5388 // TODO: support more than one level of underlying networks, either via a fixed-depth search 5389 // (e.g., 2 levels of underlying networks), or via loop detection, or.... 5390 if (!nai.propagateUnderlyingCapabilities()) return false; 5391 final Network[] underlying = underlyingNetworksOrDefault( 5392 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks); 5393 return CollectionUtils.contains(underlying, network); 5394 } 5395 5396 /** 5397 * Recompute the capabilities for any networks that had a specific network as underlying. 5398 * 5399 * When underlying networks change, such networks may have to update capabilities to reflect 5400 * things like the metered bit, their transports, and so on. The capabilities are calculated 5401 * immediately. This method runs on the ConnectivityService thread. 5402 */ propagateUnderlyingNetworkCapabilities(Network updatedNetwork)5403 private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) { 5404 ensureRunningOnConnectivityServiceThread(); 5405 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 5406 if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) { 5407 updateCapabilitiesForNetwork(nai); 5408 } 5409 } 5410 } 5411 isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges)5412 private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) { 5413 // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies 5414 // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when 5415 // a VPN is not up. 5416 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 5417 if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false; 5418 for (UidRange range : blockedUidRanges) { 5419 if (range.contains(uid)) return true; 5420 } 5421 return false; 5422 } 5423 5424 @Override setRequireVpnForUids(boolean requireVpn, UidRange[] ranges)5425 public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 5426 enforceNetworkStackOrSettingsPermission(); 5427 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS, 5428 encodeBool(requireVpn), 0 /* arg2 */, ranges)); 5429 } 5430 handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges)5431 private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 5432 if (DBG) { 5433 Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: " 5434 + Arrays.toString(ranges)); 5435 } 5436 // Cannot use a Set since the list of UID ranges might contain duplicates. 5437 final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges); 5438 for (int i = 0; i < ranges.length; i++) { 5439 if (requireVpn) { 5440 newVpnBlockedUidRanges.add(ranges[i]); 5441 } else { 5442 newVpnBlockedUidRanges.remove(ranges[i]); 5443 } 5444 } 5445 5446 try { 5447 mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges)); 5448 } catch (RemoteException | ServiceSpecificException e) { 5449 Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", " 5450 + Arrays.toString(ranges) + "): netd command failed: " + e); 5451 } 5452 5453 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 5454 final boolean curMetered = nai.networkCapabilities.isMetered(); 5455 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, 5456 mVpnBlockedUidRanges, newVpnBlockedUidRanges); 5457 } 5458 5459 mVpnBlockedUidRanges = newVpnBlockedUidRanges; 5460 } 5461 5462 @Override setLegacyLockdownVpnEnabled(boolean enabled)5463 public void setLegacyLockdownVpnEnabled(boolean enabled) { 5464 enforceNetworkStackOrSettingsPermission(); 5465 mHandler.post(() -> mLockdownEnabled = enabled); 5466 } 5467 isLegacyLockdownNai(NetworkAgentInfo nai)5468 private boolean isLegacyLockdownNai(NetworkAgentInfo nai) { 5469 return mLockdownEnabled 5470 && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY 5471 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID); 5472 } 5473 getLegacyLockdownNai()5474 private NetworkAgentInfo getLegacyLockdownNai() { 5475 if (!mLockdownEnabled) { 5476 return null; 5477 } 5478 // The legacy lockdown VPN always only applies to userId 0. 5479 final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID); 5480 if (nai == null || !isLegacyLockdownNai(nai)) return null; 5481 5482 // The legacy lockdown VPN must always have exactly one underlying network. 5483 // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in 5484 // a local variable. There is no need to make a copy because its contents cannot change. 5485 final Network[] underlying = nai.declaredUnderlyingNetworks; 5486 if (underlying == null || underlying.length != 1) { 5487 return null; 5488 } 5489 5490 // The legacy lockdown VPN always uses the default network. 5491 // If the VPN's underlying network is no longer the current default network, it means that 5492 // the default network has just switched, and the VPN is about to disconnect. 5493 // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten 5494 // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED. 5495 final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 5496 if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) { 5497 return null; 5498 } 5499 5500 return nai; 5501 }; 5502 5503 // TODO: move all callers to filterForLegacyLockdown and delete this method. 5504 // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of 5505 // just a DetailedState object. getLegacyLockdownState(DetailedState origState)5506 private DetailedState getLegacyLockdownState(DetailedState origState) { 5507 if (origState != DetailedState.CONNECTED) { 5508 return origState; 5509 } 5510 return (mLockdownEnabled && getLegacyLockdownNai() == null) 5511 ? DetailedState.CONNECTING 5512 : DetailedState.CONNECTED; 5513 } 5514 filterForLegacyLockdown(NetworkInfo ni)5515 private void filterForLegacyLockdown(NetworkInfo ni) { 5516 if (!mLockdownEnabled || !ni.isConnected()) return; 5517 // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the 5518 // state of its VPN. This is to ensure that when an underlying network connects, apps will 5519 // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN 5520 // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying 5521 // network, this time with a state of CONNECTED. 5522 // 5523 // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access 5524 // to the internal state of the Vpn object, always replace the state with CONNECTING. This 5525 // is not too far off the truth, since an always-on VPN, when not connected, is always 5526 // trying to reconnect. 5527 if (getLegacyLockdownNai() == null) { 5528 ni.setDetailedState(DetailedState.CONNECTING, "", null); 5529 } 5530 } 5531 5532 @Override setProvisioningNotificationVisible(boolean visible, int networkType, String action)5533 public void setProvisioningNotificationVisible(boolean visible, int networkType, 5534 String action) { 5535 enforceSettingsPermission(); 5536 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 5537 return; 5538 } 5539 final long ident = Binder.clearCallingIdentity(); 5540 try { 5541 // Concatenate the range of types onto the range of NetIDs. 5542 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 5543 mNotifier.setProvNotificationVisible(visible, id, action); 5544 } finally { 5545 Binder.restoreCallingIdentity(ident); 5546 } 5547 } 5548 5549 @Override setAirplaneMode(boolean enable)5550 public void setAirplaneMode(boolean enable) { 5551 enforceAirplaneModePermission(); 5552 final long ident = Binder.clearCallingIdentity(); 5553 try { 5554 final ContentResolver cr = mContext.getContentResolver(); 5555 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 5556 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 5557 intent.putExtra("state", enable); 5558 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 5559 } finally { 5560 Binder.restoreCallingIdentity(ident); 5561 } 5562 } 5563 onUserAdded(@onNull final UserHandle user)5564 private void onUserAdded(@NonNull final UserHandle user) { 5565 mPermissionMonitor.onUserAdded(user); 5566 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 5567 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 5568 } 5569 } 5570 onUserRemoved(@onNull final UserHandle user)5571 private void onUserRemoved(@NonNull final UserHandle user) { 5572 mPermissionMonitor.onUserRemoved(user); 5573 // If there was a network preference for this user, remove it. 5574 handleSetProfileNetworkPreference(new ProfileNetworkPreferences.Preference(user, null), 5575 null /* listener */); 5576 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 5577 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 5578 } 5579 } 5580 onPackageChanged(@onNull final String packageName)5581 private void onPackageChanged(@NonNull final String packageName) { 5582 // This is necessary in case a package is added or removed, but also when it's replaced to 5583 // run as a new UID by its manifest rules. Also, if a separate package shares the same UID 5584 // as one in the preferences, then it should follow the same routing as that other package, 5585 // which means updating the rules is never to be needed in this case (whether it joins or 5586 // leaves a UID with a preference). 5587 if (isMappedInOemNetworkPreference(packageName)) { 5588 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 5589 } 5590 } 5591 5592 private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 5593 @Override 5594 public void onReceive(Context context, Intent intent) { 5595 ensureRunningOnConnectivityServiceThread(); 5596 final String action = intent.getAction(); 5597 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 5598 5599 // User should be filled for below intents, check the existence. 5600 if (user == null) { 5601 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER"); 5602 return; 5603 } 5604 5605 if (Intent.ACTION_USER_ADDED.equals(action)) { 5606 onUserAdded(user); 5607 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 5608 onUserRemoved(user); 5609 } else { 5610 Log.wtf(TAG, "received unexpected intent: " + action); 5611 } 5612 } 5613 }; 5614 5615 private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { 5616 @Override 5617 public void onReceive(Context context, Intent intent) { 5618 ensureRunningOnConnectivityServiceThread(); 5619 switch (intent.getAction()) { 5620 case Intent.ACTION_PACKAGE_ADDED: 5621 case Intent.ACTION_PACKAGE_REMOVED: 5622 case Intent.ACTION_PACKAGE_REPLACED: 5623 onPackageChanged(intent.getData().getSchemeSpecificPart()); 5624 break; 5625 default: 5626 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 5627 } 5628 } 5629 }; 5630 5631 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); 5632 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); 5633 5634 private static class NetworkProviderInfo { 5635 public final String name; 5636 public final Messenger messenger; 5637 private final IBinder.DeathRecipient mDeathRecipient; 5638 public final int providerId; 5639 NetworkProviderInfo(String name, Messenger messenger, int providerId, @NonNull IBinder.DeathRecipient deathRecipient)5640 NetworkProviderInfo(String name, Messenger messenger, int providerId, 5641 @NonNull IBinder.DeathRecipient deathRecipient) { 5642 this.name = name; 5643 this.messenger = messenger; 5644 this.providerId = providerId; 5645 mDeathRecipient = deathRecipient; 5646 5647 if (mDeathRecipient == null) { 5648 throw new AssertionError("Must pass a deathRecipient"); 5649 } 5650 } 5651 connect(Context context, Handler handler)5652 void connect(Context context, Handler handler) { 5653 try { 5654 messenger.getBinder().linkToDeath(mDeathRecipient, 0); 5655 } catch (RemoteException e) { 5656 mDeathRecipient.binderDied(); 5657 } 5658 } 5659 } 5660 ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests)5661 private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) { 5662 for (int i = 0; i < requests.size(); i++) { 5663 ensureNetworkRequestHasType(requests.get(i)); 5664 } 5665 } 5666 ensureNetworkRequestHasType(NetworkRequest request)5667 private void ensureNetworkRequestHasType(NetworkRequest request) { 5668 if (request.type == NetworkRequest.Type.NONE) { 5669 throw new IllegalArgumentException( 5670 "All NetworkRequests in ConnectivityService must have a type"); 5671 } 5672 } 5673 5674 /** 5675 * Tracks info about the requester. 5676 * Also used to notice when the calling process dies so as to self-expire 5677 */ 5678 @VisibleForTesting 5679 protected class NetworkRequestInfo implements IBinder.DeathRecipient { 5680 // The requests to be satisfied in priority order. Non-multilayer requests will only have a 5681 // single NetworkRequest in mRequests. 5682 final List<NetworkRequest> mRequests; 5683 5684 // mSatisfier and mActiveRequest rely on one another therefore set them together. setSatisfier( @ullable final NetworkAgentInfo satisfier, @Nullable final NetworkRequest activeRequest)5685 void setSatisfier( 5686 @Nullable final NetworkAgentInfo satisfier, 5687 @Nullable final NetworkRequest activeRequest) { 5688 mSatisfier = satisfier; 5689 mActiveRequest = activeRequest; 5690 } 5691 5692 // The network currently satisfying this NRI. Only one request in an NRI can have a 5693 // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier. 5694 @Nullable 5695 private NetworkAgentInfo mSatisfier; getSatisfier()5696 NetworkAgentInfo getSatisfier() { 5697 return mSatisfier; 5698 } 5699 5700 // The request in mRequests assigned to a network agent. This is null if none of the 5701 // requests in mRequests can be satisfied. This member has the constraint of only being 5702 // accessible on the handler thread. 5703 @Nullable 5704 private NetworkRequest mActiveRequest; getActiveRequest()5705 NetworkRequest getActiveRequest() { 5706 return mActiveRequest; 5707 } 5708 5709 final PendingIntent mPendingIntent; 5710 boolean mPendingIntentSent; 5711 @Nullable 5712 final Messenger mMessenger; 5713 5714 // Information about the caller that caused this object to be created. 5715 @Nullable 5716 private final IBinder mBinder; 5717 final int mPid; 5718 final int mUid; 5719 final @NetworkCallback.Flag int mCallbackFlags; 5720 @Nullable 5721 final String mCallingAttributionTag; 5722 5723 // Counter keeping track of this NRI. 5724 final PerUidCounter mPerUidCounter; 5725 5726 // Effective UID of this request. This is different from mUid when a privileged process 5727 // files a request on behalf of another UID. This UID is used to determine blocked status, 5728 // UID matching, and so on. mUid above is used for permission checks and to enforce the 5729 // maximum limit of registered callbacks per UID. 5730 final int mAsUid; 5731 5732 // Default network priority of this request. 5733 final int mPreferencePriority; 5734 5735 // In order to preserve the mapping of NetworkRequest-to-callback when apps register 5736 // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be 5737 // maintained for keying off of. This is only a concern when the original nri 5738 // mNetworkRequests changes which happens currently for apps that register callbacks to 5739 // track the default network. In those cases, the nri is updated to have mNetworkRequests 5740 // that match the per-app default nri that currently tracks the calling app's uid so that 5741 // callbacks are fired at the appropriate time. When the callbacks fire, 5742 // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When 5743 // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue. 5744 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 5745 @NonNull 5746 private final NetworkRequest mNetworkRequestForCallback; getNetworkRequestForCallback()5747 NetworkRequest getNetworkRequestForCallback() { 5748 return mNetworkRequestForCallback; 5749 } 5750 5751 /** 5752 * Get the list of UIDs this nri applies to. 5753 */ 5754 @NonNull getUids()5755 Set<UidRange> getUids() { 5756 // networkCapabilities.getUids() returns a defensive copy. 5757 // multilayer requests will all have the same uids so return the first one. 5758 final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges(); 5759 return (null == uids) ? new ArraySet<>() : uids; 5760 } 5761 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final PendingIntent pi, @Nullable String callingAttributionTag)5762 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, 5763 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) { 5764 this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag, 5765 PREFERENCE_PRIORITY_INVALID); 5766 } 5767 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, @Nullable String callingAttributionTag, final int preferencePriority)5768 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 5769 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, 5770 @Nullable String callingAttributionTag, final int preferencePriority) { 5771 ensureAllNetworkRequestsHaveType(r); 5772 mRequests = initializeRequests(r); 5773 mNetworkRequestForCallback = requestForCallback; 5774 mPendingIntent = pi; 5775 mMessenger = null; 5776 mBinder = null; 5777 mPid = getCallingPid(); 5778 mUid = mDeps.getCallingUid(); 5779 mAsUid = asUid; 5780 mPerUidCounter = getRequestCounter(this); 5781 mPerUidCounter.incrementCountOrThrow(mUid); 5782 /** 5783 * Location sensitive data not included in pending intent. Only included in 5784 * {@link NetworkCallback}. 5785 */ 5786 mCallbackFlags = NetworkCallback.FLAG_NONE; 5787 mCallingAttributionTag = callingAttributionTag; 5788 mPreferencePriority = preferencePriority; 5789 } 5790 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)5791 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, 5792 @Nullable final IBinder binder, 5793 @NetworkCallback.Flag int callbackFlags, 5794 @Nullable String callingAttributionTag) { 5795 this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags, 5796 callingAttributionTag); 5797 } 5798 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)5799 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 5800 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, 5801 @Nullable final IBinder binder, 5802 @NetworkCallback.Flag int callbackFlags, 5803 @Nullable String callingAttributionTag) { 5804 super(); 5805 ensureAllNetworkRequestsHaveType(r); 5806 mRequests = initializeRequests(r); 5807 mNetworkRequestForCallback = requestForCallback; 5808 mMessenger = m; 5809 mBinder = binder; 5810 mPid = getCallingPid(); 5811 mUid = mDeps.getCallingUid(); 5812 mAsUid = asUid; 5813 mPendingIntent = null; 5814 mPerUidCounter = getRequestCounter(this); 5815 mPerUidCounter.incrementCountOrThrow(mUid); 5816 mCallbackFlags = callbackFlags; 5817 mCallingAttributionTag = callingAttributionTag; 5818 mPreferencePriority = PREFERENCE_PRIORITY_INVALID; 5819 linkDeathRecipient(); 5820 } 5821 NetworkRequestInfo(@onNull final NetworkRequestInfo nri, @NonNull final List<NetworkRequest> r)5822 NetworkRequestInfo(@NonNull final NetworkRequestInfo nri, 5823 @NonNull final List<NetworkRequest> r) { 5824 super(); 5825 ensureAllNetworkRequestsHaveType(r); 5826 mRequests = initializeRequests(r); 5827 mNetworkRequestForCallback = nri.getNetworkRequestForCallback(); 5828 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5829 if (null != satisfier) { 5830 // If the old NRI was satisfied by an NAI, then it may have had an active request. 5831 // The active request is necessary to figure out what callbacks to send, in 5832 // particular then a network updates its capabilities. 5833 // As this code creates a new NRI with a new set of requests, figure out which of 5834 // the list of requests should be the active request. It is always the first 5835 // request of the list that can be satisfied by the satisfier since the order of 5836 // requests is a priority order. 5837 // Note even in the presence of a satisfier there may not be an active request, 5838 // when the satisfier is the no-service network. 5839 NetworkRequest activeRequest = null; 5840 for (final NetworkRequest candidate : r) { 5841 if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) { 5842 activeRequest = candidate; 5843 break; 5844 } 5845 } 5846 setSatisfier(satisfier, activeRequest); 5847 } 5848 mMessenger = nri.mMessenger; 5849 mBinder = nri.mBinder; 5850 mPid = nri.mPid; 5851 mUid = nri.mUid; 5852 mAsUid = nri.mAsUid; 5853 mPendingIntent = nri.mPendingIntent; 5854 mPerUidCounter = nri.mPerUidCounter; 5855 mPerUidCounter.incrementCountOrThrow(mUid); 5856 mCallbackFlags = nri.mCallbackFlags; 5857 mCallingAttributionTag = nri.mCallingAttributionTag; 5858 mPreferencePriority = PREFERENCE_PRIORITY_INVALID; 5859 linkDeathRecipient(); 5860 } 5861 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r)5862 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) { 5863 this(asUid, Collections.singletonList(r), PREFERENCE_PRIORITY_INVALID); 5864 } 5865 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, final int preferencePriority)5866 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 5867 final int preferencePriority) { 5868 this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */, 5869 preferencePriority); 5870 } 5871 5872 // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer 5873 // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning 5874 // false. isBeingSatisfied()5875 boolean isBeingSatisfied() { 5876 return (null != mSatisfier && null != mActiveRequest); 5877 } 5878 isMultilayerRequest()5879 boolean isMultilayerRequest() { 5880 return mRequests.size() > 1; 5881 } 5882 initializeRequests(List<NetworkRequest> r)5883 private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) { 5884 // Creating a defensive copy to prevent the sender from modifying the list being 5885 // reflected in the return value of this method. 5886 final List<NetworkRequest> tempRequests = new ArrayList<>(r); 5887 return Collections.unmodifiableList(tempRequests); 5888 } 5889 decrementRequestCount()5890 void decrementRequestCount() { 5891 mPerUidCounter.decrementCount(mUid); 5892 } 5893 linkDeathRecipient()5894 void linkDeathRecipient() { 5895 if (null != mBinder) { 5896 try { 5897 mBinder.linkToDeath(this, 0); 5898 } catch (RemoteException e) { 5899 binderDied(); 5900 } 5901 } 5902 } 5903 unlinkDeathRecipient()5904 void unlinkDeathRecipient() { 5905 if (null != mBinder) { 5906 mBinder.unlinkToDeath(this, 0); 5907 } 5908 } 5909 hasHigherPriorityThan(@onNull final NetworkRequestInfo target)5910 boolean hasHigherPriorityThan(@NonNull final NetworkRequestInfo target) { 5911 // Compare two priorities, larger value means lower priority. 5912 return mPreferencePriority < target.mPreferencePriority; 5913 } 5914 getPriorityForNetd()5915 int getPriorityForNetd() { 5916 if (mPreferencePriority >= PREFERENCE_PRIORITY_NONE 5917 && mPreferencePriority <= PREFERENCE_PRIORITY_LOWEST) { 5918 return mPreferencePriority; 5919 } 5920 return PREFERENCE_PRIORITY_NONE; 5921 } 5922 5923 @Override binderDied()5924 public void binderDied() { 5925 log("ConnectivityService NetworkRequestInfo binderDied(" + 5926 "uid/pid:" + mUid + "/" + mPid + ", " + mBinder + ")"); 5927 // As an immutable collection, mRequests cannot change by the time the 5928 // lambda is evaluated on the handler thread so calling .get() from a binder thread 5929 // is acceptable. Use handleReleaseNetworkRequest and not directly 5930 // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case 5931 // the app already unregistered the request. 5932 mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0), 5933 mUid, false /* callOnUnavailable */)); 5934 } 5935 5936 @Override toString()5937 public String toString() { 5938 final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid; 5939 return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: " 5940 + (mActiveRequest == null ? null : mActiveRequest.requestId) 5941 + " callbackRequest: " 5942 + mNetworkRequestForCallback.requestId 5943 + " " + mRequests 5944 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent) 5945 + " callback flags: " + mCallbackFlags 5946 + " priority: " + mPreferencePriority; 5947 } 5948 } 5949 ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)5950 private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) { 5951 final String badCapability = networkCapabilities.describeFirstNonRequestableCapability(); 5952 if (badCapability != null) { 5953 throw new IllegalArgumentException("Cannot request network with " + badCapability); 5954 } 5955 } 5956 5957 // This checks that the passed capabilities either do not request a 5958 // specific SSID/SignalStrength, or the calling app has permission to do so. ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid, String callerPackageName)5959 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 5960 int callerPid, int callerUid, String callerPackageName) { 5961 if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) { 5962 throw new SecurityException("Insufficient permissions to request a specific SSID"); 5963 } 5964 5965 if (nc.hasSignalStrength() 5966 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { 5967 throw new SecurityException( 5968 "Insufficient permissions to request a specific signal strength"); 5969 } 5970 mAppOpsManager.checkPackage(callerUid, callerPackageName); 5971 5972 if (!nc.getSubscriptionIds().isEmpty()) { 5973 enforceNetworkFactoryPermission(); 5974 } 5975 } 5976 getSignalStrengthThresholds(@onNull final NetworkAgentInfo nai)5977 private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { 5978 final SortedSet<Integer> thresholds = new TreeSet<>(); 5979 synchronized (nai) { 5980 // mNetworkRequests may contain the same value multiple times in case of 5981 // multilayer requests. It won't matter in this case because the thresholds 5982 // will then be the same and be deduplicated as they enter the `thresholds` set. 5983 // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like. 5984 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 5985 for (final NetworkRequest req : nri.mRequests) { 5986 if (req.networkCapabilities.hasSignalStrength() 5987 && nai.satisfiesImmutableCapabilitiesOf(req)) { 5988 thresholds.add(req.networkCapabilities.getSignalStrength()); 5989 } 5990 } 5991 } 5992 } 5993 return CollectionUtils.toIntArray(new ArrayList<>(thresholds)); 5994 } 5995 updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)5996 private void updateSignalStrengthThresholds( 5997 NetworkAgentInfo nai, String reason, NetworkRequest request) { 5998 final int[] thresholdsArray = getSignalStrengthThresholds(nai); 5999 6000 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 6001 String detail; 6002 if (request != null && request.networkCapabilities.hasSignalStrength()) { 6003 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 6004 } else { 6005 detail = reason; 6006 } 6007 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 6008 detail, Arrays.toString(thresholdsArray), nai.toShortString())); 6009 } 6010 6011 nai.onSignalStrengthThresholdsUpdated(thresholdsArray); 6012 } 6013 ensureValidNetworkSpecifier(NetworkCapabilities nc)6014 private void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 6015 if (nc == null) { 6016 return; 6017 } 6018 NetworkSpecifier ns = nc.getNetworkSpecifier(); 6019 if (ns == null) { 6020 return; 6021 } 6022 if (ns instanceof MatchAllNetworkSpecifier) { 6023 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); 6024 } 6025 } 6026 ensureValid(NetworkCapabilities nc)6027 private void ensureValid(NetworkCapabilities nc) { 6028 ensureValidNetworkSpecifier(nc); 6029 if (nc.isPrivateDnsBroken()) { 6030 throw new IllegalArgumentException("Can't request broken private DNS"); 6031 } 6032 } 6033 isTargetSdkAtleast(int version, int callingUid, @NonNull String callingPackageName)6034 private boolean isTargetSdkAtleast(int version, int callingUid, 6035 @NonNull String callingPackageName) { 6036 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 6037 final PackageManager pm = 6038 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 6039 try { 6040 final int callingVersion = pm.getTargetSdkVersion(callingPackageName); 6041 if (callingVersion < version) return false; 6042 } catch (PackageManager.NameNotFoundException e) { } 6043 return true; 6044 } 6045 6046 @Override requestNetwork(int asUid, NetworkCapabilities networkCapabilities, int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder, int legacyType, int callbackFlags, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6047 public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities, 6048 int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder, 6049 int legacyType, int callbackFlags, @NonNull String callingPackageName, 6050 @Nullable String callingAttributionTag) { 6051 if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) { 6052 if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(), 6053 callingPackageName)) { 6054 throw new SecurityException("Insufficient permissions to specify legacy type"); 6055 } 6056 } 6057 final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities; 6058 final int callingUid = mDeps.getCallingUid(); 6059 // Privileged callers can track the default network of another UID by passing in a UID. 6060 if (asUid != Process.INVALID_UID) { 6061 enforceSettingsPermission(); 6062 } else { 6063 asUid = callingUid; 6064 } 6065 final NetworkRequest.Type reqType; 6066 try { 6067 reqType = NetworkRequest.Type.values()[reqTypeInt]; 6068 } catch (ArrayIndexOutOfBoundsException e) { 6069 throw new IllegalArgumentException("Unsupported request type " + reqTypeInt); 6070 } 6071 switch (reqType) { 6072 case TRACK_DEFAULT: 6073 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities} 6074 // is unused and will be replaced by ones appropriate for the UID (usually, the 6075 // calling app). This allows callers to keep track of the default network. 6076 networkCapabilities = copyDefaultNetworkCapabilitiesForUid( 6077 defaultNc, asUid, callingUid, callingPackageName); 6078 enforceAccessPermission(); 6079 break; 6080 case TRACK_SYSTEM_DEFAULT: 6081 enforceSettingsPermission(); 6082 networkCapabilities = new NetworkCapabilities(defaultNc); 6083 break; 6084 case BACKGROUND_REQUEST: 6085 enforceNetworkStackOrSettingsPermission(); 6086 // Fall-through since other checks are the same with normal requests. 6087 case REQUEST: 6088 networkCapabilities = new NetworkCapabilities(networkCapabilities); 6089 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 6090 callingAttributionTag); 6091 // TODO: this is incorrect. We mark the request as metered or not depending on 6092 // the state of the app when the request is filed, but we never change the 6093 // request if the app changes network state. http://b/29964605 6094 enforceMeteredApnPolicy(networkCapabilities); 6095 break; 6096 case LISTEN_FOR_BEST: 6097 enforceAccessPermission(); 6098 networkCapabilities = new NetworkCapabilities(networkCapabilities); 6099 break; 6100 default: 6101 throw new IllegalArgumentException("Unsupported request type " + reqType); 6102 } 6103 ensureRequestableCapabilities(networkCapabilities); 6104 ensureSufficientPermissionsForRequest(networkCapabilities, 6105 Binder.getCallingPid(), callingUid, callingPackageName); 6106 6107 // Enforce FOREGROUND if the caller does not have permission to use background network. 6108 if (reqType == LISTEN_FOR_BEST) { 6109 restrictBackgroundRequestForCaller(networkCapabilities); 6110 } 6111 6112 // Set the UID range for this request to the single UID of the requester, unless the 6113 // requester has the permission to specify other UIDs. 6114 // This will overwrite any allowed UIDs in the requested capabilities. Though there 6115 // are no visible methods to set the UIDs, an app could use reflection to try and get 6116 // networks for other apps so it's essential that the UIDs are overwritten. 6117 // Also set the requester UID and package name in the request. 6118 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 6119 callingUid, callingPackageName); 6120 6121 if (timeoutMs < 0) { 6122 throw new IllegalArgumentException("Bad timeout specified"); 6123 } 6124 ensureValid(networkCapabilities); 6125 6126 final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 6127 nextNetworkRequestId(), reqType); 6128 final NetworkRequestInfo nri = getNriToRegister( 6129 asUid, networkRequest, messenger, binder, callbackFlags, 6130 callingAttributionTag); 6131 if (DBG) log("requestNetwork for " + nri); 6132 6133 // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were 6134 // copied from the default request above. (This is necessary to ensure, for example, that 6135 // the callback does not leak sensitive information to unprivileged apps.) Check that the 6136 // changes don't alter request matching. 6137 if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT && 6138 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) { 6139 throw new IllegalStateException( 6140 "TRACK_SYSTEM_DEFAULT capabilities don't match default request: " 6141 + networkCapabilities + " vs. " + defaultNc); 6142 } 6143 6144 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); 6145 if (timeoutMs > 0) { 6146 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 6147 nri), timeoutMs); 6148 } 6149 return networkRequest; 6150 } 6151 6152 /** 6153 * Return the nri to be used when registering a network request. Specifically, this is used with 6154 * requests registered to track the default request. If there is currently a per-app default 6155 * tracking the app requestor, then we need to create a version of this nri that mirrors that of 6156 * the tracking per-app default so that callbacks are sent to the app requestor appropriately. 6157 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 6158 * when a privileged caller is tracking the default network for another uid. 6159 * @param nr the network request for the nri. 6160 * @param msgr the messenger for the nri. 6161 * @param binder the binder for the nri. 6162 * @param callingAttributionTag the calling attribution tag for the nri. 6163 * @return the nri to register. 6164 */ getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, @Nullable final Messenger msgr, @Nullable final IBinder binder, @NetworkCallback.Flag int callbackFlags, @Nullable String callingAttributionTag)6165 private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, 6166 @Nullable final Messenger msgr, @Nullable final IBinder binder, 6167 @NetworkCallback.Flag int callbackFlags, 6168 @Nullable String callingAttributionTag) { 6169 final List<NetworkRequest> requests; 6170 if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) { 6171 requests = copyDefaultNetworkRequestsForUid( 6172 asUid, nr.getRequestorUid(), nr.getRequestorPackageName()); 6173 } else { 6174 requests = Collections.singletonList(nr); 6175 } 6176 return new NetworkRequestInfo( 6177 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag); 6178 } 6179 enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, String callingPackageName, String callingAttributionTag)6180 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, 6181 String callingPackageName, String callingAttributionTag) { 6182 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { 6183 enforceConnectivityRestrictedNetworksPermission(); 6184 } else { 6185 enforceChangePermission(callingPackageName, callingAttributionTag); 6186 } 6187 } 6188 6189 @Override requestBandwidthUpdate(Network network)6190 public boolean requestBandwidthUpdate(Network network) { 6191 enforceAccessPermission(); 6192 NetworkAgentInfo nai = null; 6193 if (network == null) { 6194 return false; 6195 } 6196 synchronized (mNetworkForNetId) { 6197 nai = mNetworkForNetId.get(network.getNetId()); 6198 } 6199 if (nai != null) { 6200 nai.onBandwidthUpdateRequested(); 6201 synchronized (mBandwidthRequests) { 6202 final int uid = mDeps.getCallingUid(); 6203 Integer uidReqs = mBandwidthRequests.get(uid); 6204 if (uidReqs == null) { 6205 uidReqs = 0; 6206 } 6207 mBandwidthRequests.put(uid, ++uidReqs); 6208 } 6209 return true; 6210 } 6211 return false; 6212 } 6213 isSystem(int uid)6214 private boolean isSystem(int uid) { 6215 return uid < Process.FIRST_APPLICATION_UID; 6216 } 6217 enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)6218 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 6219 final int uid = mDeps.getCallingUid(); 6220 if (isSystem(uid)) { 6221 // Exemption for system uid. 6222 return; 6223 } 6224 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 6225 // Policy already enforced. 6226 return; 6227 } 6228 final long ident = Binder.clearCallingIdentity(); 6229 try { 6230 if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) { 6231 // If UID is restricted, don't allow them to bring up metered APNs. 6232 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 6233 } 6234 } finally { 6235 Binder.restoreCallingIdentity(ident); 6236 } 6237 } 6238 6239 @Override pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6240 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 6241 PendingIntent operation, @NonNull String callingPackageName, 6242 @Nullable String callingAttributionTag) { 6243 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 6244 final int callingUid = mDeps.getCallingUid(); 6245 networkCapabilities = new NetworkCapabilities(networkCapabilities); 6246 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 6247 callingAttributionTag); 6248 enforceMeteredApnPolicy(networkCapabilities); 6249 ensureRequestableCapabilities(networkCapabilities); 6250 ensureSufficientPermissionsForRequest(networkCapabilities, 6251 Binder.getCallingPid(), callingUid, callingPackageName); 6252 ensureValidNetworkSpecifier(networkCapabilities); 6253 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 6254 callingUid, callingPackageName); 6255 6256 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 6257 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 6258 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 6259 callingAttributionTag); 6260 if (DBG) log("pendingRequest for " + nri); 6261 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, 6262 nri)); 6263 return networkRequest; 6264 } 6265 releasePendingNetworkRequestWithDelay(PendingIntent operation)6266 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 6267 mHandler.sendMessageDelayed( 6268 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 6269 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 6270 } 6271 6272 @Override releasePendingNetworkRequest(PendingIntent operation)6273 public void releasePendingNetworkRequest(PendingIntent operation) { 6274 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 6275 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 6276 mDeps.getCallingUid(), 0, operation)); 6277 } 6278 6279 // In order to implement the compatibility measure for pre-M apps that call 6280 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 6281 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 6282 // This ensures it has permission to do so. hasWifiNetworkListenPermission(NetworkCapabilities nc)6283 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 6284 if (nc == null) { 6285 return false; 6286 } 6287 int[] transportTypes = nc.getTransportTypes(); 6288 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 6289 return false; 6290 } 6291 try { 6292 mContext.enforceCallingOrSelfPermission( 6293 android.Manifest.permission.ACCESS_WIFI_STATE, 6294 "ConnectivityService"); 6295 } catch (SecurityException e) { 6296 return false; 6297 } 6298 return true; 6299 } 6300 6301 @Override listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder, @NetworkCallback.Flag int callbackFlags, @NonNull String callingPackageName, @NonNull String callingAttributionTag)6302 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 6303 Messenger messenger, IBinder binder, 6304 @NetworkCallback.Flag int callbackFlags, 6305 @NonNull String callingPackageName, @NonNull String callingAttributionTag) { 6306 final int callingUid = mDeps.getCallingUid(); 6307 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 6308 enforceAccessPermission(); 6309 } 6310 6311 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 6312 ensureSufficientPermissionsForRequest(networkCapabilities, 6313 Binder.getCallingPid(), callingUid, callingPackageName); 6314 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 6315 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 6316 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 6317 // onLost and onAvailable callbacks when networks move in and out of the background. 6318 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 6319 // can't request networks. 6320 restrictBackgroundRequestForCaller(nc); 6321 ensureValid(nc); 6322 6323 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 6324 NetworkRequest.Type.LISTEN); 6325 NetworkRequestInfo nri = 6326 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags, 6327 callingAttributionTag); 6328 if (VDBG) log("listenForNetwork for " + nri); 6329 6330 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 6331 return networkRequest; 6332 } 6333 6334 @Override pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation, @NonNull String callingPackageName, @Nullable String callingAttributionTag)6335 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 6336 PendingIntent operation, @NonNull String callingPackageName, 6337 @Nullable String callingAttributionTag) { 6338 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 6339 final int callingUid = mDeps.getCallingUid(); 6340 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 6341 enforceAccessPermission(); 6342 } 6343 ensureValid(networkCapabilities); 6344 ensureSufficientPermissionsForRequest(networkCapabilities, 6345 Binder.getCallingPid(), callingUid, callingPackageName); 6346 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 6347 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 6348 6349 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 6350 NetworkRequest.Type.LISTEN); 6351 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 6352 callingAttributionTag); 6353 if (VDBG) log("pendingListenForNetwork for " + nri); 6354 6355 mHandler.sendMessage(mHandler.obtainMessage( 6356 EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri)); 6357 } 6358 6359 /** Returns the next Network provider ID. */ nextNetworkProviderId()6360 public final int nextNetworkProviderId() { 6361 return mNextNetworkProviderId.getAndIncrement(); 6362 } 6363 6364 @Override releaseNetworkRequest(NetworkRequest networkRequest)6365 public void releaseNetworkRequest(NetworkRequest networkRequest) { 6366 ensureNetworkRequestHasType(networkRequest); 6367 mHandler.sendMessage(mHandler.obtainMessage( 6368 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest)); 6369 } 6370 handleRegisterNetworkProvider(NetworkProviderInfo npi)6371 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { 6372 if (mNetworkProviderInfos.containsKey(npi.messenger)) { 6373 // Avoid creating duplicates. even if an app makes a direct AIDL call. 6374 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, 6375 // as that will throw if a duplicate provider is registered. 6376 loge("Attempt to register existing NetworkProviderInfo " 6377 + mNetworkProviderInfos.get(npi.messenger).name); 6378 return; 6379 } 6380 6381 if (DBG) log("Got NetworkProvider Messenger for " + npi.name); 6382 mNetworkProviderInfos.put(npi.messenger, npi); 6383 npi.connect(mContext, mTrackerHandler); 6384 } 6385 6386 @Override registerNetworkProvider(Messenger messenger, String name)6387 public int registerNetworkProvider(Messenger messenger, String name) { 6388 enforceNetworkFactoryOrSettingsPermission(); 6389 Objects.requireNonNull(messenger, "messenger must be non-null"); 6390 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, 6391 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); 6392 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); 6393 return npi.providerId; 6394 } 6395 6396 @Override unregisterNetworkProvider(Messenger messenger)6397 public void unregisterNetworkProvider(Messenger messenger) { 6398 enforceNetworkFactoryOrSettingsPermission(); 6399 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); 6400 } 6401 6402 @Override offerNetwork(final int providerId, @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, @NonNull final INetworkOfferCallback callback)6403 public void offerNetwork(final int providerId, 6404 @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, 6405 @NonNull final INetworkOfferCallback callback) { 6406 Objects.requireNonNull(score); 6407 Objects.requireNonNull(caps); 6408 Objects.requireNonNull(callback); 6409 final NetworkOffer offer = new NetworkOffer( 6410 FullScore.makeProspectiveScore(score, caps), caps, callback, providerId); 6411 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer)); 6412 } 6413 6414 @Override unofferNetwork(@onNull final INetworkOfferCallback callback)6415 public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { 6416 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback)); 6417 } 6418 handleUnregisterNetworkProvider(Messenger messenger)6419 private void handleUnregisterNetworkProvider(Messenger messenger) { 6420 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); 6421 if (npi == null) { 6422 loge("Failed to find Messenger in unregisterNetworkProvider"); 6423 return; 6424 } 6425 // Unregister all the offers from this provider 6426 final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>(); 6427 for (final NetworkOfferInfo noi : mNetworkOffers) { 6428 if (noi.offer.providerId == npi.providerId) { 6429 // Can't call handleUnregisterNetworkOffer here because iteration is in progress 6430 toRemove.add(noi); 6431 } 6432 } 6433 for (final NetworkOfferInfo noi : toRemove) { 6434 handleUnregisterNetworkOffer(noi); 6435 } 6436 if (DBG) log("unregisterNetworkProvider for " + npi.name); 6437 } 6438 6439 @Override declareNetworkRequestUnfulfillable(@onNull final NetworkRequest request)6440 public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) { 6441 if (request.hasTransport(TRANSPORT_TEST)) { 6442 enforceNetworkFactoryOrTestNetworksPermission(); 6443 } else { 6444 enforceNetworkFactoryPermission(); 6445 } 6446 final NetworkRequestInfo nri = mNetworkRequests.get(request); 6447 if (nri != null) { 6448 // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests. 6449 ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable"); 6450 mHandler.post(() -> handleReleaseNetworkRequest( 6451 nri.mRequests.get(0), mDeps.getCallingUid(), true)); 6452 } 6453 } 6454 6455 // NOTE: Accessed on multiple threads, must be synchronized on itself. 6456 @GuardedBy("mNetworkForNetId") 6457 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); 6458 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 6459 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so 6460 // there may not be a strict 1:1 correlation between the two. 6461 private final NetIdManager mNetIdManager; 6462 6463 // Tracks all NetworkAgents that are currently registered. 6464 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 6465 private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>(); 6466 6467 // UID ranges for users that are currently blocked by VPNs. 6468 // This array is accessed and iterated on multiple threads without holding locks, so its 6469 // contents must never be mutated. When the ranges change, the array is replaced with a new one 6470 // (on the handler thread). 6471 private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>(); 6472 6473 // Must only be accessed on the handler thread 6474 @NonNull 6475 private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>(); 6476 6477 @GuardedBy("mBlockedAppUids") 6478 private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 6479 6480 // Current OEM network preferences. This object must only be written to on the handler thread. 6481 // Since it is immutable and always non-null, other threads may read it if they only care 6482 // about seeing a consistent object but not that it is current. 6483 @NonNull 6484 private OemNetworkPreferences mOemNetworkPreferences = 6485 new OemNetworkPreferences.Builder().build(); 6486 // Current per-profile network preferences. This object follows the same threading rules as 6487 // the OEM network preferences above. 6488 @NonNull 6489 private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences(); 6490 6491 // A set of UIDs that should use mobile data preferentially if available. This object follows 6492 // the same threading rules as the OEM network preferences above. 6493 @NonNull 6494 private Set<Integer> mMobileDataPreferredUids = new ArraySet<>(); 6495 6496 // OemNetworkPreferences activity String log entries. 6497 private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20; 6498 @NonNull 6499 private final LocalLog mOemNetworkPreferencesLogs = 6500 new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS); 6501 6502 /** 6503 * Determine whether a given package has a mapping in the current OemNetworkPreferences. 6504 * @param packageName the package name to check existence of a mapping for. 6505 * @return true if a mapping exists, false otherwise 6506 */ isMappedInOemNetworkPreference(@onNull final String packageName)6507 private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) { 6508 return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName); 6509 } 6510 6511 // The always-on request for an Internet-capable network that apps without a specific default 6512 // fall back to. 6513 @VisibleForTesting 6514 @NonNull 6515 final NetworkRequestInfo mDefaultRequest; 6516 // Collection of NetworkRequestInfo's used for default networks. 6517 @VisibleForTesting 6518 @NonNull 6519 final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>(); 6520 isPerAppDefaultRequest(@onNull final NetworkRequestInfo nri)6521 private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) { 6522 return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri); 6523 } 6524 6525 /** 6526 * Return the default network request currently tracking the given uid. 6527 * @param uid the uid to check. 6528 * @return the NetworkRequestInfo tracking the given uid. 6529 */ 6530 @NonNull getDefaultRequestTrackingUid(final int uid)6531 private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) { 6532 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 6533 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 6534 // Checking the first request is sufficient as only multilayer requests will have more 6535 // than one request and for multilayer, all requests will track the same uids. 6536 if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) { 6537 // Find out the highest priority request. 6538 if (nri.hasHigherPriorityThan(highestPriorityNri)) { 6539 highestPriorityNri = nri; 6540 } 6541 } 6542 } 6543 return highestPriorityNri; 6544 } 6545 6546 /** 6547 * Get a copy of the network requests of the default request that is currently tracking the 6548 * given uid. 6549 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 6550 * when a privileged caller is tracking the default network for another uid. 6551 * @param requestorUid the uid to check the default for. 6552 * @param requestorPackageName the requestor's package name. 6553 * @return a copy of the default's NetworkRequest that is tracking the given uid. 6554 */ 6555 @NonNull copyDefaultNetworkRequestsForUid( final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6556 private List<NetworkRequest> copyDefaultNetworkRequestsForUid( 6557 final int asUid, final int requestorUid, @NonNull final String requestorPackageName) { 6558 return copyNetworkRequestsForUid( 6559 getDefaultRequestTrackingUid(asUid).mRequests, 6560 asUid, requestorUid, requestorPackageName); 6561 } 6562 6563 /** 6564 * Copy the given nri's NetworkRequest collection. 6565 * @param requestsToCopy the NetworkRequest collection to be copied. 6566 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 6567 * when a privileged caller is tracking the default network for another uid. 6568 * @param requestorUid the uid to set on the copied collection. 6569 * @param requestorPackageName the package name to set on the copied collection. 6570 * @return the copied NetworkRequest collection. 6571 */ 6572 @NonNull copyNetworkRequestsForUid( @onNull final List<NetworkRequest> requestsToCopy, final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6573 private List<NetworkRequest> copyNetworkRequestsForUid( 6574 @NonNull final List<NetworkRequest> requestsToCopy, final int asUid, 6575 final int requestorUid, @NonNull final String requestorPackageName) { 6576 final List<NetworkRequest> requests = new ArrayList<>(); 6577 for (final NetworkRequest nr : requestsToCopy) { 6578 requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid( 6579 nr.networkCapabilities, asUid, requestorUid, requestorPackageName), 6580 nr.legacyType, nextNetworkRequestId(), nr.type)); 6581 } 6582 return requests; 6583 } 6584 6585 @NonNull copyDefaultNetworkCapabilitiesForUid( @onNull final NetworkCapabilities netCapToCopy, final int asUid, final int requestorUid, @NonNull final String requestorPackageName)6586 private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid( 6587 @NonNull final NetworkCapabilities netCapToCopy, final int asUid, 6588 final int requestorUid, @NonNull final String requestorPackageName) { 6589 // These capabilities are for a TRACK_DEFAULT callback, so: 6590 // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between 6591 // mDefaultRequest and a per-UID default request. 6592 // TODO: stop depending on the fact that these two unrelated things happen to be the same 6593 // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will 6594 // not do this in the case of a privileged application. 6595 final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy); 6596 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 6597 netCap.setSingleUid(asUid); 6598 restrictRequestUidsForCallerAndSetRequestorInfo( 6599 netCap, requestorUid, requestorPackageName); 6600 return netCap; 6601 } 6602 6603 /** 6604 * Get the nri that is currently being tracked for callbacks by per-app defaults. 6605 * @param nr the network request to check for equality against. 6606 * @return the nri if one exists, null otherwise. 6607 */ 6608 @Nullable getNriForAppRequest(@onNull final NetworkRequest nr)6609 private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) { 6610 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 6611 if (nri.getNetworkRequestForCallback().equals(nr)) { 6612 return nri; 6613 } 6614 } 6615 return null; 6616 } 6617 6618 /** 6619 * Check if an nri is currently being managed by per-app default networking. 6620 * @param nri the nri to check. 6621 * @return true if this nri is currently being managed by per-app default networking. 6622 */ isPerAppTrackedNri(@onNull final NetworkRequestInfo nri)6623 private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) { 6624 // nri.mRequests.get(0) is only different from the original request filed in 6625 // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default 6626 // functionality therefore if these two don't match, it means this particular nri is 6627 // currently being managed by a per-app default. 6628 return nri.getNetworkRequestForCallback() != nri.mRequests.get(0); 6629 } 6630 6631 /** 6632 * Determine if an nri is a managed default request that disallows default networking. 6633 * @param nri the request to evaluate 6634 * @return true if device-default networking is disallowed 6635 */ isDefaultBlocked(@onNull final NetworkRequestInfo nri)6636 private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) { 6637 // Check if this nri is a managed default that supports the default network at its 6638 // lowest priority request. 6639 final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0); 6640 final NetworkCapabilities lowestPriorityNetCap = 6641 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities; 6642 return isPerAppDefaultRequest(nri) 6643 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities( 6644 lowestPriorityNetCap)); 6645 } 6646 6647 // Request used to optionally keep mobile data active even when higher 6648 // priority networks like Wi-Fi are active. 6649 private final NetworkRequest mDefaultMobileDataRequest; 6650 6651 // Request used to optionally keep wifi data active even when higher 6652 // priority networks like ethernet are active. 6653 private final NetworkRequest mDefaultWifiRequest; 6654 6655 // Request used to optionally keep vehicle internal network always active 6656 private final NetworkRequest mDefaultVehicleRequest; 6657 6658 // Sentinel NAI used to direct apps with default networks that should have no connectivity to a 6659 // network with no service. This NAI should never be matched against, nor should any public API 6660 // ever return the associated network. For this reason, this NAI is not in the list of available 6661 // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device 6662 // default requests that don't support using the device default network which will ultimately 6663 // allow ConnectivityService to use this no-service network when calling makeDefaultForApps(). 6664 @VisibleForTesting 6665 final NetworkAgentInfo mNoServiceNetwork; 6666 6667 // The NetworkAgentInfo currently satisfying the default request, if any. getDefaultNetwork()6668 private NetworkAgentInfo getDefaultNetwork() { 6669 return mDefaultRequest.mSatisfier; 6670 } 6671 getDefaultNetworkForUid(final int uid)6672 private NetworkAgentInfo getDefaultNetworkForUid(final int uid) { 6673 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 6674 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 6675 // Currently, all network requests will have the same uids therefore checking the first 6676 // one is sufficient. If/when uids are tracked at the nri level, this can change. 6677 final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges(); 6678 if (null == uids) { 6679 continue; 6680 } 6681 for (final UidRange range : uids) { 6682 if (range.contains(uid)) { 6683 if (nri.hasHigherPriorityThan(highestPriorityNri)) { 6684 highestPriorityNri = nri; 6685 } 6686 } 6687 } 6688 } 6689 return highestPriorityNri.getSatisfier(); 6690 } 6691 6692 @Nullable getNetwork(@ullable NetworkAgentInfo nai)6693 private Network getNetwork(@Nullable NetworkAgentInfo nai) { 6694 return nai != null ? nai.network : null; 6695 } 6696 ensureRunningOnConnectivityServiceThread()6697 private void ensureRunningOnConnectivityServiceThread() { 6698 if (mHandler.getLooper().getThread() != Thread.currentThread()) { 6699 throw new IllegalStateException( 6700 "Not running on ConnectivityService thread: " 6701 + Thread.currentThread().getName()); 6702 } 6703 } 6704 6705 @VisibleForTesting isDefaultNetwork(NetworkAgentInfo nai)6706 protected boolean isDefaultNetwork(NetworkAgentInfo nai) { 6707 return nai == getDefaultNetwork(); 6708 } 6709 6710 /** 6711 * Register a new agent with ConnectivityService to handle a network. 6712 * 6713 * @param na a reference for ConnectivityService to contact the agent asynchronously. 6714 * @param networkInfo the initial info associated with this network. It can be updated later : 6715 * see {@link #updateNetworkInfo}. 6716 * @param linkProperties the initial link properties of this network. They can be updated 6717 * later : see {@link #updateLinkProperties}. 6718 * @param networkCapabilities the initial capabilites of this network. They can be updated 6719 * later : see {@link #updateCapabilities}. 6720 * @param initialScore the initial score of the network. See 6721 * {@link NetworkAgentInfo#getCurrentScore}. 6722 * @param networkAgentConfig metadata about the network. This is never updated. 6723 * @param providerId the ID of the provider owning this NetworkAgent. 6724 * @return the network created for this agent. 6725 */ registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, int providerId)6726 public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, 6727 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 6728 @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, 6729 int providerId) { 6730 Objects.requireNonNull(networkInfo, "networkInfo must not be null"); 6731 Objects.requireNonNull(linkProperties, "linkProperties must not be null"); 6732 Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); 6733 Objects.requireNonNull(initialScore, "initialScore must not be null"); 6734 Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); 6735 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 6736 enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS); 6737 } else { 6738 enforceNetworkFactoryPermission(); 6739 } 6740 6741 final int uid = mDeps.getCallingUid(); 6742 final long token = Binder.clearCallingIdentity(); 6743 try { 6744 return registerNetworkAgentInternal(na, networkInfo, linkProperties, 6745 networkCapabilities, initialScore, networkAgentConfig, providerId, uid); 6746 } finally { 6747 Binder.restoreCallingIdentity(token); 6748 } 6749 } 6750 registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid)6751 private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, 6752 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 6753 NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, 6754 int uid) { 6755 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 6756 // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in 6757 // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never 6758 // sees capabilities that may be malicious, which might prevent mistakes in the future. 6759 networkCapabilities = new NetworkCapabilities(networkCapabilities); 6760 networkCapabilities.restrictCapabilitesForTestNetwork(uid); 6761 } 6762 6763 LinkProperties lp = new LinkProperties(linkProperties); 6764 6765 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 6766 final NetworkAgentInfo nai = new NetworkAgentInfo(na, 6767 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, 6768 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), 6769 this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs, 6770 mQosCallbackTracker, mDeps); 6771 6772 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says. 6773 processCapabilitiesFromAgent(nai, nc); 6774 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc)); 6775 processLinkPropertiesFromAgent(nai, nai.linkProperties); 6776 6777 final String extraInfo = networkInfo.getExtraInfo(); 6778 final String name = TextUtils.isEmpty(extraInfo) 6779 ? nai.networkCapabilities.getSsid() : extraInfo; 6780 if (DBG) log("registerNetworkAgent " + nai); 6781 mDeps.getNetworkStack().makeNetworkMonitor( 6782 nai.network, name, new NetworkMonitorCallbacks(nai)); 6783 // NetworkAgentInfo registration will finish when the NetworkMonitor is created. 6784 // If the network disconnects or sends any other event before that, messages are deferred by 6785 // NetworkAgent until nai.connect(), which will be called when finalizing the 6786 // registration. 6787 return nai.network; 6788 } 6789 handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor)6790 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { 6791 nai.onNetworkMonitorCreated(networkMonitor); 6792 if (VDBG) log("Got NetworkAgent Messenger"); 6793 mNetworkAgentInfos.add(nai); 6794 synchronized (mNetworkForNetId) { 6795 mNetworkForNetId.put(nai.network.getNetId(), nai); 6796 } 6797 6798 try { 6799 networkMonitor.start(); 6800 } catch (RemoteException e) { 6801 e.rethrowAsRuntimeException(); 6802 } 6803 nai.notifyRegistered(); 6804 NetworkInfo networkInfo = nai.networkInfo; 6805 updateNetworkInfo(nai, networkInfo); 6806 updateUids(nai, null, nai.networkCapabilities); 6807 } 6808 6809 private class NetworkOfferInfo implements IBinder.DeathRecipient { 6810 @NonNull public final NetworkOffer offer; 6811 NetworkOfferInfo(@onNull final NetworkOffer offer)6812 NetworkOfferInfo(@NonNull final NetworkOffer offer) { 6813 this.offer = offer; 6814 } 6815 6816 @Override binderDied()6817 public void binderDied() { 6818 mHandler.post(() -> handleUnregisterNetworkOffer(this)); 6819 } 6820 } 6821 isNetworkProviderWithIdRegistered(final int providerId)6822 private boolean isNetworkProviderWithIdRegistered(final int providerId) { 6823 for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 6824 if (npi.providerId == providerId) return true; 6825 } 6826 return false; 6827 } 6828 6829 /** 6830 * Register or update a network offer. 6831 * @param newOffer The new offer. If the callback member is the same as an existing 6832 * offer, it is an update of that offer. 6833 */ handleRegisterNetworkOffer(@onNull final NetworkOffer newOffer)6834 private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) { 6835 ensureRunningOnConnectivityServiceThread(); 6836 if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) { 6837 // This may actually happen if a provider updates its score or registers and then 6838 // immediately unregisters. The offer would still be in the handler queue, but the 6839 // provider would have been removed. 6840 if (DBG) log("Received offer from an unregistered provider"); 6841 return; 6842 } 6843 final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback); 6844 if (null != existingOffer) { 6845 handleUnregisterNetworkOffer(existingOffer); 6846 newOffer.migrateFrom(existingOffer.offer); 6847 } 6848 final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer); 6849 try { 6850 noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */); 6851 } catch (RemoteException e) { 6852 noi.binderDied(); 6853 return; 6854 } 6855 mNetworkOffers.add(noi); 6856 issueNetworkNeeds(noi); 6857 } 6858 handleUnregisterNetworkOffer(@onNull final NetworkOfferInfo noi)6859 private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) { 6860 ensureRunningOnConnectivityServiceThread(); 6861 mNetworkOffers.remove(noi); 6862 noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */); 6863 } 6864 findNetworkOfferInfoByCallback( @onNull final INetworkOfferCallback callback)6865 @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback( 6866 @NonNull final INetworkOfferCallback callback) { 6867 ensureRunningOnConnectivityServiceThread(); 6868 for (final NetworkOfferInfo noi : mNetworkOffers) { 6869 if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi; 6870 } 6871 return null; 6872 } 6873 6874 /** 6875 * Called when receiving LinkProperties directly from a NetworkAgent. 6876 * Stores into |nai| any data coming from the agent that might also be written to the network's 6877 * LinkProperties by ConnectivityService itself. This ensures that the data provided by the 6878 * agent is not lost when updateLinkProperties is called. 6879 * This method should never alter the agent's LinkProperties, only store data in |nai|. 6880 */ processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp)6881 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { 6882 lp.ensureDirectlyConnectedRoutes(); 6883 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix()); 6884 nai.networkAgentPortalData = lp.getCaptivePortalData(); 6885 } 6886 updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, @NonNull LinkProperties oldLp)6887 private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, 6888 @NonNull LinkProperties oldLp) { 6889 int netId = networkAgent.network.getNetId(); 6890 6891 // The NetworkAgent does not know whether clatd is running on its network or not, or whether 6892 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure 6893 // the LinkProperties for the network are accurate. 6894 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 6895 6896 updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities); 6897 6898 // update filtering rules, need to happen after the interface update so netd knows about the 6899 // new interface (the interface name -> index map becomes initialized) 6900 updateVpnFiltering(newLp, oldLp, networkAgent); 6901 6902 updateMtu(newLp, oldLp); 6903 // TODO - figure out what to do for clat 6904 // for (LinkProperties lp : newLp.getStackedLinks()) { 6905 // updateMtu(lp, null); 6906 // } 6907 if (isDefaultNetwork(networkAgent)) { 6908 updateTcpBufferSizes(newLp.getTcpBufferSizes()); 6909 } 6910 6911 updateRoutes(newLp, oldLp, netId); 6912 updateDnses(newLp, oldLp, netId); 6913 // Make sure LinkProperties represents the latest private DNS status. 6914 // This does not need to be done before updateDnses because the 6915 // LinkProperties are not the source of the private DNS configuration. 6916 // updateDnses will fetch the private DNS configuration from DnsManager. 6917 mDnsManager.updatePrivateDnsStatus(netId, newLp); 6918 6919 if (isDefaultNetwork(networkAgent)) { 6920 handleApplyDefaultProxy(newLp.getHttpProxy()); 6921 } else { 6922 updateProxy(newLp, oldLp); 6923 } 6924 6925 updateWakeOnLan(newLp); 6926 6927 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo. 6928 // It is not always contained in the LinkProperties sent from NetworkAgents, and if it 6929 // does, it needs to be merged here. 6930 newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData, 6931 networkAgent.capportApiData)); 6932 6933 // TODO - move this check to cover the whole function 6934 if (!Objects.equals(newLp, oldLp)) { 6935 synchronized (networkAgent) { 6936 networkAgent.linkProperties = newLp; 6937 } 6938 // Start or stop DNS64 detection and 464xlat according to network state. 6939 networkAgent.clatd.update(); 6940 notifyIfacesChangedForNetworkStats(); 6941 networkAgent.networkMonitor().notifyLinkPropertiesChanged( 6942 new LinkProperties(newLp, true /* parcelSensitiveFields */)); 6943 if (networkAgent.everConnected) { 6944 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 6945 } 6946 } 6947 6948 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 6949 } 6950 6951 /** 6952 * @param naData captive portal data from NetworkAgent 6953 * @param apiData captive portal data from capport API 6954 */ 6955 @Nullable mergeCaptivePortalData(CaptivePortalData naData, CaptivePortalData apiData)6956 private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData, 6957 CaptivePortalData apiData) { 6958 if (naData == null || apiData == null) { 6959 return naData == null ? apiData : naData; 6960 } 6961 final CaptivePortalData.Builder captivePortalBuilder = 6962 new CaptivePortalData.Builder(naData); 6963 6964 if (apiData.isCaptive()) { 6965 captivePortalBuilder.setCaptive(true); 6966 } 6967 if (apiData.isSessionExtendable()) { 6968 captivePortalBuilder.setSessionExtendable(true); 6969 } 6970 if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) { 6971 // Expiry time, bytes remaining, refresh time all need to come from the same source, 6972 // otherwise data would be inconsistent. Prefer the capport API info if present, 6973 // as it can generally be refreshed more often. 6974 captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis()); 6975 captivePortalBuilder.setBytesRemaining(apiData.getByteLimit()); 6976 captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis()); 6977 } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) { 6978 // No source has time / bytes remaining information: surface the newest refresh time 6979 // for other fields 6980 captivePortalBuilder.setRefreshTime( 6981 Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis())); 6982 } 6983 6984 // Prioritize the user portal URL from the network agent if the source is authenticated. 6985 if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource() 6986 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 6987 captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(), 6988 apiData.getUserPortalUrlSource()); 6989 } 6990 // Prioritize the venue information URL from the network agent if the source is 6991 // authenticated. 6992 if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource() 6993 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 6994 captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(), 6995 apiData.getVenueInfoUrlSource()); 6996 } 6997 return captivePortalBuilder.build(); 6998 } 6999 wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)7000 private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) { 7001 // Marks are only available on WiFi interfaces. Checking for 7002 // marks on unsupported interfaces is harmless. 7003 if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 7004 return; 7005 } 7006 7007 int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark); 7008 int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask); 7009 7010 // Mask/mark of zero will not detect anything interesting. 7011 // Don't install rules unless both values are nonzero. 7012 if (mark == 0 || mask == 0) { 7013 return; 7014 } 7015 7016 final String prefix = "iface:" + iface; 7017 try { 7018 if (add) { 7019 mNetd.wakeupAddInterface(iface, prefix, mark, mask); 7020 } else { 7021 mNetd.wakeupDelInterface(iface, prefix, mark, mask); 7022 } 7023 } catch (Exception e) { 7024 loge("Exception modifying wakeup packet monitoring: " + e); 7025 } 7026 7027 } 7028 updateInterfaces(final @Nullable LinkProperties newLp, final @Nullable LinkProperties oldLp, final int netId, final @NonNull NetworkCapabilities caps)7029 private void updateInterfaces(final @Nullable LinkProperties newLp, 7030 final @Nullable LinkProperties oldLp, final int netId, 7031 final @NonNull NetworkCapabilities caps) { 7032 final CompareResult<String> interfaceDiff = new CompareResult<>( 7033 oldLp != null ? oldLp.getAllInterfaceNames() : null, 7034 newLp != null ? newLp.getAllInterfaceNames() : null); 7035 if (!interfaceDiff.added.isEmpty()) { 7036 for (final String iface : interfaceDiff.added) { 7037 try { 7038 if (DBG) log("Adding iface " + iface + " to network " + netId); 7039 mNetd.networkAddInterface(netId, iface); 7040 wakeupModifyInterface(iface, caps, true); 7041 mDeps.reportNetworkInterfaceForTransports(mContext, iface, 7042 caps.getTransportTypes()); 7043 } catch (Exception e) { 7044 logw("Exception adding interface: " + e); 7045 } 7046 } 7047 } 7048 for (final String iface : interfaceDiff.removed) { 7049 try { 7050 if (DBG) log("Removing iface " + iface + " from network " + netId); 7051 wakeupModifyInterface(iface, caps, false); 7052 mNetd.networkRemoveInterface(netId, iface); 7053 } catch (Exception e) { 7054 loge("Exception removing interface: " + e); 7055 } 7056 } 7057 } 7058 7059 // TODO: move to frameworks/libs/net. convertRouteInfo(RouteInfo route)7060 private RouteInfoParcel convertRouteInfo(RouteInfo route) { 7061 final String nextHop; 7062 7063 switch (route.getType()) { 7064 case RouteInfo.RTN_UNICAST: 7065 if (route.hasGateway()) { 7066 nextHop = route.getGateway().getHostAddress(); 7067 } else { 7068 nextHop = INetd.NEXTHOP_NONE; 7069 } 7070 break; 7071 case RouteInfo.RTN_UNREACHABLE: 7072 nextHop = INetd.NEXTHOP_UNREACHABLE; 7073 break; 7074 case RouteInfo.RTN_THROW: 7075 nextHop = INetd.NEXTHOP_THROW; 7076 break; 7077 default: 7078 nextHop = INetd.NEXTHOP_NONE; 7079 break; 7080 } 7081 7082 final RouteInfoParcel rip = new RouteInfoParcel(); 7083 rip.ifName = route.getInterface(); 7084 rip.destination = route.getDestination().toString(); 7085 rip.nextHop = nextHop; 7086 rip.mtu = route.getMtu(); 7087 7088 return rip; 7089 } 7090 7091 /** 7092 * Have netd update routes from oldLp to newLp. 7093 * @return true if routes changed between oldLp and newLp 7094 */ updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)7095 private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { 7096 // compare the route diff to determine which routes have been updated 7097 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff = 7098 new CompareOrUpdateResult<>( 7099 oldLp != null ? oldLp.getAllRoutes() : null, 7100 newLp != null ? newLp.getAllRoutes() : null, 7101 (r) -> r.getRouteKey()); 7102 7103 // add routes before removing old in case it helps with continuous connectivity 7104 7105 // do this twice, adding non-next-hop routes first, then routes they are dependent on 7106 for (RouteInfo route : routeDiff.added) { 7107 if (route.hasGateway()) continue; 7108 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 7109 try { 7110 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); 7111 } catch (Exception e) { 7112 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 7113 loge("Exception in networkAddRouteParcel for non-gateway: " + e); 7114 } 7115 } 7116 } 7117 for (RouteInfo route : routeDiff.added) { 7118 if (!route.hasGateway()) continue; 7119 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 7120 try { 7121 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); 7122 } catch (Exception e) { 7123 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 7124 loge("Exception in networkAddRouteParcel for gateway: " + e); 7125 } 7126 } 7127 } 7128 7129 for (RouteInfo route : routeDiff.removed) { 7130 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); 7131 try { 7132 mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route)); 7133 } catch (Exception e) { 7134 loge("Exception in networkRemoveRouteParcel: " + e); 7135 } 7136 } 7137 7138 for (RouteInfo route : routeDiff.updated) { 7139 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId); 7140 try { 7141 mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route)); 7142 } catch (Exception e) { 7143 loge("Exception in networkUpdateRouteParcel: " + e); 7144 } 7145 } 7146 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty() 7147 || !routeDiff.updated.isEmpty(); 7148 } 7149 updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)7150 private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { 7151 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 7152 return; // no updating necessary 7153 } 7154 7155 if (DBG) { 7156 final Collection<InetAddress> dnses = newLp.getDnsServers(); 7157 log("Setting DNS servers for network " + netId + " to " + dnses); 7158 } 7159 try { 7160 mDnsManager.noteDnsServersForNetwork(netId, newLp); 7161 mDnsManager.flushVmDnsCache(); 7162 } catch (Exception e) { 7163 loge("Exception in setDnsConfigurationForNetwork: " + e); 7164 } 7165 } 7166 updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)7167 private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, 7168 NetworkAgentInfo nai) { 7169 final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null; 7170 final String newIface = newLp != null ? newLp.getInterfaceName() : null; 7171 final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp); 7172 final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp); 7173 7174 if (!wasFiltering && !needsFiltering) { 7175 // Nothing to do. 7176 return; 7177 } 7178 7179 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) { 7180 // Nothing changed. 7181 return; 7182 } 7183 7184 final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges(); 7185 final int vpnAppUid = nai.networkCapabilities.getOwnerUid(); 7186 // TODO: this create a window of opportunity for apps to receive traffic between the time 7187 // when the old rules are removed and the time when new rules are added. To fix this, 7188 // make eBPF support two allowlisted interfaces so here new rules can be added before the 7189 // old rules are being removed. 7190 if (wasFiltering) { 7191 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid); 7192 } 7193 if (needsFiltering) { 7194 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid); 7195 } 7196 } 7197 updateWakeOnLan(@onNull LinkProperties lp)7198 private void updateWakeOnLan(@NonNull LinkProperties lp) { 7199 if (mWolSupportedInterfaces == null) { 7200 mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray( 7201 R.array.config_wakeonlan_supported_interfaces)); 7202 } 7203 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName())); 7204 } 7205 getNetworkPermission(NetworkCapabilities nc)7206 private int getNetworkPermission(NetworkCapabilities nc) { 7207 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 7208 return INetd.PERMISSION_SYSTEM; 7209 } 7210 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 7211 return INetd.PERMISSION_NETWORK; 7212 } 7213 return INetd.PERMISSION_NONE; 7214 } 7215 updateNetworkPermissions(@onNull final NetworkAgentInfo nai, @NonNull final NetworkCapabilities newNc)7216 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai, 7217 @NonNull final NetworkCapabilities newNc) { 7218 final int oldPermission = getNetworkPermission(nai.networkCapabilities); 7219 final int newPermission = getNetworkPermission(newNc); 7220 if (oldPermission != newPermission && nai.created && !nai.isVPN()) { 7221 try { 7222 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission); 7223 } catch (RemoteException | ServiceSpecificException e) { 7224 loge("Exception in networkSetPermissionForNetwork: " + e); 7225 } 7226 } 7227 } 7228 7229 /** 7230 * Called when receiving NetworkCapabilities directly from a NetworkAgent. 7231 * Stores into |nai| any data coming from the agent that might also be written to the network's 7232 * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the 7233 * agent is not lost when updateCapabilities is called. 7234 * This method should never alter the agent's NetworkCapabilities, only store data in |nai|. 7235 */ processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc)7236 private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) { 7237 // Note: resetting the owner UID before storing the agent capabilities in NAI means that if 7238 // the agent attempts to change the owner UID, then nai.declaredCapabilities will not 7239 // actually be the same as the capabilities sent by the agent. Still, it is safer to reset 7240 // the owner UID here and behave as if the agent had never tried to change it. 7241 if (nai.networkCapabilities.getOwnerUid() != nc.getOwnerUid()) { 7242 Log.e(TAG, nai.toShortString() + ": ignoring attempt to change owner from " 7243 + nai.networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid()); 7244 nc.setOwnerUid(nai.networkCapabilities.getOwnerUid()); 7245 } 7246 nai.declaredCapabilities = new NetworkCapabilities(nc); 7247 } 7248 7249 /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */ 7250 @VisibleForTesting applyUnderlyingCapabilities(@ullable Network[] underlyingNetworks, @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc)7251 void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, 7252 @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { 7253 underlyingNetworks = underlyingNetworksOrDefault( 7254 agentCaps.getOwnerUid(), underlyingNetworks); 7255 long transportTypes = NetworkCapabilitiesUtils.packBits(agentCaps.getTransportTypes()); 7256 int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 7257 int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 7258 // metered if any underlying is metered, or originally declared metered by the agent. 7259 boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 7260 boolean roaming = false; // roaming if any underlying is roaming 7261 boolean congested = false; // congested if any underlying is congested 7262 boolean suspended = true; // suspended if all underlying are suspended 7263 7264 boolean hadUnderlyingNetworks = false; 7265 if (null != underlyingNetworks) { 7266 for (Network underlyingNetwork : underlyingNetworks) { 7267 final NetworkAgentInfo underlying = 7268 getNetworkAgentInfoForNetwork(underlyingNetwork); 7269 if (underlying == null) continue; 7270 7271 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; 7272 hadUnderlyingNetworks = true; 7273 for (int underlyingType : underlyingCaps.getTransportTypes()) { 7274 transportTypes |= 1L << underlyingType; 7275 } 7276 7277 // Merge capabilities of this underlying network. For bandwidth, assume the 7278 // worst case. 7279 downKbps = NetworkCapabilities.minBandwidth(downKbps, 7280 underlyingCaps.getLinkDownstreamBandwidthKbps()); 7281 upKbps = NetworkCapabilities.minBandwidth(upKbps, 7282 underlyingCaps.getLinkUpstreamBandwidthKbps()); 7283 // If this underlying network is metered, the VPN is metered (it may cost money 7284 // to send packets on this network). 7285 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 7286 // If this underlying network is roaming, the VPN is roaming (the billing structure 7287 // is different than the usual, local one). 7288 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); 7289 // If this underlying network is congested, the VPN is congested (the current 7290 // condition of the network affects the performance of this network). 7291 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 7292 // If this network is not suspended, the VPN is not suspended (the VPN 7293 // is able to transfer some data). 7294 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 7295 } 7296 } 7297 if (!hadUnderlyingNetworks) { 7298 // No idea what the underlying networks are; assume reasonable defaults 7299 metered = true; 7300 roaming = false; 7301 congested = false; 7302 suspended = false; 7303 } 7304 7305 newNc.setTransportTypes(NetworkCapabilitiesUtils.unpackBits(transportTypes)); 7306 newNc.setLinkDownstreamBandwidthKbps(downKbps); 7307 newNc.setLinkUpstreamBandwidthKbps(upKbps); 7308 newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered); 7309 newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); 7310 newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); 7311 newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); 7312 } 7313 7314 /** 7315 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 7316 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 7317 * and foreground status). 7318 */ 7319 @NonNull mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)7320 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 7321 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 7322 // Don't complain for VPNs since they're not driven by requests and there is no risk of 7323 // causing a connect/teardown loop. 7324 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to 7325 // avoid connect/teardown loops. 7326 if (nai.everConnected && 7327 !nai.isVPN() && 7328 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 7329 // TODO: consider not complaining when a network agent degrades its capabilities if this 7330 // does not cause any request (that is not a listen) currently matching that agent to 7331 // stop being matched by the updated agent. 7332 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 7333 if (!TextUtils.isEmpty(diff)) { 7334 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 7335 } 7336 } 7337 7338 // Don't modify caller's NetworkCapabilities. 7339 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 7340 if (nai.lastValidated) { 7341 newNc.addCapability(NET_CAPABILITY_VALIDATED); 7342 } else { 7343 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 7344 } 7345 if (nai.lastCaptivePortalDetected) { 7346 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 7347 } else { 7348 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 7349 } 7350 if (nai.isBackgroundNetwork()) { 7351 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 7352 } else { 7353 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 7354 } 7355 if (nai.partialConnectivity) { 7356 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 7357 } else { 7358 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 7359 } 7360 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken()); 7361 7362 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING 7363 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) { 7364 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7365 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING); 7366 } 7367 7368 if (nai.propagateUnderlyingCapabilities()) { 7369 applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, nai.declaredCapabilities, 7370 newNc); 7371 } 7372 7373 return newNc; 7374 } 7375 updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7376 private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, 7377 NetworkCapabilities prevNc, NetworkCapabilities newNc) { 7378 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 7379 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 7380 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 7381 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 7382 if (prevSuspended != suspended) { 7383 // TODO (b/73132094) : remove this call once the few users of onSuspended and 7384 // onResumed have been removed. 7385 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED 7386 : ConnectivityManager.CALLBACK_RESUMED); 7387 } 7388 if (prevSuspended != suspended || prevRoaming != roaming) { 7389 // updateNetworkInfo will mix in the suspended info from the capabilities and 7390 // take appropriate action for the network having possibly changed state. 7391 updateNetworkInfo(nai, nai.networkInfo); 7392 } 7393 } 7394 7395 /** 7396 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 7397 * 7398 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 7399 * capabilities we manage and store in {@code nai}, such as validated status and captive 7400 * portal status) 7401 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 7402 * potentially triggers rematches. 7403 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 7404 * change.) 7405 * 7406 * @param oldScore score of the network before any of the changes that prompted us 7407 * to call this function. 7408 * @param nai the network having its capabilities updated. 7409 * @param nc the new network capabilities. 7410 */ updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai, @NonNull final NetworkCapabilities nc)7411 private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai, 7412 @NonNull final NetworkCapabilities nc) { 7413 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 7414 if (Objects.equals(nai.networkCapabilities, newNc)) return; 7415 updateNetworkPermissions(nai, newNc); 7416 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc); 7417 7418 updateUids(nai, prevNc, newNc); 7419 nai.updateScoreForNetworkAgentUpdate(); 7420 7421 if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) { 7422 // If the requestable capabilities haven't changed, and the score hasn't changed, then 7423 // the change we're processing can't affect any requests, it can only affect the listens 7424 // on this network. We might have been called by rematchNetworkAndRequests when a 7425 // network changed foreground state. 7426 processListenRequests(nai); 7427 } else { 7428 // If the requestable capabilities have changed or the score changed, we can't have been 7429 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 7430 rematchAllNetworksAndRequests(); 7431 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 7432 } 7433 updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc); 7434 7435 final boolean oldMetered = prevNc.isMetered(); 7436 final boolean newMetered = newNc.isMetered(); 7437 final boolean meteredChanged = oldMetered != newMetered; 7438 7439 if (meteredChanged) { 7440 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, 7441 mVpnBlockedUidRanges, mVpnBlockedUidRanges); 7442 } 7443 7444 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) 7445 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 7446 7447 // Report changes that are interesting for network statistics tracking. 7448 if (meteredChanged || roamingChanged) { 7449 notifyIfacesChangedForNetworkStats(); 7450 } 7451 7452 // This network might have been underlying another network. Propagate its capabilities. 7453 propagateUnderlyingNetworkCapabilities(nai.network); 7454 7455 if (!newNc.equalsTransportTypes(prevNc)) { 7456 mDnsManager.updateTransportsForNetwork( 7457 nai.network.getNetId(), newNc.getTransportTypes()); 7458 } 7459 7460 maybeSendProxyBroadcast(nai, prevNc, newNc); 7461 } 7462 7463 /** Convenience method to update the capabilities for a given network. */ updateCapabilitiesForNetwork(NetworkAgentInfo nai)7464 private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) { 7465 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); 7466 } 7467 7468 /** 7469 * Returns whether VPN isolation (ingress interface filtering) should be applied on the given 7470 * network. 7471 * 7472 * Ingress interface filtering enforces that all apps under the given network can only receive 7473 * packets from the network's interface (and loopback). This is important for VPNs because 7474 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any 7475 * non-VPN interfaces. 7476 * 7477 * As a result, this method should return true iff 7478 * 1. the network is an app VPN (not legacy VPN) 7479 * 2. the VPN does not allow bypass 7480 * 3. the VPN is fully-routed 7481 * 4. the VPN interface is non-null 7482 * 7483 * @see INetd#firewallAddUidInterfaceRules 7484 * @see INetd#firewallRemoveUidInterfaceRules 7485 */ requiresVpnIsolation(@onNull NetworkAgentInfo nai, NetworkCapabilities nc, LinkProperties lp)7486 private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, 7487 LinkProperties lp) { 7488 if (nc == null || lp == null) return false; 7489 return nai.isVPN() 7490 && !nai.networkAgentConfig.allowBypass 7491 && nc.getOwnerUid() != Process.SYSTEM_UID 7492 && lp.getInterfaceName() != null 7493 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute()) 7494 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()); 7495 } 7496 toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)7497 private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 7498 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; 7499 int index = 0; 7500 for (UidRange range : ranges) { 7501 stableRanges[index] = new UidRangeParcel(range.start, range.stop); 7502 index++; 7503 } 7504 return stableRanges; 7505 } 7506 toUidRangeStableParcels(UidRange[] ranges)7507 private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) { 7508 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 7509 for (int i = 0; i < ranges.length; i++) { 7510 stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop); 7511 } 7512 return stableRanges; 7513 } 7514 maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges, int[] exemptUids)7515 private void maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges, 7516 int[] exemptUids) { 7517 if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) { 7518 try { 7519 mNetd.socketDestroy(ranges, exemptUids); 7520 } catch (Exception e) { 7521 loge("Exception in socket destroy: ", e); 7522 } 7523 } 7524 } 7525 updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges)7526 private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) { 7527 int[] exemptUids = new int[2]; 7528 // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used 7529 // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when 7530 // starting a legacy VPN, and remove VPN_UID here. (b/176542831) 7531 exemptUids[0] = VPN_UID; 7532 exemptUids[1] = nai.networkCapabilities.getOwnerUid(); 7533 UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges); 7534 7535 maybeCloseSockets(nai, ranges, exemptUids); 7536 try { 7537 if (add) { 7538 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 7539 nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN)); 7540 } else { 7541 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 7542 nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN)); 7543 } 7544 } catch (Exception e) { 7545 loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges + 7546 " on netId " + nai.network.netId + ". " + e); 7547 } 7548 maybeCloseSockets(nai, ranges, exemptUids); 7549 } 7550 isProxySetOnAnyDefaultNetwork()7551 private boolean isProxySetOnAnyDefaultNetwork() { 7552 ensureRunningOnConnectivityServiceThread(); 7553 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 7554 final NetworkAgentInfo nai = nri.getSatisfier(); 7555 if (nai != null && nai.linkProperties.getHttpProxy() != null) { 7556 return true; 7557 } 7558 } 7559 return false; 7560 } 7561 maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7562 private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, 7563 NetworkCapabilities newNc) { 7564 // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that 7565 // the proxy might be changed since the default network satisfied by the apps might also 7566 // changed. 7567 // TODO: Try to track the default network that apps use and only send a proxy broadcast when 7568 // that happens to prevent false alarms. 7569 if (nai.isVPN() && nai.everConnected && !NetworkCapabilities.hasSameUids(prevNc, newNc) 7570 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) { 7571 mProxyTracker.sendProxyBroadcast(); 7572 } 7573 } 7574 updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)7575 private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, 7576 NetworkCapabilities newNc) { 7577 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges(); 7578 Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges(); 7579 if (null == prevRanges) prevRanges = new ArraySet<>(); 7580 if (null == newRanges) newRanges = new ArraySet<>(); 7581 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 7582 7583 prevRanges.removeAll(newRanges); 7584 newRanges.removeAll(prevRangesCopy); 7585 7586 try { 7587 // When updating the VPN uid routing rules, add the new range first then remove the old 7588 // range. If old range were removed first, there would be a window between the old 7589 // range being removed and the new range being added, during which UIDs contained 7590 // in both ranges are not subject to any VPN routing rules. Adding new range before 7591 // removing old range works because, unlike the filtering rules below, it's possible to 7592 // add duplicate UID routing rules. 7593 // TODO: calculate the intersection of add & remove. Imagining that we are trying to 7594 // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is: 7595 // [1-5] & [1-2],[4-5] == [3] 7596 // Then we can do: 7597 // maybeCloseSockets([3]) 7598 // mNetd.networkAddUidRanges([1-2],[4-5]) 7599 // mNetd.networkRemoveUidRanges([1-5]) 7600 // maybeCloseSockets([3]) 7601 // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the 7602 // number of binder calls from 6 to 4. 7603 if (!newRanges.isEmpty()) { 7604 updateVpnUidRanges(true, nai, newRanges); 7605 } 7606 if (!prevRanges.isEmpty()) { 7607 updateVpnUidRanges(false, nai, prevRanges); 7608 } 7609 final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties); 7610 final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties); 7611 final String iface = nai.linkProperties.getInterfaceName(); 7612 // For VPN uid interface filtering, old ranges need to be removed before new ranges can 7613 // be added, due to the range being expanded and stored as individual UIDs. For example 7614 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means 7615 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges 7616 // were added first and then newRanges got removed later, there would be only one uid 7617 // 10013 left. A consequence of removing old ranges before adding new ranges is that 7618 // there is now a window of opportunity when the UIDs are not subject to any filtering. 7619 // Note that this is in contrast with the (more robust) update of VPN routing rules 7620 // above, where the addition of new ranges happens before the removal of old ranges. 7621 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range 7622 // to be removed will never overlap with the new range to be added. 7623 if (wasFiltering && !prevRanges.isEmpty()) { 7624 mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, prevNc.getOwnerUid()); 7625 } 7626 if (shouldFilter && !newRanges.isEmpty()) { 7627 mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, newNc.getOwnerUid()); 7628 } 7629 } catch (Exception e) { 7630 // Never crash! 7631 loge("Exception in updateUids: ", e); 7632 } 7633 } 7634 handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)7635 public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) { 7636 ensureRunningOnConnectivityServiceThread(); 7637 7638 if (!mNetworkAgentInfos.contains(nai)) { 7639 // Ignore updates for disconnected networks 7640 return; 7641 } 7642 if (VDBG || DDBG) { 7643 log("Update of LinkProperties for " + nai.toShortString() 7644 + "; created=" + nai.created 7645 + "; everConnected=" + nai.everConnected); 7646 } 7647 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not 7648 // modify its oldLp parameter. 7649 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties)); 7650 } 7651 sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)7652 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 7653 int notificationType) { 7654 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 7655 Intent intent = new Intent(); 7656 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 7657 // If apps could file multi-layer requests with PendingIntents, they'd need to know 7658 // which of the layer is satisfied alongside with some ID for the request. Hence, if 7659 // such an API is ever implemented, there is no doubt the right request to send in 7660 // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would 7661 // need to be sent as a separate extra. 7662 final NetworkRequest req = nri.isMultilayerRequest() 7663 ? nri.getActiveRequest() 7664 // Non-multilayer listen requests do not have an active request 7665 : nri.mRequests.get(0); 7666 if (req == null) { 7667 Log.wtf(TAG, "No request in NRI " + nri); 7668 } 7669 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req); 7670 nri.mPendingIntentSent = true; 7671 sendIntent(nri.mPendingIntent, intent); 7672 } 7673 // else not handled 7674 } 7675 sendIntent(PendingIntent pendingIntent, Intent intent)7676 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 7677 mPendingIntentWakeLock.acquire(); 7678 try { 7679 if (DBG) log("Sending " + pendingIntent); 7680 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */); 7681 } catch (PendingIntent.CanceledException e) { 7682 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 7683 mPendingIntentWakeLock.release(); 7684 releasePendingNetworkRequest(pendingIntent); 7685 } 7686 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 7687 } 7688 7689 @Override onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)7690 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 7691 String resultData, Bundle resultExtras) { 7692 if (DBG) log("Finished sending " + pendingIntent); 7693 mPendingIntentWakeLock.release(); 7694 // Release with a delay so the receiving client has an opportunity to put in its 7695 // own request. 7696 releasePendingNetworkRequestWithDelay(pendingIntent); 7697 } 7698 callCallbackForRequest(@onNull final NetworkRequestInfo nri, @NonNull final NetworkAgentInfo networkAgent, final int notificationType, final int arg1)7699 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, 7700 @NonNull final NetworkAgentInfo networkAgent, final int notificationType, 7701 final int arg1) { 7702 if (nri.mMessenger == null) { 7703 // Default request has no msgr. Also prevents callbacks from being invoked for 7704 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks 7705 // are Type.LISTEN, but should not have NetworkCallbacks invoked. 7706 return; 7707 } 7708 Bundle bundle = new Bundle(); 7709 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 7710 // TODO: check if defensive copies of data is needed. 7711 final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); 7712 putParcelable(bundle, nrForCallback); 7713 Message msg = Message.obtain(); 7714 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) { 7715 putParcelable(bundle, networkAgent.network); 7716 } 7717 final boolean includeLocationSensitiveInfo = 7718 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0; 7719 switch (notificationType) { 7720 case ConnectivityManager.CALLBACK_AVAILABLE: { 7721 final NetworkCapabilities nc = 7722 networkCapabilitiesRestrictedForCallerPermissions( 7723 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 7724 putParcelable( 7725 bundle, 7726 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 7727 nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid, 7728 nrForCallback.getRequestorPackageName(), 7729 nri.mCallingAttributionTag)); 7730 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 7731 networkAgent.linkProperties, nri.mPid, nri.mUid)); 7732 // For this notification, arg1 contains the blocked status. 7733 msg.arg1 = arg1; 7734 break; 7735 } 7736 case ConnectivityManager.CALLBACK_LOSING: { 7737 msg.arg1 = arg1; 7738 break; 7739 } 7740 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 7741 // networkAgent can't be null as it has been accessed a few lines above. 7742 final NetworkCapabilities netCap = 7743 networkCapabilitiesRestrictedForCallerPermissions( 7744 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 7745 putParcelable( 7746 bundle, 7747 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 7748 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid, 7749 nrForCallback.getRequestorPackageName(), 7750 nri.mCallingAttributionTag)); 7751 break; 7752 } 7753 case ConnectivityManager.CALLBACK_IP_CHANGED: { 7754 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 7755 networkAgent.linkProperties, nri.mPid, nri.mUid)); 7756 break; 7757 } 7758 case ConnectivityManager.CALLBACK_BLK_CHANGED: { 7759 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1); 7760 msg.arg1 = arg1; 7761 break; 7762 } 7763 } 7764 msg.what = notificationType; 7765 msg.setData(bundle); 7766 try { 7767 if (VDBG) { 7768 String notification = ConnectivityManager.getCallbackName(notificationType); 7769 log("sending notification " + notification + " for " + nrForCallback); 7770 } 7771 nri.mMessenger.send(msg); 7772 } catch (RemoteException e) { 7773 // may occur naturally in the race of binder death. 7774 loge("RemoteException caught trying to send a callback msg for " + nrForCallback); 7775 } 7776 } 7777 putParcelable(Bundle bundle, T t)7778 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 7779 bundle.putParcelable(t.getClass().getSimpleName(), t); 7780 } 7781 teardownUnneededNetwork(NetworkAgentInfo nai)7782 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 7783 if (nai.numRequestNetworkRequests() != 0) { 7784 for (int i = 0; i < nai.numNetworkRequests(); i++) { 7785 NetworkRequest nr = nai.requestAt(i); 7786 // Ignore listening and track default requests. 7787 if (!nr.isRequest()) continue; 7788 loge("Dead network still had at least " + nr); 7789 break; 7790 } 7791 } 7792 nai.disconnect(); 7793 } 7794 handleLingerComplete(NetworkAgentInfo oldNetwork)7795 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 7796 if (oldNetwork == null) { 7797 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 7798 return; 7799 } 7800 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString()); 7801 7802 // If we get here it means that the last linger timeout for this network expired. So there 7803 // must be no other active linger timers, and we must stop lingering. 7804 oldNetwork.clearInactivityState(); 7805 7806 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 7807 // Tear the network down. 7808 teardownUnneededNetwork(oldNetwork); 7809 } else { 7810 // Put the network in the background if it doesn't satisfy any foreground request. 7811 updateCapabilitiesForNetwork(oldNetwork); 7812 } 7813 } 7814 processDefaultNetworkChanges(@onNull final NetworkReassignment changes)7815 private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) { 7816 boolean isDefaultChanged = false; 7817 for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) { 7818 final NetworkReassignment.RequestReassignment reassignment = 7819 changes.getReassignment(defaultRequestInfo); 7820 if (null == reassignment) { 7821 continue; 7822 } 7823 // reassignment only contains those instances where the satisfying network changed. 7824 isDefaultChanged = true; 7825 // Notify system services of the new default. 7826 makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork); 7827 } 7828 7829 if (isDefaultChanged) { 7830 // Hold a wakelock for a short time to help apps in migrating to a new default. 7831 scheduleReleaseNetworkTransitionWakelock(); 7832 } 7833 } 7834 makeDefault(@onNull final NetworkRequestInfo nri, @Nullable final NetworkAgentInfo oldDefaultNetwork, @Nullable final NetworkAgentInfo newDefaultNetwork)7835 private void makeDefault(@NonNull final NetworkRequestInfo nri, 7836 @Nullable final NetworkAgentInfo oldDefaultNetwork, 7837 @Nullable final NetworkAgentInfo newDefaultNetwork) { 7838 if (DBG) { 7839 log("Switching to new default network for: " + nri + " using " + newDefaultNetwork); 7840 } 7841 7842 // Fix up the NetworkCapabilities of any networks that have this network as underlying. 7843 if (newDefaultNetwork != null) { 7844 propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network); 7845 } 7846 7847 // Set an app level managed default and return since further processing only applies to the 7848 // default network. 7849 if (mDefaultRequest != nri) { 7850 makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork); 7851 return; 7852 } 7853 7854 makeDefaultNetwork(newDefaultNetwork); 7855 7856 if (oldDefaultNetwork != null) { 7857 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork); 7858 } 7859 mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork); 7860 handleApplyDefaultProxy(null != newDefaultNetwork 7861 ? newDefaultNetwork.linkProperties.getHttpProxy() : null); 7862 updateTcpBufferSizes(null != newDefaultNetwork 7863 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null); 7864 notifyIfacesChangedForNetworkStats(); 7865 } 7866 makeDefaultForApps(@onNull final NetworkRequestInfo nri, @Nullable final NetworkAgentInfo oldDefaultNetwork, @Nullable final NetworkAgentInfo newDefaultNetwork)7867 private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri, 7868 @Nullable final NetworkAgentInfo oldDefaultNetwork, 7869 @Nullable final NetworkAgentInfo newDefaultNetwork) { 7870 try { 7871 if (VDBG) { 7872 log("Setting default network for " + nri 7873 + " using UIDs " + nri.getUids() 7874 + " with old network " + (oldDefaultNetwork != null 7875 ? oldDefaultNetwork.network().getNetId() : "null") 7876 + " and new network " + (newDefaultNetwork != null 7877 ? newDefaultNetwork.network().getNetId() : "null")); 7878 } 7879 if (nri.getUids().isEmpty()) { 7880 throw new IllegalStateException("makeDefaultForApps called without specifying" 7881 + " any applications to set as the default." + nri); 7882 } 7883 if (null != newDefaultNetwork) { 7884 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 7885 newDefaultNetwork.network.getNetId(), 7886 toUidRangeStableParcels(nri.getUids()), 7887 nri.getPriorityForNetd())); 7888 } 7889 if (null != oldDefaultNetwork) { 7890 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 7891 oldDefaultNetwork.network.getNetId(), 7892 toUidRangeStableParcels(nri.getUids()), 7893 nri.getPriorityForNetd())); 7894 } 7895 } catch (RemoteException | ServiceSpecificException e) { 7896 loge("Exception setting app default network", e); 7897 } 7898 } 7899 makeDefaultNetwork(@ullable final NetworkAgentInfo newDefaultNetwork)7900 private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) { 7901 try { 7902 if (null != newDefaultNetwork) { 7903 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId()); 7904 } else { 7905 mNetd.networkClearDefault(); 7906 } 7907 } catch (RemoteException | ServiceSpecificException e) { 7908 loge("Exception setting default network :" + e); 7909 } 7910 } 7911 processListenRequests(@onNull final NetworkAgentInfo nai)7912 private void processListenRequests(@NonNull final NetworkAgentInfo nai) { 7913 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 7914 processNewlyLostListenRequests(nai); 7915 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 7916 processNewlySatisfiedListenRequests(nai); 7917 } 7918 processNewlyLostListenRequests(@onNull final NetworkAgentInfo nai)7919 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) { 7920 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 7921 if (nri.isMultilayerRequest()) { 7922 continue; 7923 } 7924 final NetworkRequest nr = nri.mRequests.get(0); 7925 if (!nr.isListen()) continue; 7926 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 7927 nai.removeRequest(nr.requestId); 7928 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0); 7929 } 7930 } 7931 } 7932 processNewlySatisfiedListenRequests(@onNull final NetworkAgentInfo nai)7933 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) { 7934 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 7935 if (nri.isMultilayerRequest()) { 7936 continue; 7937 } 7938 final NetworkRequest nr = nri.mRequests.get(0); 7939 if (!nr.isListen()) continue; 7940 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 7941 nai.addRequest(nr); 7942 notifyNetworkAvailable(nai, nri); 7943 } 7944 } 7945 } 7946 7947 // An accumulator class to gather the list of changes that result from a rematch. 7948 private static class NetworkReassignment { 7949 static class RequestReassignment { 7950 @NonNull public final NetworkRequestInfo mNetworkRequestInfo; 7951 @Nullable public final NetworkRequest mOldNetworkRequest; 7952 @Nullable public final NetworkRequest mNewNetworkRequest; 7953 @Nullable public final NetworkAgentInfo mOldNetwork; 7954 @Nullable public final NetworkAgentInfo mNewNetwork; RequestReassignment(@onNull final NetworkRequestInfo networkRequestInfo, @Nullable final NetworkRequest oldNetworkRequest, @Nullable final NetworkRequest newNetworkRequest, @Nullable final NetworkAgentInfo oldNetwork, @Nullable final NetworkAgentInfo newNetwork)7955 RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo, 7956 @Nullable final NetworkRequest oldNetworkRequest, 7957 @Nullable final NetworkRequest newNetworkRequest, 7958 @Nullable final NetworkAgentInfo oldNetwork, 7959 @Nullable final NetworkAgentInfo newNetwork) { 7960 mNetworkRequestInfo = networkRequestInfo; 7961 mOldNetworkRequest = oldNetworkRequest; 7962 mNewNetworkRequest = newNetworkRequest; 7963 mOldNetwork = oldNetwork; 7964 mNewNetwork = newNetwork; 7965 } 7966 toString()7967 public String toString() { 7968 final NetworkRequest requestToShow = null != mNewNetworkRequest 7969 ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0); 7970 return requestToShow.requestId + " : " 7971 + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null") 7972 + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null"); 7973 } 7974 } 7975 7976 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>(); 7977 getRequestReassignments()7978 @NonNull Iterable<RequestReassignment> getRequestReassignments() { 7979 return mReassignments; 7980 } 7981 addRequestReassignment(@onNull final RequestReassignment reassignment)7982 void addRequestReassignment(@NonNull final RequestReassignment reassignment) { 7983 if (Build.isDebuggable()) { 7984 // The code is never supposed to add two reassignments of the same request. Make 7985 // sure this stays true, but without imposing this expensive check on all 7986 // reassignments on all user devices. 7987 for (final RequestReassignment existing : mReassignments) { 7988 if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) { 7989 throw new IllegalStateException("Trying to reassign [" 7990 + reassignment + "] but already have [" 7991 + existing + "]"); 7992 } 7993 } 7994 } 7995 mReassignments.add(reassignment); 7996 } 7997 7998 // Will return null if this reassignment does not change the network assigned to 7999 // the passed request. 8000 @Nullable getReassignment(@onNull final NetworkRequestInfo nri)8001 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) { 8002 for (final RequestReassignment event : getRequestReassignments()) { 8003 if (nri == event.mNetworkRequestInfo) return event; 8004 } 8005 return null; 8006 } 8007 toString()8008 public String toString() { 8009 final StringJoiner sj = new StringJoiner(", " /* delimiter */, 8010 "NetReassign [" /* prefix */, "]" /* suffix */); 8011 if (mReassignments.isEmpty()) return sj.add("no changes").toString(); 8012 for (final RequestReassignment rr : getRequestReassignments()) { 8013 sj.add(rr.toString()); 8014 } 8015 return sj.toString(); 8016 } 8017 debugString()8018 public String debugString() { 8019 final StringBuilder sb = new StringBuilder(); 8020 sb.append("NetworkReassignment :"); 8021 if (mReassignments.isEmpty()) return sb.append(" no changes").toString(); 8022 for (final RequestReassignment rr : getRequestReassignments()) { 8023 sb.append("\n ").append(rr); 8024 } 8025 return sb.append("\n").toString(); 8026 } 8027 } 8028 updateSatisfiersForRematchRequest(@onNull final NetworkRequestInfo nri, @Nullable final NetworkRequest previousRequest, @Nullable final NetworkRequest newRequest, @Nullable final NetworkAgentInfo previousSatisfier, @Nullable final NetworkAgentInfo newSatisfier, final long now)8029 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri, 8030 @Nullable final NetworkRequest previousRequest, 8031 @Nullable final NetworkRequest newRequest, 8032 @Nullable final NetworkAgentInfo previousSatisfier, 8033 @Nullable final NetworkAgentInfo newSatisfier, 8034 final long now) { 8035 if (null != newSatisfier && mNoServiceNetwork != newSatisfier) { 8036 if (VDBG) log("rematch for " + newSatisfier.toShortString()); 8037 if (null != previousRequest && null != previousSatisfier) { 8038 if (VDBG || DDBG) { 8039 log(" accepting network in place of " + previousSatisfier.toShortString()); 8040 } 8041 previousSatisfier.removeRequest(previousRequest.requestId); 8042 previousSatisfier.lingerRequest(previousRequest.requestId, now); 8043 } else { 8044 if (VDBG || DDBG) log(" accepting network in place of null"); 8045 } 8046 8047 // To prevent constantly CPU wake up for nascent timer, if a network comes up 8048 // and immediately satisfies a request then remove the timer. This will happen for 8049 // all networks except in the case of an underlying network for a VCN. 8050 if (newSatisfier.isNascent()) { 8051 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE); 8052 newSatisfier.unsetInactive(); 8053 } 8054 8055 // if newSatisfier is not null, then newRequest may not be null. 8056 newSatisfier.unlingerRequest(newRequest.requestId); 8057 if (!newSatisfier.addRequest(newRequest)) { 8058 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has " 8059 + newRequest); 8060 } 8061 } else if (null != previousRequest && null != previousSatisfier) { 8062 if (DBG) { 8063 log("Network " + previousSatisfier.toShortString() + " stopped satisfying" 8064 + " request " + previousRequest.requestId); 8065 } 8066 previousSatisfier.removeRequest(previousRequest.requestId); 8067 } 8068 nri.setSatisfier(newSatisfier, newRequest); 8069 } 8070 8071 /** 8072 * This function is triggered when something can affect what network should satisfy what 8073 * request, and it computes the network reassignment from the passed collection of requests to 8074 * network match to the one that the system should now have. That data is encoded in an 8075 * object that is a list of changes, each of them having an NRI, and old satisfier, and a new 8076 * satisfier. 8077 * 8078 * After the reassignment is computed, it is applied to the state objects. 8079 * 8080 * @param networkRequests the nri objects to evaluate for possible network reassignment 8081 * @return NetworkReassignment listing of proposed network assignment changes 8082 */ 8083 @NonNull computeNetworkReassignment( @onNull final Collection<NetworkRequestInfo> networkRequests)8084 private NetworkReassignment computeNetworkReassignment( 8085 @NonNull final Collection<NetworkRequestInfo> networkRequests) { 8086 final NetworkReassignment changes = new NetworkReassignment(); 8087 8088 // Gather the list of all relevant agents. 8089 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>(); 8090 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 8091 if (!nai.everConnected) { 8092 continue; 8093 } 8094 nais.add(nai); 8095 } 8096 8097 for (final NetworkRequestInfo nri : networkRequests) { 8098 // Non-multilayer listen requests can be ignored. 8099 if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) { 8100 continue; 8101 } 8102 NetworkAgentInfo bestNetwork = null; 8103 NetworkRequest bestRequest = null; 8104 for (final NetworkRequest req : nri.mRequests) { 8105 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier()); 8106 // Stop evaluating as the highest possible priority request is satisfied. 8107 if (null != bestNetwork) { 8108 bestRequest = req; 8109 break; 8110 } 8111 } 8112 if (null == bestNetwork && isDefaultBlocked(nri)) { 8113 // Remove default networking if disallowed for managed default requests. 8114 bestNetwork = mNoServiceNetwork; 8115 } 8116 if (nri.getSatisfier() != bestNetwork) { 8117 // bestNetwork may be null if no network can satisfy this request. 8118 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( 8119 nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork)); 8120 } 8121 } 8122 return changes; 8123 } 8124 getNrisFromGlobalRequests()8125 private Set<NetworkRequestInfo> getNrisFromGlobalRequests() { 8126 return new HashSet<>(mNetworkRequests.values()); 8127 } 8128 8129 /** 8130 * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks 8131 * being disconnected. 8132 */ rematchAllNetworksAndRequests()8133 private void rematchAllNetworksAndRequests() { 8134 rematchNetworksAndRequests(getNrisFromGlobalRequests()); 8135 } 8136 8137 /** 8138 * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks 8139 * being disconnected. 8140 */ rematchNetworksAndRequests( @onNull final Set<NetworkRequestInfo> networkRequests)8141 private void rematchNetworksAndRequests( 8142 @NonNull final Set<NetworkRequestInfo> networkRequests) { 8143 ensureRunningOnConnectivityServiceThread(); 8144 // TODO: This may be slow, and should be optimized. 8145 final long now = SystemClock.elapsedRealtime(); 8146 final NetworkReassignment changes = computeNetworkReassignment(networkRequests); 8147 if (VDBG || DDBG) { 8148 log(changes.debugString()); 8149 } else if (DBG) { 8150 log(changes.toString()); // Shorter form, only one line of log 8151 } 8152 applyNetworkReassignment(changes, now); 8153 issueNetworkNeeds(); 8154 } 8155 applyNetworkReassignment(@onNull final NetworkReassignment changes, final long now)8156 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes, 8157 final long now) { 8158 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos; 8159 8160 // Since most of the time there are only 0 or 1 background networks, it would probably 8161 // be more efficient to just use an ArrayList here. TODO : measure performance 8162 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>(); 8163 for (final NetworkAgentInfo nai : nais) { 8164 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai); 8165 } 8166 8167 // First, update the lists of satisfied requests in the network agents. This is necessary 8168 // because some code later depends on this state to be correct, most prominently computing 8169 // the linger status. 8170 for (final NetworkReassignment.RequestReassignment event : 8171 changes.getRequestReassignments()) { 8172 updateSatisfiersForRematchRequest(event.mNetworkRequestInfo, 8173 event.mOldNetworkRequest, event.mNewNetworkRequest, 8174 event.mOldNetwork, event.mNewNetwork, 8175 now); 8176 } 8177 8178 // Process default network changes if applicable. 8179 processDefaultNetworkChanges(changes); 8180 8181 // Notify requested networks are available after the default net is switched, but 8182 // before LegacyTypeTracker sends legacy broadcasts 8183 for (final NetworkReassignment.RequestReassignment event : 8184 changes.getRequestReassignments()) { 8185 if (null != event.mNewNetwork) { 8186 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo); 8187 } else { 8188 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork, 8189 ConnectivityManager.CALLBACK_LOST, 0); 8190 } 8191 } 8192 8193 // Update the inactivity state before processing listen callbacks, because the background 8194 // computation depends on whether the network is inactive. Don't send the LOSING callbacks 8195 // just yet though, because they have to be sent after the listens are processed to keep 8196 // backward compatibility. 8197 final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>(); 8198 for (final NetworkAgentInfo nai : nais) { 8199 // Rematching may have altered the inactivity state of some networks, so update all 8200 // inactivity timers. updateInactivityState reads the state from the network agent 8201 // and does nothing if the state has not changed : the source of truth is controlled 8202 // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which 8203 // have been called while rematching the individual networks above. 8204 if (updateInactivityState(nai, now)) { 8205 inactiveNetworks.add(nai); 8206 } 8207 } 8208 8209 for (final NetworkAgentInfo nai : nais) { 8210 if (!nai.everConnected) continue; 8211 final boolean oldBackground = oldBgNetworks.contains(nai); 8212 // Process listen requests and update capabilities if the background state has 8213 // changed for this network. For consistency with previous behavior, send onLost 8214 // callbacks before onAvailable. 8215 processNewlyLostListenRequests(nai); 8216 if (oldBackground != nai.isBackgroundNetwork()) { 8217 applyBackgroundChangeForRematch(nai); 8218 } 8219 processNewlySatisfiedListenRequests(nai); 8220 } 8221 8222 for (final NetworkAgentInfo nai : inactiveNetworks) { 8223 // For nascent networks, if connecting with no foreground request, skip broadcasting 8224 // LOSING for backward compatibility. This is typical when mobile data connected while 8225 // wifi connected with mobile data always-on enabled. 8226 if (nai.isNascent()) continue; 8227 notifyNetworkLosing(nai, now); 8228 } 8229 8230 updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais); 8231 8232 // Tear down all unneeded networks. 8233 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 8234 if (unneeded(nai, UnneededFor.TEARDOWN)) { 8235 if (nai.getInactivityExpiry() > 0) { 8236 // This network has active linger timers and no requests, but is not 8237 // lingering. Linger it. 8238 // 8239 // One way (the only way?) this can happen if this network is unvalidated 8240 // and became unneeded due to another network improving its score to the 8241 // point where this network will no longer be able to satisfy any requests 8242 // even if it validates. 8243 if (updateInactivityState(nai, now)) { 8244 notifyNetworkLosing(nai, now); 8245 } 8246 } else { 8247 if (DBG) log("Reaping " + nai.toShortString()); 8248 teardownUnneededNetwork(nai); 8249 } 8250 } 8251 } 8252 } 8253 8254 /** 8255 * Apply a change in background state resulting from rematching networks with requests. 8256 * 8257 * During rematch, a network may change background states by starting to satisfy or stopping 8258 * to satisfy a foreground request. Listens don't count for this. When a network changes 8259 * background states, its capabilities need to be updated and callbacks fired for the 8260 * capability change. 8261 * 8262 * @param nai The network that changed background states 8263 */ applyBackgroundChangeForRematch(@onNull final NetworkAgentInfo nai)8264 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) { 8265 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities); 8266 if (Objects.equals(nai.networkCapabilities, newNc)) return; 8267 updateNetworkPermissions(nai, newNc); 8268 nai.getAndSetNetworkCapabilities(newNc); 8269 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 8270 } 8271 updateLegacyTypeTrackerAndVpnLockdownForRematch( @onNull final NetworkReassignment changes, @NonNull final Collection<NetworkAgentInfo> nais)8272 private void updateLegacyTypeTrackerAndVpnLockdownForRematch( 8273 @NonNull final NetworkReassignment changes, 8274 @NonNull final Collection<NetworkAgentInfo> nais) { 8275 final NetworkReassignment.RequestReassignment reassignmentOfDefault = 8276 changes.getReassignment(mDefaultRequest); 8277 final NetworkAgentInfo oldDefaultNetwork = 8278 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null; 8279 final NetworkAgentInfo newDefaultNetwork = 8280 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null; 8281 8282 if (oldDefaultNetwork != newDefaultNetwork) { 8283 // Maintain the illusion : since the legacy API only understands one network at a time, 8284 // if the default network changed, apps should see a disconnected broadcast for the 8285 // old default network before they see a connected broadcast for the new one. 8286 if (oldDefaultNetwork != null) { 8287 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 8288 oldDefaultNetwork, true); 8289 } 8290 if (newDefaultNetwork != null) { 8291 // The new default network can be newly null if and only if the old default 8292 // network doesn't satisfy the default request any more because it lost a 8293 // capability. 8294 mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0; 8295 mLegacyTypeTracker.add( 8296 newDefaultNetwork.networkInfo.getType(), newDefaultNetwork); 8297 } 8298 } 8299 8300 // Now that all the callbacks have been sent, send the legacy network broadcasts 8301 // as needed. This is necessary so that legacy requests correctly bind dns 8302 // requests to this network. The legacy users are listening for this broadcast 8303 // and will generally do a dns request so they can ensureRouteToHost and if 8304 // they do that before the callbacks happen they'll use the default network. 8305 // 8306 // TODO: Is there still a race here? The legacy broadcast will be sent after sending 8307 // callbacks, but if apps can receive the broadcast before the callback, they still might 8308 // have an inconsistent view of networking. 8309 // 8310 // This *does* introduce a race where if the user uses the new api 8311 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 8312 // they may get old info. Reverse this after the old startUsing api is removed. 8313 // This is on top of the multiple intent sequencing referenced in the todo above. 8314 for (NetworkAgentInfo nai : nais) { 8315 if (nai.everConnected) { 8316 addNetworkToLegacyTypeTracker(nai); 8317 } 8318 } 8319 } 8320 issueNetworkNeeds()8321 private void issueNetworkNeeds() { 8322 ensureRunningOnConnectivityServiceThread(); 8323 for (final NetworkOfferInfo noi : mNetworkOffers) { 8324 issueNetworkNeeds(noi); 8325 } 8326 } 8327 issueNetworkNeeds(@onNull final NetworkOfferInfo noi)8328 private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) { 8329 ensureRunningOnConnectivityServiceThread(); 8330 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 8331 informOffer(nri, noi.offer, mNetworkRanker); 8332 } 8333 } 8334 8335 /** 8336 * Inform a NetworkOffer about any new situation of a request. 8337 * 8338 * This function handles updates to offers. A number of events may happen that require 8339 * updating the registrant for this offer about the situation : 8340 * • The offer itself was updated. This may lead the offer to no longer being able 8341 * to satisfy a request or beat a satisfier (and therefore be no longer needed), 8342 * or conversely being strengthened enough to beat the satisfier (and therefore 8343 * start being needed) 8344 * • The network satisfying a request changed (including cases where the request 8345 * starts or stops being satisfied). The new network may be a stronger or weaker 8346 * match than the old one, possibly affecting whether the offer is needed. 8347 * • The network satisfying a request updated their score. This may lead the offer 8348 * to no longer be able to beat it if the current satisfier got better, or 8349 * conversely start being a good choice if the current satisfier got weaker. 8350 * 8351 * @param nri The request 8352 * @param offer The offer. This may be an updated offer. 8353 */ informOffer(@onNull NetworkRequestInfo nri, @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker)8354 private static void informOffer(@NonNull NetworkRequestInfo nri, 8355 @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) { 8356 final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null; 8357 final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null; 8358 8359 // Multi-layer requests have a currently active request, the one being satisfied. 8360 // Since the system will try to bring up a better network than is currently satisfying 8361 // the request, NetworkProviders need to be told the offers matching the requests *above* 8362 // the currently satisfied one are needed, that the ones *below* the satisfied one are 8363 // not needed, and the offer is needed for the active request iff the offer can beat 8364 // the satisfier. 8365 // For non-multilayer requests, the logic above gracefully degenerates to only the 8366 // last case. 8367 // To achieve this, the loop below will proceed in three steps. In a first phase, inform 8368 // providers that the offer is needed for this request, until the active request is found. 8369 // In a second phase, deal with the currently active request. In a third phase, inform 8370 // the providers that offer is unneeded for the remaining requests. 8371 8372 // First phase : inform providers of all requests above the active request. 8373 int i; 8374 for (i = 0; nri.mRequests.size() > i; ++i) { 8375 final NetworkRequest request = nri.mRequests.get(i); 8376 if (activeRequest == request) break; // Found the active request : go to phase 2 8377 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 8378 // Since this request is higher-priority than the one currently satisfied, if the 8379 // offer can satisfy it, the provider should try and bring up the network for sure ; 8380 // no need to even ask the ranker – an offer that can satisfy is always better than 8381 // no network. Hence tell the provider so unless it already knew. 8382 if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) { 8383 offer.onNetworkNeeded(request); 8384 } 8385 } 8386 8387 // Second phase : deal with the active request (if any) 8388 if (null != activeRequest && activeRequest.isRequest()) { 8389 final boolean oldNeeded = offer.neededFor(activeRequest); 8390 // If an offer can satisfy the request, it is considered needed if it is currently 8391 // served by this provider or if this offer can beat the current satisfier. 8392 final boolean currentlyServing = satisfier != null 8393 && satisfier.factorySerialNumber == offer.providerId 8394 && activeRequest.canBeSatisfiedBy(offer.caps); 8395 final boolean newNeeded = currentlyServing 8396 || networkRanker.mightBeat(activeRequest, satisfier, offer); 8397 if (newNeeded != oldNeeded) { 8398 if (newNeeded) { 8399 offer.onNetworkNeeded(activeRequest); 8400 } else { 8401 // The offer used to be able to beat the satisfier. Now it can't. 8402 offer.onNetworkUnneeded(activeRequest); 8403 } 8404 } 8405 } 8406 8407 // Third phase : inform the providers that the offer isn't needed for any request 8408 // below the active one. 8409 for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) { 8410 final NetworkRequest request = nri.mRequests.get(i); 8411 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 8412 // Since this request is lower-priority than the one currently satisfied, if the 8413 // offer can satisfy it, the provider should not try and bring up the network. 8414 // Hence tell the provider so unless it already knew. 8415 if (offer.neededFor(request)) { 8416 offer.onNetworkUnneeded(request); 8417 } 8418 } 8419 } 8420 addNetworkToLegacyTypeTracker(@onNull final NetworkAgentInfo nai)8421 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) { 8422 for (int i = 0; i < nai.numNetworkRequests(); i++) { 8423 NetworkRequest nr = nai.requestAt(i); 8424 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 8425 // legacy type tracker filters out repeat adds 8426 mLegacyTypeTracker.add(nr.legacyType, nai); 8427 } 8428 } 8429 8430 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 8431 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 8432 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 8433 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 8434 if (nai.isVPN()) { 8435 mLegacyTypeTracker.add(TYPE_VPN, nai); 8436 } 8437 } 8438 updateInetCondition(NetworkAgentInfo nai)8439 private void updateInetCondition(NetworkAgentInfo nai) { 8440 // Don't bother updating until we've graduated to validated at least once. 8441 if (!nai.everValidated) return; 8442 // For now only update icons for the default connection. 8443 // TODO: Update WiFi and cellular icons separately. b/17237507 8444 if (!isDefaultNetwork(nai)) return; 8445 8446 int newInetCondition = nai.lastValidated ? 100 : 0; 8447 // Don't repeat publish. 8448 if (newInetCondition == mDefaultInetConditionPublished) return; 8449 8450 mDefaultInetConditionPublished = newInetCondition; 8451 sendInetConditionBroadcast(nai.networkInfo); 8452 } 8453 8454 @NonNull mixInInfo(@onNull final NetworkAgentInfo nai, @NonNull NetworkInfo info)8455 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) { 8456 final NetworkInfo newInfo = new NetworkInfo(info); 8457 // The suspended and roaming bits are managed in NetworkCapabilities. 8458 final boolean suspended = 8459 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 8460 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) { 8461 // Only override the state with SUSPENDED if the network is currently in CONNECTED 8462 // state. This is because the network could have been suspended before connecting, 8463 // or it could be disconnecting while being suspended, and in both these cases 8464 // the state should not be overridden. Note that the only detailed state that 8465 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to 8466 // worry about multiple different substates of CONNECTED. 8467 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(), 8468 info.getExtraInfo()); 8469 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) { 8470 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the 8471 // network agent is created, then goes to suspended, then goes out of suspended without 8472 // ever setting connected. Check if network agent is ever connected to update the state. 8473 newInfo.setDetailedState(nai.everConnected 8474 ? NetworkInfo.DetailedState.CONNECTED 8475 : NetworkInfo.DetailedState.CONNECTING, 8476 info.getReason(), 8477 info.getExtraInfo()); 8478 } 8479 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 8480 return newInfo; 8481 } 8482 updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info)8483 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) { 8484 final NetworkInfo newInfo = mixInInfo(networkAgent, info); 8485 8486 final NetworkInfo.State state = newInfo.getState(); 8487 NetworkInfo oldInfo = null; 8488 synchronized (networkAgent) { 8489 oldInfo = networkAgent.networkInfo; 8490 networkAgent.networkInfo = newInfo; 8491 } 8492 8493 if (DBG) { 8494 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from " 8495 + oldInfo.getState() + " to " + state); 8496 } 8497 8498 if (!networkAgent.created 8499 && (state == NetworkInfo.State.CONNECTED 8500 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { 8501 8502 // A network that has just connected has zero requests and is thus a foreground network. 8503 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 8504 8505 if (!createNativeNetwork(networkAgent)) return; 8506 if (networkAgent.propagateUnderlyingCapabilities()) { 8507 // Initialize the network's capabilities to their starting values according to the 8508 // underlying networks. This ensures that the capabilities are correct before 8509 // anything happens to the network. 8510 updateCapabilitiesForNetwork(networkAgent); 8511 } 8512 networkAgent.created = true; 8513 networkAgent.onNetworkCreated(); 8514 } 8515 8516 if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) { 8517 networkAgent.everConnected = true; 8518 8519 // NetworkCapabilities need to be set before sending the private DNS config to 8520 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required. 8521 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities); 8522 8523 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 8524 updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties), 8525 null); 8526 8527 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect 8528 // command must be sent after updating LinkProperties to maximize chances of 8529 // NetworkMonitor seeing the correct LinkProperties when starting. 8530 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call. 8531 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) { 8532 networkAgent.networkMonitor().setAcceptPartialConnectivity(); 8533 } 8534 networkAgent.networkMonitor().notifyNetworkConnected( 8535 new LinkProperties(networkAgent.linkProperties, 8536 true /* parcelSensitiveFields */), 8537 networkAgent.networkCapabilities); 8538 scheduleUnvalidatedPrompt(networkAgent); 8539 8540 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 8541 // be communicated to a particular NetworkAgent depends only on the network's immutable, 8542 // capabilities, so it only needs to be done once on initial connect, not every time the 8543 // network's capabilities change. Note that we do this before rematching the network, 8544 // so we could decide to tear it down immediately afterwards. That's fine though - on 8545 // disconnection NetworkAgents should stop any signal strength monitoring they have been 8546 // doing. 8547 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 8548 8549 // Before first rematching networks, put an inactivity timer without any request, this 8550 // allows {@code updateInactivityState} to update the state accordingly and prevent 8551 // tearing down for any {@code unneeded} evaluation in this period. 8552 // Note that the timer will not be rescheduled since the expiry time is 8553 // fixed after connection regardless of the network satisfying other requests or not. 8554 // But it will be removed as soon as the network satisfies a request for the first time. 8555 networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE, 8556 SystemClock.elapsedRealtime(), mNascentDelayMs); 8557 networkAgent.setInactive(); 8558 8559 // Consider network even though it is not yet validated. 8560 rematchAllNetworksAndRequests(); 8561 8562 // This has to happen after matching the requests, because callbacks are just requests. 8563 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 8564 } else if (state == NetworkInfo.State.DISCONNECTED) { 8565 networkAgent.disconnect(); 8566 if (networkAgent.isVPN()) { 8567 updateUids(networkAgent, networkAgent.networkCapabilities, null); 8568 } 8569 disconnectAndDestroyNetwork(networkAgent); 8570 if (networkAgent.isVPN()) { 8571 // As the active or bound network changes for apps, broadcast the default proxy, as 8572 // apps may need to update their proxy data. This is called after disconnecting from 8573 // VPN to make sure we do not broadcast the old proxy data. 8574 // TODO(b/122649188): send the broadcast only to VPN users. 8575 mProxyTracker.sendProxyBroadcast(); 8576 } 8577 } else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED || 8578 state == NetworkInfo.State.SUSPENDED)) { 8579 mLegacyTypeTracker.update(networkAgent); 8580 } 8581 } 8582 updateNetworkScore(@onNull final NetworkAgentInfo nai, final NetworkScore score)8583 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { 8584 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); 8585 nai.setScore(score); 8586 rematchAllNetworksAndRequests(); 8587 } 8588 8589 // Notify only this one new request of the current state. Transfer all the 8590 // current state by calling NetworkCapabilities and LinkProperties callbacks 8591 // so that callers can be guaranteed to have as close to atomicity in state 8592 // transfer as can be supported by this current API. notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)8593 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 8594 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 8595 if (nri.mPendingIntent != null) { 8596 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE); 8597 // Attempt no subsequent state pushes where intents are involved. 8598 return; 8599 } 8600 8601 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 8602 final boolean metered = nai.networkCapabilities.isMetered(); 8603 final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges); 8604 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 8605 getBlockedState(blockedReasons, metered, vpnBlocked)); 8606 } 8607 8608 // Notify the requests on this NAI that the network is now lingered. notifyNetworkLosing(@onNull final NetworkAgentInfo nai, final long now)8609 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) { 8610 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 8611 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 8612 } 8613 getBlockedState(int reasons, boolean metered, boolean vpnBlocked)8614 private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) { 8615 if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK; 8616 return vpnBlocked 8617 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN 8618 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN; 8619 } 8620 setUidBlockedReasons(int uid, @BlockedReason int blockedReasons)8621 private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) { 8622 if (blockedReasons == BLOCKED_REASON_NONE) { 8623 mUidBlockedReasons.delete(uid); 8624 } else { 8625 mUidBlockedReasons.put(uid, blockedReasons); 8626 } 8627 } 8628 8629 /** 8630 * Notify of the blocked state apps with a registered callback matching a given NAI. 8631 * 8632 * Unlike other callbacks, blocked status is different between each individual uid. So for 8633 * any given nai, all requests need to be considered according to the uid who filed it. 8634 * 8635 * @param nai The target NetworkAgentInfo. 8636 * @param oldMetered True if the previous network capabilities were metered. 8637 * @param newMetered True if the current network capabilities are metered. 8638 * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN. 8639 * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN. 8640 */ maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, boolean newMetered, List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges)8641 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, 8642 boolean newMetered, List<UidRange> oldBlockedUidRanges, 8643 List<UidRange> newBlockedUidRanges) { 8644 8645 for (int i = 0; i < nai.numNetworkRequests(); i++) { 8646 NetworkRequest nr = nai.requestAt(i); 8647 NetworkRequestInfo nri = mNetworkRequests.get(nr); 8648 8649 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 8650 final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges); 8651 final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges) 8652 ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges) 8653 : oldVpnBlocked; 8654 8655 final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked); 8656 final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked); 8657 if (oldBlockedState != newBlockedState) { 8658 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 8659 newBlockedState); 8660 } 8661 } 8662 } 8663 8664 /** 8665 * Notify apps with a given UID of the new blocked state according to new uid state. 8666 * @param uid The uid for which the rules changed. 8667 * @param blockedReasons The reasons for why an uid is blocked. 8668 */ maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons)8669 private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) { 8670 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 8671 final boolean metered = nai.networkCapabilities.isMetered(); 8672 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); 8673 8674 final int oldBlockedState = getBlockedState( 8675 mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked); 8676 final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked); 8677 if (oldBlockedState == newBlockedState) { 8678 continue; 8679 } 8680 for (int i = 0; i < nai.numNetworkRequests(); i++) { 8681 NetworkRequest nr = nai.requestAt(i); 8682 NetworkRequestInfo nri = mNetworkRequests.get(nr); 8683 if (nri != null && nri.mAsUid == uid) { 8684 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 8685 newBlockedState); 8686 } 8687 } 8688 } 8689 } 8690 8691 @VisibleForTesting sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)8692 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 8693 // The NetworkInfo we actually send out has no bearing on the real 8694 // state of affairs. For example, if the default connection is mobile, 8695 // and a request for HIPRI has just gone away, we need to pretend that 8696 // HIPRI has just disconnected. So we need to set the type to HIPRI and 8697 // the state to DISCONNECTED, even though the network is of type MOBILE 8698 // and is still connected. 8699 NetworkInfo info = new NetworkInfo(nai.networkInfo); 8700 info.setType(type); 8701 filterForLegacyLockdown(info); 8702 if (state != DetailedState.DISCONNECTED) { 8703 info.setDetailedState(state, null, info.getExtraInfo()); 8704 sendConnectedBroadcast(info); 8705 } else { 8706 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 8707 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 8708 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 8709 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 8710 if (info.isFailover()) { 8711 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 8712 nai.networkInfo.setFailover(false); 8713 } 8714 if (info.getReason() != null) { 8715 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 8716 } 8717 if (info.getExtraInfo() != null) { 8718 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 8719 } 8720 NetworkAgentInfo newDefaultAgent = null; 8721 if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { 8722 newDefaultAgent = mDefaultRequest.getSatisfier(); 8723 if (newDefaultAgent != null) { 8724 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 8725 newDefaultAgent.networkInfo); 8726 } else { 8727 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 8728 } 8729 } 8730 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 8731 mDefaultInetConditionPublished); 8732 sendStickyBroadcast(intent); 8733 if (newDefaultAgent != null) { 8734 sendConnectedBroadcast(newDefaultAgent.networkInfo); 8735 } 8736 } 8737 } 8738 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)8739 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 8740 if (VDBG || DDBG) { 8741 String notification = ConnectivityManager.getCallbackName(notifyType); 8742 log("notifyType " + notification + " for " + networkAgent.toShortString()); 8743 } 8744 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 8745 NetworkRequest nr = networkAgent.requestAt(i); 8746 NetworkRequestInfo nri = mNetworkRequests.get(nr); 8747 if (VDBG) log(" sending notification for " + nr); 8748 if (nri.mPendingIntent == null) { 8749 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 8750 } else { 8751 sendPendingIntentForRequest(nri, networkAgent, notifyType); 8752 } 8753 } 8754 } 8755 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)8756 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 8757 notifyNetworkCallbacks(networkAgent, notifyType, 0); 8758 } 8759 8760 /** 8761 * Returns the list of all interfaces that could be used by network traffic that does not 8762 * explicitly specify a network. This includes the default network, but also all VPNs that are 8763 * currently connected. 8764 * 8765 * Must be called on the handler thread. 8766 */ 8767 @NonNull getDefaultNetworks()8768 private ArrayList<Network> getDefaultNetworks() { 8769 ensureRunningOnConnectivityServiceThread(); 8770 final ArrayList<Network> defaultNetworks = new ArrayList<>(); 8771 final Set<Integer> activeNetIds = new ArraySet<>(); 8772 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 8773 if (nri.isBeingSatisfied()) { 8774 activeNetIds.add(nri.getSatisfier().network().netId); 8775 } 8776 } 8777 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 8778 if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) { 8779 defaultNetworks.add(nai.network); 8780 } 8781 } 8782 return defaultNetworks; 8783 } 8784 8785 /** 8786 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 8787 * active iface's tracked properties has changed. 8788 */ notifyIfacesChangedForNetworkStats()8789 private void notifyIfacesChangedForNetworkStats() { 8790 ensureRunningOnConnectivityServiceThread(); 8791 String activeIface = null; 8792 LinkProperties activeLinkProperties = getActiveLinkProperties(); 8793 if (activeLinkProperties != null) { 8794 activeIface = activeLinkProperties.getInterfaceName(); 8795 } 8796 8797 final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo(); 8798 try { 8799 final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>(); 8800 for (final NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) { 8801 snapshots.add(snapshot); 8802 } 8803 mStatsManager.notifyNetworkStatus(getDefaultNetworks(), 8804 snapshots, activeIface, Arrays.asList(underlyingNetworkInfos)); 8805 } catch (Exception ignored) { 8806 } 8807 } 8808 8809 @Override getCaptivePortalServerUrl()8810 public String getCaptivePortalServerUrl() { 8811 enforceNetworkStackOrSettingsPermission(); 8812 String settingUrl = mResources.get().getString( 8813 R.string.config_networkCaptivePortalServerUrl); 8814 8815 if (!TextUtils.isEmpty(settingUrl)) { 8816 return settingUrl; 8817 } 8818 8819 settingUrl = Settings.Global.getString(mContext.getContentResolver(), 8820 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL); 8821 if (!TextUtils.isEmpty(settingUrl)) { 8822 return settingUrl; 8823 } 8824 8825 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL; 8826 } 8827 8828 @Override startNattKeepalive(Network network, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr)8829 public void startNattKeepalive(Network network, int intervalSeconds, 8830 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { 8831 enforceKeepalivePermission(); 8832 mKeepaliveTracker.startNattKeepalive( 8833 getNetworkAgentInfoForNetwork(network), null /* fd */, 8834 intervalSeconds, cb, 8835 srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT); 8836 } 8837 8838 @Override startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr)8839 public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, 8840 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, 8841 String dstAddr) { 8842 try { 8843 final FileDescriptor fd = pfd.getFileDescriptor(); 8844 mKeepaliveTracker.startNattKeepalive( 8845 getNetworkAgentInfoForNetwork(network), fd, resourceId, 8846 intervalSeconds, cb, 8847 srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT); 8848 } finally { 8849 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 8850 // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately. 8851 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 8852 IoUtils.closeQuietly(pfd); 8853 } 8854 } 8855 } 8856 8857 @Override startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, ISocketKeepaliveCallback cb)8858 public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, 8859 ISocketKeepaliveCallback cb) { 8860 try { 8861 enforceKeepalivePermission(); 8862 final FileDescriptor fd = pfd.getFileDescriptor(); 8863 mKeepaliveTracker.startTcpKeepalive( 8864 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); 8865 } finally { 8866 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 8867 // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately. 8868 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 8869 IoUtils.closeQuietly(pfd); 8870 } 8871 } 8872 } 8873 8874 @Override stopKeepalive(Network network, int slot)8875 public void stopKeepalive(Network network, int slot) { 8876 mHandler.sendMessage(mHandler.obtainMessage( 8877 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network)); 8878 } 8879 8880 @Override factoryReset()8881 public void factoryReset() { 8882 enforceSettingsPermission(); 8883 8884 final int uid = mDeps.getCallingUid(); 8885 final long token = Binder.clearCallingIdentity(); 8886 try { 8887 if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET, 8888 UserHandle.getUserHandleForUid(uid))) { 8889 return; 8890 } 8891 8892 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext); 8893 ipMemoryStore.factoryReset(); 8894 8895 // Turn airplane mode off 8896 setAirplaneMode(false); 8897 8898 // restore private DNS settings to default mode (opportunistic) 8899 if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, 8900 UserHandle.getUserHandleForUid(uid))) { 8901 ConnectivitySettingsManager.setPrivateDnsMode(mContext, 8902 PRIVATE_DNS_MODE_OPPORTUNISTIC); 8903 } 8904 8905 Settings.Global.putString(mContext.getContentResolver(), 8906 ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 8907 } finally { 8908 Binder.restoreCallingIdentity(token); 8909 } 8910 } 8911 8912 @Override getNetworkWatchlistConfigHash()8913 public byte[] getNetworkWatchlistConfigHash() { 8914 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 8915 if (nwm == null) { 8916 loge("Unable to get NetworkWatchlistManager"); 8917 return null; 8918 } 8919 // Redirect it to network watchlist service to access watchlist file and calculate hash. 8920 return nwm.getWatchlistConfigHash(); 8921 } 8922 logNetworkEvent(NetworkAgentInfo nai, int evtype)8923 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 8924 int[] transports = nai.networkCapabilities.getTransportTypes(); 8925 mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype)); 8926 } 8927 toBool(int encodedBoolean)8928 private static boolean toBool(int encodedBoolean) { 8929 return encodedBoolean != 0; // Only 0 means false. 8930 } 8931 encodeBool(boolean b)8932 private static int encodeBool(boolean b) { 8933 return b ? 1 : 0; 8934 } 8935 8936 @Override handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)8937 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 8938 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 8939 @NonNull String[] args) { 8940 return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 8941 err.getFileDescriptor(), args); 8942 } 8943 8944 private class ShellCmd extends BasicShellCommandHandler { 8945 @Override onCommand(String cmd)8946 public int onCommand(String cmd) { 8947 if (cmd == null) { 8948 return handleDefaultCommands(cmd); 8949 } 8950 final PrintWriter pw = getOutPrintWriter(); 8951 try { 8952 switch (cmd) { 8953 case "airplane-mode": 8954 final String action = getNextArg(); 8955 if ("enable".equals(action)) { 8956 setAirplaneMode(true); 8957 return 0; 8958 } else if ("disable".equals(action)) { 8959 setAirplaneMode(false); 8960 return 0; 8961 } else if (action == null) { 8962 final ContentResolver cr = mContext.getContentResolver(); 8963 final int enabled = Settings.Global.getInt(cr, 8964 Settings.Global.AIRPLANE_MODE_ON); 8965 pw.println(enabled == 0 ? "disabled" : "enabled"); 8966 return 0; 8967 } else { 8968 onHelp(); 8969 return -1; 8970 } 8971 default: 8972 return handleDefaultCommands(cmd); 8973 } 8974 } catch (Exception e) { 8975 pw.println(e); 8976 } 8977 return -1; 8978 } 8979 8980 @Override onHelp()8981 public void onHelp() { 8982 PrintWriter pw = getOutPrintWriter(); 8983 pw.println("Connectivity service commands:"); 8984 pw.println(" help"); 8985 pw.println(" Print this help text."); 8986 pw.println(" airplane-mode [enable|disable]"); 8987 pw.println(" Turn airplane mode on or off."); 8988 pw.println(" airplane-mode"); 8989 pw.println(" Get airplane mode."); 8990 } 8991 } 8992 getVpnType(@ullable NetworkAgentInfo vpn)8993 private int getVpnType(@Nullable NetworkAgentInfo vpn) { 8994 if (vpn == null) return VpnManager.TYPE_VPN_NONE; 8995 final TransportInfo ti = vpn.networkCapabilities.getTransportInfo(); 8996 if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE; 8997 return ((VpnTransportInfo) ti).getType(); 8998 } 8999 9000 /** 9001 * @param connectionInfo the connection to resolve. 9002 * @return {@code uid} if the connection is found and the app has permission to observe it 9003 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the 9004 * connection is not found. 9005 */ getConnectionOwnerUid(ConnectionInfo connectionInfo)9006 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { 9007 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { 9008 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); 9009 } 9010 9011 final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol, 9012 connectionInfo.local, connectionInfo.remote); 9013 9014 if (uid == INVALID_UID) return uid; // Not found. 9015 9016 // Connection owner UIDs are visible only to the network stack and to the VpnService-based 9017 // VPN, if any, that applies to the UID that owns the connection. 9018 if (checkNetworkStackPermission()) return uid; 9019 9020 final NetworkAgentInfo vpn = getVpnForUid(uid); 9021 if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE 9022 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) { 9023 return INVALID_UID; 9024 } 9025 9026 return uid; 9027 } 9028 9029 /** 9030 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. 9031 * 9032 * <p>The TestNetworkService must be run in the system server due to TUN creation. 9033 */ 9034 @Override startOrGetTestNetworkService()9035 public IBinder startOrGetTestNetworkService() { 9036 synchronized (mTNSLock) { 9037 TestNetworkService.enforceTestNetworkPermissions(mContext); 9038 9039 if (mTNS == null) { 9040 mTNS = new TestNetworkService(mContext); 9041 } 9042 9043 return mTNS; 9044 } 9045 } 9046 9047 /** 9048 * Handler used for managing all Connectivity Diagnostics related functions. 9049 * 9050 * @see android.net.ConnectivityDiagnosticsManager 9051 * 9052 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file 9053 */ 9054 @VisibleForTesting 9055 class ConnectivityDiagnosticsHandler extends Handler { 9056 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName(); 9057 9058 /** 9059 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link 9060 * android.net.ConnectivityDiagnosticsManager}. 9061 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and 9062 * NetworkRequestInfo to be registered 9063 */ 9064 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1; 9065 9066 /** 9067 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link 9068 * android.net.ConnectivityDiagnosticsManager}. 9069 * obj = the IConnectivityDiagnosticsCallback to be unregistered 9070 * arg1 = the uid of the caller 9071 */ 9072 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2; 9073 9074 /** 9075 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks 9076 * after processing {@link #EVENT_NETWORK_TESTED} events. 9077 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from 9078 * NetworkMonitor. 9079 * data = PersistableBundle of extras passed from NetworkMonitor. 9080 * 9081 * <p>See {@link ConnectivityService#EVENT_NETWORK_TESTED}. 9082 */ 9083 private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED; 9084 9085 /** 9086 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has 9087 * been detected on the network. 9088 * obj = Long the timestamp (in millis) for when the suspected data stall was detected. 9089 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method. 9090 * arg2 = NetID. 9091 * data = PersistableBundle of extras passed from NetworkMonitor. 9092 */ 9093 private static final int EVENT_DATA_STALL_SUSPECTED = 4; 9094 9095 /** 9096 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to 9097 * the platform. This event will invoke {@link 9098 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned 9099 * callbacks. 9100 * obj = Network that was reported on 9101 * arg1 = boolint for the quality reported 9102 */ 9103 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5; 9104 ConnectivityDiagnosticsHandler(Looper looper)9105 private ConnectivityDiagnosticsHandler(Looper looper) { 9106 super(looper); 9107 } 9108 9109 @Override handleMessage(Message msg)9110 public void handleMessage(Message msg) { 9111 switch (msg.what) { 9112 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 9113 handleRegisterConnectivityDiagnosticsCallback( 9114 (ConnectivityDiagnosticsCallbackInfo) msg.obj); 9115 break; 9116 } 9117 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 9118 handleUnregisterConnectivityDiagnosticsCallback( 9119 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1); 9120 break; 9121 } 9122 case EVENT_NETWORK_TESTED: { 9123 final ConnectivityReportEvent reportEvent = 9124 (ConnectivityReportEvent) msg.obj; 9125 9126 handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras); 9127 break; 9128 } 9129 case EVENT_DATA_STALL_SUSPECTED: { 9130 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 9131 final Pair<Long, PersistableBundle> arg = 9132 (Pair<Long, PersistableBundle>) msg.obj; 9133 if (nai == null) break; 9134 9135 handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second); 9136 break; 9137 } 9138 case EVENT_NETWORK_CONNECTIVITY_REPORTED: { 9139 handleNetworkConnectivityReported((NetworkAgentInfo) msg.obj, toBool(msg.arg1)); 9140 break; 9141 } 9142 default: { 9143 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what); 9144 } 9145 } 9146 } 9147 } 9148 9149 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */ 9150 @VisibleForTesting 9151 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient { 9152 @NonNull private final IConnectivityDiagnosticsCallback mCb; 9153 @NonNull private final NetworkRequestInfo mRequestInfo; 9154 @NonNull private final String mCallingPackageName; 9155 9156 @VisibleForTesting ConnectivityDiagnosticsCallbackInfo( @onNull IConnectivityDiagnosticsCallback cb, @NonNull NetworkRequestInfo nri, @NonNull String callingPackageName)9157 ConnectivityDiagnosticsCallbackInfo( 9158 @NonNull IConnectivityDiagnosticsCallback cb, 9159 @NonNull NetworkRequestInfo nri, 9160 @NonNull String callingPackageName) { 9161 mCb = cb; 9162 mRequestInfo = nri; 9163 mCallingPackageName = callingPackageName; 9164 } 9165 9166 @Override binderDied()9167 public void binderDied() { 9168 log("ConnectivityDiagnosticsCallback IBinder died."); 9169 unregisterConnectivityDiagnosticsCallback(mCb); 9170 } 9171 } 9172 9173 /** 9174 * Class used for sending information from {@link 9175 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it. 9176 */ 9177 private static class NetworkTestedResults { 9178 private final int mNetId; 9179 private final int mTestResult; 9180 private final long mTimestampMillis; 9181 @Nullable private final String mRedirectUrl; 9182 NetworkTestedResults( int netId, int testResult, long timestampMillis, @Nullable String redirectUrl)9183 private NetworkTestedResults( 9184 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) { 9185 mNetId = netId; 9186 mTestResult = testResult; 9187 mTimestampMillis = timestampMillis; 9188 mRedirectUrl = redirectUrl; 9189 } 9190 } 9191 9192 /** 9193 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link 9194 * ConnectivityDiagnosticsHandler}. 9195 */ 9196 private static class ConnectivityReportEvent { 9197 private final long mTimestampMillis; 9198 @NonNull private final NetworkAgentInfo mNai; 9199 private final PersistableBundle mExtras; 9200 ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, PersistableBundle p)9201 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, 9202 PersistableBundle p) { 9203 mTimestampMillis = timestampMillis; 9204 mNai = nai; 9205 mExtras = p; 9206 } 9207 } 9208 handleRegisterConnectivityDiagnosticsCallback( @onNull ConnectivityDiagnosticsCallbackInfo cbInfo)9209 private void handleRegisterConnectivityDiagnosticsCallback( 9210 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) { 9211 ensureRunningOnConnectivityServiceThread(); 9212 9213 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb; 9214 final IBinder iCb = cb.asBinder(); 9215 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 9216 9217 // Connectivity Diagnostics are meant to be used with a single network request. It would be 9218 // confusing for these networks to change when an NRI is satisfied in another layer. 9219 if (nri.isMultilayerRequest()) { 9220 throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer " 9221 + "network requests."); 9222 } 9223 9224 // This means that the client registered the same callback multiple times. Do 9225 // not override the previous entry, and exit silently. 9226 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) { 9227 if (VDBG) log("Diagnostics callback is already registered"); 9228 9229 // Decrement the reference count for this NetworkRequestInfo. The reference count is 9230 // incremented when the NetworkRequestInfo is created as part of 9231 // enforceRequestCountLimit(). 9232 nri.decrementRequestCount(); 9233 return; 9234 } 9235 9236 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo); 9237 9238 try { 9239 iCb.linkToDeath(cbInfo, 0); 9240 } catch (RemoteException e) { 9241 cbInfo.binderDied(); 9242 return; 9243 } 9244 9245 // Once registered, provide ConnectivityReports for matching Networks 9246 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>(); 9247 synchronized (mNetworkForNetId) { 9248 for (int i = 0; i < mNetworkForNetId.size(); i++) { 9249 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 9250 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0) 9251 if (nai.satisfies(nri.mRequests.get(0))) { 9252 matchingNetworks.add(nai); 9253 } 9254 } 9255 } 9256 for (final NetworkAgentInfo nai : matchingNetworks) { 9257 final ConnectivityReport report = nai.getConnectivityReport(); 9258 if (report == null) { 9259 continue; 9260 } 9261 if (!checkConnectivityDiagnosticsPermissions( 9262 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 9263 continue; 9264 } 9265 9266 try { 9267 cb.onConnectivityReportAvailable(report); 9268 } catch (RemoteException e) { 9269 // Exception while sending the ConnectivityReport. Move on to the next network. 9270 } 9271 } 9272 } 9273 handleUnregisterConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback cb, int uid)9274 private void handleUnregisterConnectivityDiagnosticsCallback( 9275 @NonNull IConnectivityDiagnosticsCallback cb, int uid) { 9276 ensureRunningOnConnectivityServiceThread(); 9277 final IBinder iCb = cb.asBinder(); 9278 9279 final ConnectivityDiagnosticsCallbackInfo cbInfo = 9280 mConnectivityDiagnosticsCallbacks.remove(iCb); 9281 if (cbInfo == null) { 9282 if (VDBG) log("Removing diagnostics callback that is not currently registered"); 9283 return; 9284 } 9285 9286 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 9287 9288 // Caller's UID must either be the registrants (if they are unregistering) or the System's 9289 // (if the Binder died) 9290 if (uid != nri.mUid && uid != Process.SYSTEM_UID) { 9291 if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's"); 9292 return; 9293 } 9294 9295 // Decrement the reference count for this NetworkRequestInfo. The reference count is 9296 // incremented when the NetworkRequestInfo is created as part of 9297 // enforceRequestCountLimit(). 9298 nri.decrementRequestCount(); 9299 9300 iCb.unlinkToDeath(cbInfo, 0); 9301 } 9302 handleNetworkTestedWithExtras( @onNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras)9303 private void handleNetworkTestedWithExtras( 9304 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) { 9305 final NetworkAgentInfo nai = reportEvent.mNai; 9306 final NetworkCapabilities networkCapabilities = 9307 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 9308 final ConnectivityReport report = 9309 new ConnectivityReport( 9310 reportEvent.mNai.network, 9311 reportEvent.mTimestampMillis, 9312 nai.linkProperties, 9313 networkCapabilities, 9314 extras); 9315 nai.setConnectivityReport(report); 9316 final List<IConnectivityDiagnosticsCallback> results = 9317 getMatchingPermissionedCallbacks(nai); 9318 for (final IConnectivityDiagnosticsCallback cb : results) { 9319 try { 9320 cb.onConnectivityReportAvailable(report); 9321 } catch (RemoteException ex) { 9322 loge("Error invoking onConnectivityReport", ex); 9323 } 9324 } 9325 } 9326 handleDataStallSuspected( @onNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, @NonNull PersistableBundle extras)9327 private void handleDataStallSuspected( 9328 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, 9329 @NonNull PersistableBundle extras) { 9330 final NetworkCapabilities networkCapabilities = 9331 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 9332 final DataStallReport report = 9333 new DataStallReport( 9334 nai.network, 9335 timestampMillis, 9336 detectionMethod, 9337 nai.linkProperties, 9338 networkCapabilities, 9339 extras); 9340 final List<IConnectivityDiagnosticsCallback> results = 9341 getMatchingPermissionedCallbacks(nai); 9342 for (final IConnectivityDiagnosticsCallback cb : results) { 9343 try { 9344 cb.onDataStallSuspected(report); 9345 } catch (RemoteException ex) { 9346 loge("Error invoking onDataStallSuspected", ex); 9347 } 9348 } 9349 } 9350 handleNetworkConnectivityReported( @onNull NetworkAgentInfo nai, boolean connectivity)9351 private void handleNetworkConnectivityReported( 9352 @NonNull NetworkAgentInfo nai, boolean connectivity) { 9353 final List<IConnectivityDiagnosticsCallback> results = 9354 getMatchingPermissionedCallbacks(nai); 9355 for (final IConnectivityDiagnosticsCallback cb : results) { 9356 try { 9357 cb.onNetworkConnectivityReported(nai.network, connectivity); 9358 } catch (RemoteException ex) { 9359 loge("Error invoking onNetworkConnectivityReported", ex); 9360 } 9361 } 9362 } 9363 getNetworkCapabilitiesWithoutUids(@onNull NetworkCapabilities nc)9364 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) { 9365 final NetworkCapabilities sanitized = new NetworkCapabilities(nc, 9366 NetworkCapabilities.REDACT_ALL); 9367 sanitized.setUids(null); 9368 sanitized.setAdministratorUids(new int[0]); 9369 sanitized.setOwnerUid(Process.INVALID_UID); 9370 return sanitized; 9371 } 9372 getMatchingPermissionedCallbacks( @onNull NetworkAgentInfo nai)9373 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks( 9374 @NonNull NetworkAgentInfo nai) { 9375 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); 9376 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry : 9377 mConnectivityDiagnosticsCallbacks.entrySet()) { 9378 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue(); 9379 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 9380 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0). 9381 if (nai.satisfies(nri.mRequests.get(0))) { 9382 if (checkConnectivityDiagnosticsPermissions( 9383 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 9384 results.add(entry.getValue().mCb); 9385 } 9386 } 9387 } 9388 return results; 9389 } 9390 isLocationPermissionRequiredForConnectivityDiagnostics( @onNull NetworkAgentInfo nai)9391 private boolean isLocationPermissionRequiredForConnectivityDiagnostics( 9392 @NonNull NetworkAgentInfo nai) { 9393 // TODO(b/188483916): replace with a transport-agnostic location-aware check 9394 return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI); 9395 } 9396 hasLocationPermission(String packageName, int uid)9397 private boolean hasLocationPermission(String packageName, int uid) { 9398 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid 9399 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the 9400 // call in a try-catch. 9401 try { 9402 if (!mLocationPermissionChecker.checkLocationPermission( 9403 packageName, null /* featureId */, uid, null /* message */)) { 9404 return false; 9405 } 9406 } catch (SecurityException e) { 9407 return false; 9408 } 9409 9410 return true; 9411 } 9412 ownsVpnRunningOverNetwork(int uid, Network network)9413 private boolean ownsVpnRunningOverNetwork(int uid, Network network) { 9414 for (NetworkAgentInfo virtual : mNetworkAgentInfos) { 9415 if (virtual.propagateUnderlyingCapabilities() 9416 && virtual.networkCapabilities.getOwnerUid() == uid 9417 && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) { 9418 return true; 9419 } 9420 } 9421 9422 return false; 9423 } 9424 9425 @VisibleForTesting checkConnectivityDiagnosticsPermissions( int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName)9426 boolean checkConnectivityDiagnosticsPermissions( 9427 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) { 9428 if (checkNetworkStackPermission(callbackPid, callbackUid)) { 9429 return true; 9430 } 9431 9432 // Administrator UIDs also contains the Owner UID 9433 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); 9434 if (!CollectionUtils.contains(administratorUids, callbackUid) 9435 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) { 9436 return false; 9437 } 9438 9439 return !isLocationPermissionRequiredForConnectivityDiagnostics(nai) 9440 || hasLocationPermission(callbackPackageName, callbackUid); 9441 } 9442 9443 @Override registerConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback callback, @NonNull NetworkRequest request, @NonNull String callingPackageName)9444 public void registerConnectivityDiagnosticsCallback( 9445 @NonNull IConnectivityDiagnosticsCallback callback, 9446 @NonNull NetworkRequest request, 9447 @NonNull String callingPackageName) { 9448 if (request.legacyType != TYPE_NONE) { 9449 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." 9450 + " Please use NetworkCapabilities instead."); 9451 } 9452 final int callingUid = mDeps.getCallingUid(); 9453 mAppOpsManager.checkPackage(callingUid, callingPackageName); 9454 9455 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid 9456 // and administrator uids to be safe. 9457 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); 9458 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 9459 9460 final NetworkRequest requestWithId = 9461 new NetworkRequest( 9462 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); 9463 9464 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit. 9465 // 9466 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in 9467 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the 9468 // callback's binder death. 9469 final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId); 9470 final ConnectivityDiagnosticsCallbackInfo cbInfo = 9471 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName); 9472 9473 mConnectivityDiagnosticsHandler.sendMessage( 9474 mConnectivityDiagnosticsHandler.obtainMessage( 9475 ConnectivityDiagnosticsHandler 9476 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 9477 cbInfo)); 9478 } 9479 9480 @Override unregisterConnectivityDiagnosticsCallback( @onNull IConnectivityDiagnosticsCallback callback)9481 public void unregisterConnectivityDiagnosticsCallback( 9482 @NonNull IConnectivityDiagnosticsCallback callback) { 9483 Objects.requireNonNull(callback, "callback must be non-null"); 9484 mConnectivityDiagnosticsHandler.sendMessage( 9485 mConnectivityDiagnosticsHandler.obtainMessage( 9486 ConnectivityDiagnosticsHandler 9487 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 9488 mDeps.getCallingUid(), 9489 0, 9490 callback)); 9491 } 9492 9493 @Override simulateDataStall(int detectionMethod, long timestampMillis, @NonNull Network network, @NonNull PersistableBundle extras)9494 public void simulateDataStall(int detectionMethod, long timestampMillis, 9495 @NonNull Network network, @NonNull PersistableBundle extras) { 9496 enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS, 9497 android.Manifest.permission.NETWORK_STACK); 9498 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 9499 if (!nc.hasTransport(TRANSPORT_TEST)) { 9500 throw new SecurityException("Data Stall simluation is only possible for test networks"); 9501 } 9502 9503 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 9504 if (nai == null || nai.creatorUid != mDeps.getCallingUid()) { 9505 throw new SecurityException("Data Stall simulation is only possible for network " 9506 + "creators"); 9507 } 9508 9509 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat 9510 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the 9511 // Data Stall information as a DataStallReportParcelable and passing to 9512 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are 9513 // still passed to ConnectivityDiagnostics (with new detection methods masked). 9514 final DataStallReportParcelable p = new DataStallReportParcelable(); 9515 p.timestampMillis = timestampMillis; 9516 p.detectionMethod = detectionMethod; 9517 9518 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 9519 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS); 9520 } 9521 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 9522 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE); 9523 p.tcpMetricsCollectionPeriodMillis = extras.getInt( 9524 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS); 9525 } 9526 9527 notifyDataStallSuspected(p, network.getNetId()); 9528 } 9529 9530 private class NetdCallback extends BaseNetdUnsolicitedEventListener { 9531 @Override onInterfaceClassActivityChanged(boolean isActive, int transportType, long timestampNs, int uid)9532 public void onInterfaceClassActivityChanged(boolean isActive, int transportType, 9533 long timestampNs, int uid) { 9534 mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs); 9535 } 9536 9537 @Override onInterfaceLinkStateChanged(String iface, boolean up)9538 public void onInterfaceLinkStateChanged(String iface, boolean up) { 9539 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 9540 nai.clatd.interfaceLinkStateChanged(iface, up); 9541 } 9542 } 9543 9544 @Override onInterfaceRemoved(String iface)9545 public void onInterfaceRemoved(String iface) { 9546 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 9547 nai.clatd.interfaceRemoved(iface); 9548 } 9549 } 9550 } 9551 9552 private final LegacyNetworkActivityTracker mNetworkActivityTracker; 9553 9554 /** 9555 * Class used for updating network activity tracking with netd and notify network activity 9556 * changes. 9557 */ 9558 private static final class LegacyNetworkActivityTracker { 9559 private static final int NO_UID = -1; 9560 private final Context mContext; 9561 private final INetd mNetd; 9562 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 9563 new RemoteCallbackList<>(); 9564 // Indicate the current system default network activity is active or not. 9565 @GuardedBy("mActiveIdleTimers") 9566 private boolean mNetworkActive; 9567 @GuardedBy("mActiveIdleTimers") 9568 private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap(); 9569 private final Handler mHandler; 9570 9571 private class IdleTimerParams { 9572 public final int timeout; 9573 public final int transportType; 9574 IdleTimerParams(int timeout, int transport)9575 IdleTimerParams(int timeout, int transport) { 9576 this.timeout = timeout; 9577 this.transportType = transport; 9578 } 9579 } 9580 LegacyNetworkActivityTracker(@onNull Context context, @NonNull Handler handler, @NonNull INetd netd)9581 LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler, 9582 @NonNull INetd netd) { 9583 mContext = context; 9584 mNetd = netd; 9585 mHandler = handler; 9586 } 9587 setAndReportNetworkActive(boolean active, int transportType, long tsNanos)9588 public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) { 9589 sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos); 9590 synchronized (mActiveIdleTimers) { 9591 mNetworkActive = active; 9592 // If there are no idle timers, it means that system is not monitoring 9593 // activity, so the system default network for those default network 9594 // unspecified apps is always considered active. 9595 // 9596 // TODO: If the mActiveIdleTimers is empty, netd will actually not send 9597 // any network activity change event. Whenever this event is received, 9598 // the mActiveIdleTimers should be always not empty. The legacy behavior 9599 // is no-op. Remove to refer to mNetworkActive only. 9600 if (mNetworkActive || mActiveIdleTimers.isEmpty()) { 9601 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY)); 9602 } 9603 } 9604 } 9605 9606 // The network activity should only be updated from ConnectivityService handler thread 9607 // when mActiveIdleTimers lock is held. 9608 @GuardedBy("mActiveIdleTimers") reportNetworkActive()9609 private void reportNetworkActive() { 9610 final int length = mNetworkActivityListeners.beginBroadcast(); 9611 if (DDBG) log("reportNetworkActive, notify " + length + " listeners"); 9612 try { 9613 for (int i = 0; i < length; i++) { 9614 try { 9615 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 9616 } catch (RemoteException | RuntimeException e) { 9617 loge("Fail to send network activie to listener " + e); 9618 } 9619 } 9620 } finally { 9621 mNetworkActivityListeners.finishBroadcast(); 9622 } 9623 } 9624 9625 @GuardedBy("mActiveIdleTimers") handleReportNetworkActivity()9626 public void handleReportNetworkActivity() { 9627 synchronized (mActiveIdleTimers) { 9628 reportNetworkActive(); 9629 } 9630 } 9631 9632 // This is deprecated and only to support legacy use cases. transportTypeToLegacyType(int type)9633 private int transportTypeToLegacyType(int type) { 9634 switch (type) { 9635 case NetworkCapabilities.TRANSPORT_CELLULAR: 9636 return TYPE_MOBILE; 9637 case NetworkCapabilities.TRANSPORT_WIFI: 9638 return TYPE_WIFI; 9639 case NetworkCapabilities.TRANSPORT_BLUETOOTH: 9640 return TYPE_BLUETOOTH; 9641 case NetworkCapabilities.TRANSPORT_ETHERNET: 9642 return TYPE_ETHERNET; 9643 default: 9644 loge("Unexpected transport in transportTypeToLegacyType: " + type); 9645 } 9646 return ConnectivityManager.TYPE_NONE; 9647 } 9648 sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos)9649 public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 9650 final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 9651 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 9652 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 9653 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 9654 final long ident = Binder.clearCallingIdentity(); 9655 try { 9656 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 9657 RECEIVE_DATA_ACTIVITY_CHANGE, 9658 null /* resultReceiver */, 9659 null /* scheduler */, 9660 0 /* initialCode */, 9661 null /* initialData */, 9662 null /* initialExtra */); 9663 } finally { 9664 Binder.restoreCallingIdentity(ident); 9665 } 9666 } 9667 9668 /** 9669 * Setup data activity tracking for the given network. 9670 * 9671 * Every {@code setupDataActivityTracking} should be paired with a 9672 * {@link #removeDataActivityTracking} for cleanup. 9673 */ setupDataActivityTracking(NetworkAgentInfo networkAgent)9674 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) { 9675 final String iface = networkAgent.linkProperties.getInterfaceName(); 9676 9677 final int timeout; 9678 final int type; 9679 9680 if (networkAgent.networkCapabilities.hasTransport( 9681 NetworkCapabilities.TRANSPORT_CELLULAR)) { 9682 timeout = Settings.Global.getInt(mContext.getContentResolver(), 9683 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE, 9684 10); 9685 type = NetworkCapabilities.TRANSPORT_CELLULAR; 9686 } else if (networkAgent.networkCapabilities.hasTransport( 9687 NetworkCapabilities.TRANSPORT_WIFI)) { 9688 timeout = Settings.Global.getInt(mContext.getContentResolver(), 9689 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI, 9690 15); 9691 type = NetworkCapabilities.TRANSPORT_WIFI; 9692 } else { 9693 return; // do not track any other networks 9694 } 9695 9696 updateRadioPowerState(true /* isActive */, type); 9697 9698 if (timeout > 0 && iface != null) { 9699 try { 9700 synchronized (mActiveIdleTimers) { 9701 // Networks start up. 9702 mNetworkActive = true; 9703 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type)); 9704 mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type)); 9705 reportNetworkActive(); 9706 } 9707 } catch (Exception e) { 9708 // You shall not crash! 9709 loge("Exception in setupDataActivityTracking " + e); 9710 } 9711 } 9712 } 9713 9714 /** 9715 * Remove data activity tracking when network disconnects. 9716 */ removeDataActivityTracking(NetworkAgentInfo networkAgent)9717 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 9718 final String iface = networkAgent.linkProperties.getInterfaceName(); 9719 final NetworkCapabilities caps = networkAgent.networkCapabilities; 9720 9721 if (iface == null) return; 9722 9723 final int type; 9724 if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { 9725 type = NetworkCapabilities.TRANSPORT_CELLULAR; 9726 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 9727 type = NetworkCapabilities.TRANSPORT_WIFI; 9728 } else { 9729 return; // do not track any other networks 9730 } 9731 9732 try { 9733 updateRadioPowerState(false /* isActive */, type); 9734 synchronized (mActiveIdleTimers) { 9735 final IdleTimerParams params = mActiveIdleTimers.remove(iface); 9736 // The call fails silently if no idle timer setup for this interface 9737 mNetd.idletimerRemoveInterface(iface, params.timeout, 9738 Integer.toString(params.transportType)); 9739 } 9740 } catch (Exception e) { 9741 // You shall not crash! 9742 loge("Exception in removeDataActivityTracking " + e); 9743 } 9744 } 9745 9746 /** 9747 * Update data activity tracking when network state is updated. 9748 */ updateDataActivityTracking(NetworkAgentInfo newNetwork, NetworkAgentInfo oldNetwork)9749 public void updateDataActivityTracking(NetworkAgentInfo newNetwork, 9750 NetworkAgentInfo oldNetwork) { 9751 if (newNetwork != null) { 9752 setupDataActivityTracking(newNetwork); 9753 } 9754 if (oldNetwork != null) { 9755 removeDataActivityTracking(oldNetwork); 9756 } 9757 } 9758 updateRadioPowerState(boolean isActive, int transportType)9759 private void updateRadioPowerState(boolean isActive, int transportType) { 9760 final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class); 9761 switch (transportType) { 9762 case NetworkCapabilities.TRANSPORT_CELLULAR: 9763 bs.reportMobileRadioPowerState(isActive, NO_UID); 9764 break; 9765 case NetworkCapabilities.TRANSPORT_WIFI: 9766 bs.reportWifiRadioPowerState(isActive, NO_UID); 9767 break; 9768 default: 9769 logw("Untracked transport type:" + transportType); 9770 } 9771 } 9772 isDefaultNetworkActive()9773 public boolean isDefaultNetworkActive() { 9774 synchronized (mActiveIdleTimers) { 9775 // If there are no idle timers, it means that system is not monitoring activity, 9776 // so the default network is always considered active. 9777 // 9778 // TODO : Distinguish between the cases where mActiveIdleTimers is empty because 9779 // tracking is disabled (negative idle timer value configured), or no active default 9780 // network. In the latter case, this reports active but it should report inactive. 9781 return mNetworkActive || mActiveIdleTimers.isEmpty(); 9782 } 9783 } 9784 registerNetworkActivityListener(@onNull INetworkActivityListener l)9785 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 9786 mNetworkActivityListeners.register(l); 9787 } 9788 unregisterNetworkActivityListener(@onNull INetworkActivityListener l)9789 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 9790 mNetworkActivityListeners.unregister(l); 9791 } 9792 dump(IndentingPrintWriter pw)9793 public void dump(IndentingPrintWriter pw) { 9794 synchronized (mActiveIdleTimers) { 9795 pw.print("mNetworkActive="); pw.println(mNetworkActive); 9796 pw.println("Idle timers:"); 9797 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) { 9798 pw.print(" "); pw.print(ent.getKey()); pw.println(":"); 9799 final IdleTimerParams params = ent.getValue(); 9800 pw.print(" timeout="); pw.print(params.timeout); 9801 pw.print(" type="); pw.println(params.transportType); 9802 } 9803 } 9804 } 9805 } 9806 9807 /** 9808 * Registers {@link QosSocketFilter} with {@link IQosCallback}. 9809 * 9810 * @param socketInfo the socket information 9811 * @param callback the callback to register 9812 */ 9813 @Override registerQosSocketCallback(@onNull final QosSocketInfo socketInfo, @NonNull final IQosCallback callback)9814 public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo, 9815 @NonNull final IQosCallback callback) { 9816 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork()); 9817 if (nai == null || nai.networkCapabilities == null) { 9818 try { 9819 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); 9820 } catch (final RemoteException ex) { 9821 loge("registerQosCallbackInternal: RemoteException", ex); 9822 } 9823 return; 9824 } 9825 registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai); 9826 } 9827 9828 /** 9829 * Register a {@link IQosCallback} with base {@link QosFilter}. 9830 * 9831 * @param filter the filter to register 9832 * @param callback the callback to register 9833 * @param nai the agent information related to the filter's network 9834 */ 9835 @VisibleForTesting registerQosCallbackInternal(@onNull final QosFilter filter, @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai)9836 public void registerQosCallbackInternal(@NonNull final QosFilter filter, 9837 @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) { 9838 if (filter == null) throw new IllegalArgumentException("filter must be non-null"); 9839 if (callback == null) throw new IllegalArgumentException("callback must be non-null"); 9840 9841 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 9842 enforceConnectivityRestrictedNetworksPermission(); 9843 } 9844 mQosCallbackTracker.registerCallback(callback, filter, nai); 9845 } 9846 9847 /** 9848 * Unregisters the given callback. 9849 * 9850 * @param callback the callback to unregister 9851 */ 9852 @Override unregisterQosCallback(@onNull final IQosCallback callback)9853 public void unregisterQosCallback(@NonNull final IQosCallback callback) { 9854 Objects.requireNonNull(callback, "callback must be non-null"); 9855 mQosCallbackTracker.unregisterCallback(callback); 9856 } 9857 9858 /** 9859 * Request that a user profile is put by default on a network matching a given preference. 9860 * 9861 * See the documentation for the individual preferences for a description of the supported 9862 * behaviors. 9863 * 9864 * @param profile the profile concerned. 9865 * @param preference the preference for this profile, as one of the PROFILE_NETWORK_PREFERENCE_* 9866 * constants. 9867 * @param listener an optional listener to listen for completion of the operation. 9868 */ 9869 @Override setProfileNetworkPreference(@onNull final UserHandle profile, @ConnectivityManager.ProfileNetworkPreference final int preference, @Nullable final IOnCompleteListener listener)9870 public void setProfileNetworkPreference(@NonNull final UserHandle profile, 9871 @ConnectivityManager.ProfileNetworkPreference final int preference, 9872 @Nullable final IOnCompleteListener listener) { 9873 Objects.requireNonNull(profile); 9874 PermissionUtils.enforceNetworkStackPermission(mContext); 9875 if (DBG) { 9876 log("setProfileNetworkPreference " + profile + " to " + preference); 9877 } 9878 if (profile.getIdentifier() < 0) { 9879 throw new IllegalArgumentException("Must explicitly specify a user handle (" 9880 + "UserHandle.CURRENT not supported)"); 9881 } 9882 final UserManager um = mContext.getSystemService(UserManager.class); 9883 if (!um.isManagedProfile(profile.getIdentifier())) { 9884 throw new IllegalArgumentException("Profile must be a managed profile"); 9885 } 9886 9887 final NetworkCapabilities nc; 9888 switch (preference) { 9889 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT: 9890 nc = null; 9891 break; 9892 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE: 9893 final UidRange uids = UidRange.createForUser(profile); 9894 nc = createDefaultNetworkCapabilitiesForUidRange(uids); 9895 nc.addCapability(NET_CAPABILITY_ENTERPRISE); 9896 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 9897 break; 9898 default: 9899 throw new IllegalArgumentException( 9900 "Invalid preference in setProfileNetworkPreference"); 9901 } 9902 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE, 9903 new Pair<>(new ProfileNetworkPreferences.Preference(profile, nc), listener))); 9904 } 9905 validateNetworkCapabilitiesOfProfileNetworkPreference( @ullable final NetworkCapabilities nc)9906 private void validateNetworkCapabilitiesOfProfileNetworkPreference( 9907 @Nullable final NetworkCapabilities nc) { 9908 if (null == nc) return; // Null caps are always allowed. It means to remove the setting. 9909 ensureRequestableCapabilities(nc); 9910 } 9911 createNrisFromProfileNetworkPreferences( @onNull final ProfileNetworkPreferences prefs)9912 private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences( 9913 @NonNull final ProfileNetworkPreferences prefs) { 9914 final ArraySet<NetworkRequestInfo> result = new ArraySet<>(); 9915 for (final ProfileNetworkPreferences.Preference pref : prefs.preferences) { 9916 // The NRI for a user should be comprised of two layers: 9917 // - The request for the capabilities 9918 // - The request for the default network, for fallback. Create an image of it to 9919 // have the correct UIDs in it (also a request can only be part of one NRI, because 9920 // of lookups in 1:1 associations like mNetworkRequests). 9921 // Note that denying a fallback can be implemented simply by not adding the second 9922 // request. 9923 final ArrayList<NetworkRequest> nrs = new ArrayList<>(); 9924 nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities)); 9925 nrs.add(createDefaultInternetRequestForTransport( 9926 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 9927 setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids())); 9928 final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs, 9929 PREFERENCE_PRIORITY_PROFILE); 9930 result.add(nri); 9931 } 9932 return result; 9933 } 9934 handleSetProfileNetworkPreference( @onNull final ProfileNetworkPreferences.Preference preference, @Nullable final IOnCompleteListener listener)9935 private void handleSetProfileNetworkPreference( 9936 @NonNull final ProfileNetworkPreferences.Preference preference, 9937 @Nullable final IOnCompleteListener listener) { 9938 validateNetworkCapabilitiesOfProfileNetworkPreference(preference.capabilities); 9939 9940 mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference); 9941 mSystemNetworkRequestCounter.transact( 9942 mDeps.getCallingUid(), mProfileNetworkPreferences.preferences.size(), 9943 () -> { 9944 final ArraySet<NetworkRequestInfo> nris = 9945 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences); 9946 replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_PROFILE); 9947 }); 9948 // Finally, rematch. 9949 rematchAllNetworksAndRequests(); 9950 9951 if (null != listener) { 9952 try { 9953 listener.onComplete(); 9954 } catch (RemoteException e) { 9955 loge("Listener for setProfileNetworkPreference has died"); 9956 } 9957 } 9958 } 9959 9960 @VisibleForTesting 9961 @NonNull createNrisFromMobileDataPreferredUids( @onNull final Set<Integer> uids)9962 ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids( 9963 @NonNull final Set<Integer> uids) { 9964 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 9965 if (uids.size() == 0) { 9966 // Should not create NetworkRequestInfo if no preferences. Without uid range in 9967 // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI. 9968 if (DBG) log("Don't create NetworkRequestInfo because no preferences"); 9969 return nris; 9970 } 9971 9972 final List<NetworkRequest> requests = new ArrayList<>(); 9973 // The NRI should be comprised of two layers: 9974 // - The request for the mobile network preferred. 9975 // - The request for the default network, for fallback. 9976 requests.add(createDefaultInternetRequestForTransport( 9977 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST)); 9978 requests.add(createDefaultInternetRequestForTransport( 9979 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 9980 final Set<UidRange> ranges = new ArraySet<>(); 9981 for (final int uid : uids) { 9982 ranges.add(new UidRange(uid, uid)); 9983 } 9984 setNetworkRequestUids(requests, ranges); 9985 nris.add(new NetworkRequestInfo(Process.myUid(), requests, 9986 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED)); 9987 return nris; 9988 } 9989 handleMobileDataPreferredUidsChanged()9990 private void handleMobileDataPreferredUidsChanged() { 9991 mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext); 9992 mSystemNetworkRequestCounter.transact( 9993 mDeps.getCallingUid(), 1 /* numOfNewRequests */, 9994 () -> { 9995 final ArraySet<NetworkRequestInfo> nris = 9996 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids); 9997 replaceDefaultNetworkRequestsForPreference(nris, 9998 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 9999 }); 10000 // Finally, rematch. 10001 rematchAllNetworksAndRequests(); 10002 } 10003 enforceAutomotiveDevice()10004 private void enforceAutomotiveDevice() { 10005 final boolean isAutomotiveDevice = 10006 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 10007 if (!isAutomotiveDevice) { 10008 throw new UnsupportedOperationException( 10009 "setOemNetworkPreference() is only available on automotive devices."); 10010 } 10011 } 10012 10013 /** 10014 * Used by automotive devices to set the network preferences used to direct traffic at an 10015 * application level as per the given OemNetworkPreferences. An example use-case would be an 10016 * automotive OEM wanting to provide connectivity for applications critical to the usage of a 10017 * vehicle via a particular network. 10018 * 10019 * Calling this will overwrite the existing preference. 10020 * 10021 * @param preference {@link OemNetworkPreferences} The application network preference to be set. 10022 * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used 10023 * to communicate completion of setOemNetworkPreference(); 10024 */ 10025 @Override setOemNetworkPreference( @onNull final OemNetworkPreferences preference, @Nullable final IOnCompleteListener listener)10026 public void setOemNetworkPreference( 10027 @NonNull final OemNetworkPreferences preference, 10028 @Nullable final IOnCompleteListener listener) { 10029 10030 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 10031 // Only bypass the permission/device checks if this is a valid test request. 10032 if (isValidTestOemNetworkPreference(preference)) { 10033 enforceManageTestNetworksPermission(); 10034 } else { 10035 enforceAutomotiveDevice(); 10036 enforceOemNetworkPreferencesPermission(); 10037 validateOemNetworkPreferences(preference); 10038 } 10039 10040 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE, 10041 new Pair<>(preference, listener))); 10042 } 10043 10044 /** 10045 * Check the validity of an OEM network preference to be used for testing purposes. 10046 * @param preference the preference to validate 10047 * @return true if this is a valid OEM network preference test request. 10048 */ isValidTestOemNetworkPreference( @onNull final OemNetworkPreferences preference)10049 private boolean isValidTestOemNetworkPreference( 10050 @NonNull final OemNetworkPreferences preference) { 10051 // Allow for clearing of an existing OemNetworkPreference used for testing. 10052 // This isn't called on the handler thread so it is possible that mOemNetworkPreferences 10053 // changes after this check is complete. This is an unlikely scenario as calling of this API 10054 // is controlled by the OEM therefore the added complexity is not worth adding given those 10055 // circumstances. That said, it is an edge case to be aware of hence this comment. 10056 final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0 10057 && isTestOemNetworkPreference(mOemNetworkPreferences); 10058 return isTestOemNetworkPreference(preference) || isValidTestClearPref; 10059 } 10060 isTestOemNetworkPreference(@onNull final OemNetworkPreferences preference)10061 private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) { 10062 final Map<String, Integer> prefMap = preference.getNetworkPreferences(); 10063 return prefMap.size() == 1 10064 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST) 10065 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY)); 10066 } 10067 validateOemNetworkPreferences(@onNull OemNetworkPreferences preference)10068 private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) { 10069 for (@OemNetworkPreferences.OemNetworkPreference final int pref 10070 : preference.getNetworkPreferences().values()) { 10071 if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) { 10072 throw new IllegalArgumentException( 10073 OemNetworkPreferences.oemNetworkPreferenceToString(pref) 10074 + " is an invalid value."); 10075 } 10076 } 10077 } 10078 handleSetOemNetworkPreference( @onNull final OemNetworkPreferences preference, @Nullable final IOnCompleteListener listener)10079 private void handleSetOemNetworkPreference( 10080 @NonNull final OemNetworkPreferences preference, 10081 @Nullable final IOnCompleteListener listener) { 10082 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 10083 if (DBG) { 10084 log("set OEM network preferences :" + preference.toString()); 10085 } 10086 10087 mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference); 10088 final int uniquePreferenceCount = new ArraySet<>( 10089 preference.getNetworkPreferences().values()).size(); 10090 mSystemNetworkRequestCounter.transact( 10091 mDeps.getCallingUid(), uniquePreferenceCount, 10092 () -> { 10093 final ArraySet<NetworkRequestInfo> nris = 10094 new OemNetworkRequestFactory() 10095 .createNrisFromOemNetworkPreferences(preference); 10096 replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_OEM); 10097 }); 10098 mOemNetworkPreferences = preference; 10099 10100 if (null != listener) { 10101 try { 10102 listener.onComplete(); 10103 } catch (RemoteException e) { 10104 loge("Can't send onComplete in handleSetOemNetworkPreference", e); 10105 } 10106 } 10107 } 10108 replaceDefaultNetworkRequestsForPreference( @onNull final Set<NetworkRequestInfo> nris, final int preferencePriority)10109 private void replaceDefaultNetworkRequestsForPreference( 10110 @NonNull final Set<NetworkRequestInfo> nris, final int preferencePriority) { 10111 // Skip the requests which are set by other network preference. Because the uid range rules 10112 // should stay in netd. 10113 final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests); 10114 requests.removeIf(request -> request.mPreferencePriority != preferencePriority); 10115 handleRemoveNetworkRequests(requests); 10116 addPerAppDefaultNetworkRequests(nris); 10117 } 10118 addPerAppDefaultNetworkRequests(@onNull final Set<NetworkRequestInfo> nris)10119 private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 10120 ensureRunningOnConnectivityServiceThread(); 10121 mDefaultNetworkRequests.addAll(nris); 10122 final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate = 10123 getPerAppCallbackRequestsToUpdate(); 10124 final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris); 10125 mSystemNetworkRequestCounter.transact( 10126 mDeps.getCallingUid(), perAppCallbackRequestsToUpdate.size(), 10127 () -> { 10128 nrisToRegister.addAll( 10129 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate)); 10130 handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate); 10131 handleRegisterNetworkRequests(nrisToRegister); 10132 }); 10133 } 10134 10135 /** 10136 * All current requests that are tracking the default network need to be assessed as to whether 10137 * or not the current set of per-application default requests will be changing their default 10138 * network. If so, those requests will need to be updated so that they will send callbacks for 10139 * default network changes at the appropriate time. Additionally, those requests tracking the 10140 * default that were previously updated by this flow will need to be reassessed. 10141 * @return the nris which will need to be updated. 10142 */ getPerAppCallbackRequestsToUpdate()10143 private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() { 10144 final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>(); 10145 // Get the distinct nris to check since for multilayer requests, it is possible to have the 10146 // same nri in the map's values for each of its NetworkRequest objects. 10147 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values()); 10148 for (final NetworkRequestInfo nri : nris) { 10149 // Include this nri if it is currently being tracked. 10150 if (isPerAppTrackedNri(nri)) { 10151 defaultCallbackRequests.add(nri); 10152 continue; 10153 } 10154 // We only track callbacks for requests tracking the default. 10155 if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) { 10156 continue; 10157 } 10158 // Include this nri if it will be tracked by the new per-app default requests. 10159 final boolean isNriGoingToBeTracked = 10160 getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest; 10161 if (isNriGoingToBeTracked) { 10162 defaultCallbackRequests.add(nri); 10163 } 10164 } 10165 return defaultCallbackRequests; 10166 } 10167 10168 /** 10169 * Create nris for those network requests that are currently tracking the default network that 10170 * are being controlled by a per-application default. 10171 * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the 10172 * foundation when creating the nri. Important items include the calling uid's original 10173 * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These 10174 * requests are assumed to have already been validated as needing to be updated. 10175 * @return the Set of nris to use when registering network requests. 10176 */ createPerAppCallbackRequestsToRegister( @onNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate)10177 private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister( 10178 @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) { 10179 final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>(); 10180 for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) { 10181 final NetworkRequestInfo trackingNri = 10182 getDefaultRequestTrackingUid(callbackRequest.mAsUid); 10183 10184 // If this nri is not being tracked, then change it back to an untracked nri. 10185 if (trackingNri == mDefaultRequest) { 10186 callbackRequestsToRegister.add(new NetworkRequestInfo( 10187 callbackRequest, 10188 Collections.singletonList(callbackRequest.getNetworkRequestForCallback()))); 10189 continue; 10190 } 10191 10192 final NetworkRequest request = callbackRequest.mRequests.get(0); 10193 callbackRequestsToRegister.add(new NetworkRequestInfo( 10194 callbackRequest, 10195 copyNetworkRequestsForUid( 10196 trackingNri.mRequests, callbackRequest.mAsUid, 10197 callbackRequest.mUid, request.getRequestorPackageName()))); 10198 } 10199 return callbackRequestsToRegister; 10200 } 10201 setNetworkRequestUids(@onNull final List<NetworkRequest> requests, @NonNull final Set<UidRange> uids)10202 private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests, 10203 @NonNull final Set<UidRange> uids) { 10204 for (final NetworkRequest req : requests) { 10205 req.networkCapabilities.setUids(UidRange.toIntRanges(uids)); 10206 } 10207 } 10208 10209 /** 10210 * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}. 10211 */ 10212 @VisibleForTesting 10213 final class OemNetworkRequestFactory { createNrisFromOemNetworkPreferences( @onNull final OemNetworkPreferences preference)10214 ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences( 10215 @NonNull final OemNetworkPreferences preference) { 10216 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 10217 final SparseArray<Set<Integer>> uids = 10218 createUidsFromOemNetworkPreferences(preference); 10219 for (int i = 0; i < uids.size(); i++) { 10220 final int key = uids.keyAt(i); 10221 final Set<Integer> value = uids.valueAt(i); 10222 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value); 10223 // No need to add an nri without any requests. 10224 if (0 == nri.mRequests.size()) { 10225 continue; 10226 } 10227 nris.add(nri); 10228 } 10229 10230 return nris; 10231 } 10232 createUidsFromOemNetworkPreferences( @onNull final OemNetworkPreferences preference)10233 private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences( 10234 @NonNull final OemNetworkPreferences preference) { 10235 final SparseArray<Set<Integer>> prefToUids = new SparseArray<>(); 10236 final PackageManager pm = mContext.getPackageManager(); 10237 final List<UserHandle> users = 10238 mContext.getSystemService(UserManager.class).getUserHandles(true); 10239 if (null == users || users.size() == 0) { 10240 if (VDBG || DDBG) { 10241 log("No users currently available for setting the OEM network preference."); 10242 } 10243 return prefToUids; 10244 } 10245 for (final Map.Entry<String, Integer> entry : 10246 preference.getNetworkPreferences().entrySet()) { 10247 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue(); 10248 // Add the rules for all users as this policy is device wide. 10249 for (final UserHandle user : users) { 10250 try { 10251 final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid; 10252 if (!prefToUids.contains(pref)) { 10253 prefToUids.put(pref, new ArraySet<>()); 10254 } 10255 prefToUids.get(pref).add(uid); 10256 } catch (PackageManager.NameNotFoundException e) { 10257 // Although this may seem like an error scenario, it is ok that uninstalled 10258 // packages are sent on a network preference as the system will watch for 10259 // package installations associated with this network preference and update 10260 // accordingly. This is done to minimize race conditions on app install. 10261 continue; 10262 } 10263 } 10264 } 10265 return prefToUids; 10266 } 10267 createNriFromOemNetworkPreferences( @emNetworkPreferences.OemNetworkPreference final int preference, @NonNull final Set<Integer> uids)10268 private NetworkRequestInfo createNriFromOemNetworkPreferences( 10269 @OemNetworkPreferences.OemNetworkPreference final int preference, 10270 @NonNull final Set<Integer> uids) { 10271 final List<NetworkRequest> requests = new ArrayList<>(); 10272 // Requests will ultimately be evaluated by order of insertion therefore it matters. 10273 switch (preference) { 10274 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID: 10275 requests.add(createUnmeteredNetworkRequest()); 10276 requests.add(createOemPaidNetworkRequest()); 10277 requests.add(createDefaultInternetRequestForTransport( 10278 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 10279 break; 10280 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK: 10281 requests.add(createUnmeteredNetworkRequest()); 10282 requests.add(createOemPaidNetworkRequest()); 10283 break; 10284 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY: 10285 requests.add(createOemPaidNetworkRequest()); 10286 break; 10287 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY: 10288 requests.add(createOemPrivateNetworkRequest()); 10289 break; 10290 case OEM_NETWORK_PREFERENCE_TEST: 10291 requests.add(createUnmeteredNetworkRequest()); 10292 requests.add(createTestNetworkRequest()); 10293 requests.add(createDefaultRequest()); 10294 break; 10295 case OEM_NETWORK_PREFERENCE_TEST_ONLY: 10296 requests.add(createTestNetworkRequest()); 10297 break; 10298 default: 10299 // This should never happen. 10300 throw new IllegalArgumentException("createNriFromOemNetworkPreferences()" 10301 + " called with invalid preference of " + preference); 10302 } 10303 10304 final ArraySet<UidRange> ranges = new ArraySet<>(); 10305 for (final int uid : uids) { 10306 ranges.add(new UidRange(uid, uid)); 10307 } 10308 setNetworkRequestUids(requests, ranges); 10309 return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_PRIORITY_OEM); 10310 } 10311 createUnmeteredNetworkRequest()10312 private NetworkRequest createUnmeteredNetworkRequest() { 10313 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 10314 .addCapability(NET_CAPABILITY_NOT_METERED) 10315 .addCapability(NET_CAPABILITY_VALIDATED); 10316 return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap); 10317 } 10318 createOemPaidNetworkRequest()10319 private NetworkRequest createOemPaidNetworkRequest() { 10320 // NET_CAPABILITY_OEM_PAID is a restricted capability. 10321 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 10322 .addCapability(NET_CAPABILITY_OEM_PAID) 10323 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 10324 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 10325 } 10326 createOemPrivateNetworkRequest()10327 private NetworkRequest createOemPrivateNetworkRequest() { 10328 // NET_CAPABILITY_OEM_PRIVATE is a restricted capability. 10329 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 10330 .addCapability(NET_CAPABILITY_OEM_PRIVATE) 10331 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 10332 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 10333 } 10334 createDefaultPerAppNetCap()10335 private NetworkCapabilities createDefaultPerAppNetCap() { 10336 final NetworkCapabilities netcap = new NetworkCapabilities(); 10337 netcap.addCapability(NET_CAPABILITY_INTERNET); 10338 netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 10339 return netcap; 10340 } 10341 createTestNetworkRequest()10342 private NetworkRequest createTestNetworkRequest() { 10343 final NetworkCapabilities netcap = new NetworkCapabilities(); 10344 netcap.clearAll(); 10345 netcap.addTransportType(TRANSPORT_TEST); 10346 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 10347 } 10348 } 10349 } 10350