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