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