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.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; 21 import static android.content.pm.PackageManager.FEATURE_BLUETOOTH; 22 import static android.content.pm.PackageManager.FEATURE_LEANBACK; 23 import static android.content.pm.PackageManager.FEATURE_WATCH; 24 import static android.content.pm.PackageManager.FEATURE_WIFI; 25 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 26 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 27 import static android.net.BpfNetMapsConstants.METERED_ALLOW_CHAINS; 28 import static android.net.BpfNetMapsConstants.METERED_DENY_CHAINS; 29 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; 30 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK; 31 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT; 32 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS; 33 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS; 34 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS; 35 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS; 36 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE; 37 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 38 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 39 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND; 40 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; 41 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 42 import static android.net.ConnectivityManager.BLOCKED_REASON_NETWORK_RESTRICTED; 43 import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED; 44 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 45 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; 46 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 47 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 48 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 49 import static android.net.ConnectivityManager.TYPE_BLUETOOTH; 50 import static android.net.ConnectivityManager.TYPE_ETHERNET; 51 import static android.net.ConnectivityManager.TYPE_MOBILE; 52 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS; 53 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 54 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY; 55 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 56 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 57 import static android.net.ConnectivityManager.TYPE_MOBILE_IA; 58 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS; 59 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 60 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 61 import static android.net.ConnectivityManager.TYPE_NONE; 62 import static android.net.ConnectivityManager.TYPE_PROXY; 63 import static android.net.ConnectivityManager.TYPE_VPN; 64 import static android.net.ConnectivityManager.TYPE_WIFI; 65 import static android.net.ConnectivityManager.TYPE_WIFI_P2P; 66 import static android.net.ConnectivityManager.getNetworkTypeName; 67 import static android.net.ConnectivityManager.isNetworkTypeValid; 68 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 69 import static android.net.INetd.PERMISSION_INTERNET; 70 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 71 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 72 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_SKIPPED; 73 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 74 import static android.net.MulticastRoutingConfig.FORWARD_NONE; 75 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 76 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 77 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 78 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 79 import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK; 80 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED; 81 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 82 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 83 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 84 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 85 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 86 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 87 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 88 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 89 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 90 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 91 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 92 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 93 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 94 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 95 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 96 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 97 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 98 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 99 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 100 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 101 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 102 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; 103 import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY; 104 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 105 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 106 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_LOCAL_NETWORK; 107 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION; 108 import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION; 109 import static android.os.Process.INVALID_UID; 110 import static android.os.Process.VPN_UID; 111 import static android.system.OsConstants.ETH_P_ALL; 112 import static android.system.OsConstants.F_OK; 113 import static android.system.OsConstants.IPPROTO_TCP; 114 import static android.system.OsConstants.IPPROTO_UDP; 115 116 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_GETSOCKOPT; 117 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND; 118 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_CONNECT; 119 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND; 120 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_CONNECT; 121 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS; 122 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS; 123 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE; 124 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_RELEASE; 125 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_SETSOCKOPT; 126 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_RECVMSG; 127 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_SENDMSG; 128 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_RECVMSG; 129 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_SENDMSG; 130 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired; 131 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf; 132 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission; 133 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr; 134 import static com.android.net.module.util.PermissionUtils.hasAnyPermissionOf; 135 import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE; 136 import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS; 137 import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI; 138 import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING; 139 140 import static java.util.Map.Entry; 141 142 import android.Manifest; 143 import android.annotation.CheckResult; 144 import android.annotation.NonNull; 145 import android.annotation.Nullable; 146 import android.annotation.RequiresApi; 147 import android.annotation.SuppressLint; 148 import android.annotation.TargetApi; 149 import android.app.ActivityManager; 150 import android.app.ActivityManager.UidFrozenStateChangedCallback; 151 import android.app.AppOpsManager; 152 import android.app.BroadcastOptions; 153 import android.app.PendingIntent; 154 import android.app.admin.DevicePolicyManager; 155 import android.app.compat.CompatChanges; 156 import android.app.usage.NetworkStatsManager; 157 import android.content.BroadcastReceiver; 158 import android.content.ComponentName; 159 import android.content.ContentResolver; 160 import android.content.Context; 161 import android.content.Intent; 162 import android.content.IntentFilter; 163 import android.content.pm.PackageManager; 164 import android.content.res.XmlResourceParser; 165 import android.database.ContentObserver; 166 import android.net.BpfNetMapsUtils; 167 import android.net.CaptivePortal; 168 import android.net.CaptivePortalData; 169 import android.net.ConnectionInfo; 170 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 171 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 172 import android.net.ConnectivityManager; 173 import android.net.ConnectivityManager.BlockedReason; 174 import android.net.ConnectivityManager.NetworkCallback; 175 import android.net.ConnectivityManager.RestrictBackgroundStatus; 176 import android.net.ConnectivitySettingsManager; 177 import android.net.DataStallReportParcelable; 178 import android.net.DnsResolverServiceManager; 179 import android.net.DscpPolicy; 180 import android.net.ICaptivePortal; 181 import android.net.IConnectivityDiagnosticsCallback; 182 import android.net.IConnectivityManager; 183 import android.net.IDnsResolver; 184 import android.net.INetd; 185 import android.net.INetworkActivityListener; 186 import android.net.INetworkAgent; 187 import android.net.INetworkMonitor; 188 import android.net.INetworkMonitorCallbacks; 189 import android.net.INetworkOfferCallback; 190 import android.net.IOnCompleteListener; 191 import android.net.IQosCallback; 192 import android.net.ISocketKeepaliveCallback; 193 import android.net.InetAddresses; 194 import android.net.IpMemoryStore; 195 import android.net.IpPrefix; 196 import android.net.LinkProperties; 197 import android.net.LocalNetworkConfig; 198 import android.net.LocalNetworkInfo; 199 import android.net.MatchAllNetworkSpecifier; 200 import android.net.MulticastRoutingConfig; 201 import android.net.NativeNetworkConfig; 202 import android.net.NativeNetworkType; 203 import android.net.NattSocketKeepalive; 204 import android.net.Network; 205 import android.net.NetworkAgent; 206 import android.net.NetworkAgentConfig; 207 import android.net.NetworkCapabilities; 208 import android.net.NetworkInfo; 209 import android.net.NetworkInfo.DetailedState; 210 import android.net.NetworkMonitorManager; 211 import android.net.NetworkPolicyManager; 212 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 213 import android.net.NetworkProvider; 214 import android.net.NetworkRequest; 215 import android.net.NetworkScore; 216 import android.net.NetworkSpecifier; 217 import android.net.NetworkStack; 218 import android.net.NetworkState; 219 import android.net.NetworkStateSnapshot; 220 import android.net.NetworkTestResultParcelable; 221 import android.net.NetworkUtils; 222 import android.net.NetworkWatchlistManager; 223 import android.net.OemNetworkPreferences; 224 import android.net.PrivateDnsConfigParcel; 225 import android.net.ProfileNetworkPreference; 226 import android.net.ProxyInfo; 227 import android.net.QosCallbackException; 228 import android.net.QosFilter; 229 import android.net.QosSocketFilter; 230 import android.net.QosSocketInfo; 231 import android.net.RouteInfo; 232 import android.net.SocketKeepalive; 233 import android.net.TetheringManager; 234 import android.net.TransportInfo; 235 import android.net.UidRange; 236 import android.net.UidRangeParcel; 237 import android.net.UnderlyingNetworkInfo; 238 import android.net.Uri; 239 import android.net.VpnManager; 240 import android.net.VpnTransportInfo; 241 import android.net.metrics.IpConnectivityLog; 242 import android.net.metrics.NetworkEvent; 243 import android.net.netd.aidl.NativeUidRangeConfig; 244 import android.net.networkstack.ModuleNetworkStackClient; 245 import android.net.networkstack.NetworkStackClientBase; 246 import android.net.networkstack.aidl.NetworkMonitorParameters; 247 import android.net.resolv.aidl.DnsHealthEventParcel; 248 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; 249 import android.net.resolv.aidl.Nat64PrefixEventParcel; 250 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 251 import android.net.shared.PrivateDnsConfig; 252 import android.net.wifi.WifiInfo; 253 import android.os.BatteryStatsManager; 254 import android.os.Binder; 255 import android.os.Build; 256 import android.os.Bundle; 257 import android.os.ConditionVariable; 258 import android.os.Handler; 259 import android.os.HandlerThread; 260 import android.os.IBinder; 261 import android.os.Looper; 262 import android.os.Message; 263 import android.os.Messenger; 264 import android.os.ParcelFileDescriptor; 265 import android.os.Parcelable; 266 import android.os.PersistableBundle; 267 import android.os.PowerManager; 268 import android.os.Process; 269 import android.os.RemoteCallbackList; 270 import android.os.RemoteException; 271 import android.os.ServiceSpecificException; 272 import android.os.SystemClock; 273 import android.os.SystemProperties; 274 import android.os.UserHandle; 275 import android.os.UserManager; 276 import android.provider.Settings; 277 import android.stats.connectivity.MeteredState; 278 import android.stats.connectivity.RequestType; 279 import android.stats.connectivity.ValidatedState; 280 import android.sysprop.NetworkProperties; 281 import android.system.ErrnoException; 282 import android.system.Os; 283 import android.telephony.SubscriptionManager; 284 import android.telephony.TelephonyManager; 285 import android.text.TextUtils; 286 import android.util.ArrayMap; 287 import android.util.ArraySet; 288 import android.util.LocalLog; 289 import android.util.Log; 290 import android.util.Pair; 291 import android.util.Range; 292 import android.util.SparseArray; 293 import android.util.SparseIntArray; 294 import android.util.StatsEvent; 295 296 import com.android.connectivity.resources.R; 297 import com.android.internal.annotations.GuardedBy; 298 import com.android.internal.annotations.VisibleForTesting; 299 import com.android.internal.util.IndentingPrintWriter; 300 import com.android.internal.util.MessageUtils; 301 import com.android.metrics.ConnectionDurationForTransports; 302 import com.android.metrics.ConnectionDurationPerTransports; 303 import com.android.metrics.ConnectivitySampleMetricsHelper; 304 import com.android.metrics.ConnectivityStateSample; 305 import com.android.metrics.NetworkCountForTransports; 306 import com.android.metrics.NetworkCountPerTransports; 307 import com.android.metrics.NetworkDescription; 308 import com.android.metrics.NetworkList; 309 import com.android.metrics.NetworkRequestCount; 310 import com.android.metrics.RequestCountForType; 311 import com.android.modules.utils.BasicShellCommandHandler; 312 import com.android.modules.utils.build.SdkLevel; 313 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 314 import com.android.net.module.util.BinderUtils; 315 import com.android.net.module.util.BitUtils; 316 import com.android.net.module.util.BpfUtils; 317 import com.android.net.module.util.CollectionUtils; 318 import com.android.net.module.util.DeviceConfigUtils; 319 import com.android.net.module.util.HandlerUtils; 320 import com.android.net.module.util.InterfaceParams; 321 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; 322 import com.android.net.module.util.LinkPropertiesUtils.CompareResult; 323 import com.android.net.module.util.LocationPermissionChecker; 324 import com.android.net.module.util.PerUidCounter; 325 import com.android.net.module.util.PermissionUtils; 326 import com.android.net.module.util.TcUtils; 327 import com.android.net.module.util.netlink.InetDiagMessage; 328 import com.android.networkstack.apishim.BroadcastOptionsShimImpl; 329 import com.android.networkstack.apishim.ConstantsShim; 330 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 331 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 332 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 333 import com.android.server.connectivity.AutodestructReference; 334 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 335 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive; 336 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 337 import com.android.server.connectivity.ClatCoordinator; 338 import com.android.server.connectivity.ConnectivityFlags; 339 import com.android.server.connectivity.ConnectivityResources; 340 import com.android.server.connectivity.DnsManager; 341 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; 342 import com.android.server.connectivity.DscpPolicyTracker; 343 import com.android.server.connectivity.FullScore; 344 import com.android.server.connectivity.InvalidTagException; 345 import com.android.server.connectivity.KeepaliveResourceUtil; 346 import com.android.server.connectivity.KeepaliveTracker; 347 import com.android.server.connectivity.LingerMonitor; 348 import com.android.server.connectivity.MockableSystemProperties; 349 import com.android.server.connectivity.MulticastRoutingCoordinatorService; 350 import com.android.server.connectivity.MultinetworkPolicyTracker; 351 import com.android.server.connectivity.NetworkAgentInfo; 352 import com.android.server.connectivity.NetworkDiagnostics; 353 import com.android.server.connectivity.NetworkNotificationManager; 354 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 355 import com.android.server.connectivity.NetworkOffer; 356 import com.android.server.connectivity.NetworkPreferenceList; 357 import com.android.server.connectivity.NetworkRanker; 358 import com.android.server.connectivity.NetworkRequestStateStatsMetrics; 359 import com.android.server.connectivity.PermissionMonitor; 360 import com.android.server.connectivity.ProfileNetworkPreferenceInfo; 361 import com.android.server.connectivity.ProxyTracker; 362 import com.android.server.connectivity.QosCallbackTracker; 363 import com.android.server.connectivity.RoutingCoordinatorService; 364 import com.android.server.connectivity.SatelliteAccessController; 365 import com.android.server.connectivity.UidRangeUtils; 366 import com.android.server.connectivity.VpnNetworkPreferenceInfo; 367 import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService; 368 369 import libcore.io.IoUtils; 370 371 import org.xmlpull.v1.XmlPullParserException; 372 373 import java.io.FileDescriptor; 374 import java.io.IOException; 375 import java.io.InterruptedIOException; 376 import java.io.PrintWriter; 377 import java.io.Writer; 378 import java.net.Inet4Address; 379 import java.net.InetAddress; 380 import java.net.InetSocketAddress; 381 import java.net.SocketException; 382 import java.net.UnknownHostException; 383 import java.util.ArrayList; 384 import java.util.Arrays; 385 import java.util.Collection; 386 import java.util.Collections; 387 import java.util.Comparator; 388 import java.util.ConcurrentModificationException; 389 import java.util.HashMap; 390 import java.util.HashSet; 391 import java.util.List; 392 import java.util.Map; 393 import java.util.Map.Entry; 394 import java.util.NoSuchElementException; 395 import java.util.Objects; 396 import java.util.Random; 397 import java.util.Set; 398 import java.util.SortedSet; 399 import java.util.StringJoiner; 400 import java.util.TreeSet; 401 import java.util.concurrent.TimeUnit; 402 import java.util.concurrent.atomic.AtomicInteger; 403 import java.util.function.BiConsumer; 404 import java.util.function.Consumer; 405 406 /** 407 * @hide 408 */ 409 public class ConnectivityService extends IConnectivityManager.Stub 410 implements PendingIntent.OnFinished { 411 private static final String TAG = ConnectivityService.class.getSimpleName(); 412 413 private static final String DIAG_ARG = "--diag"; 414 public static final String SHORT_ARG = "--short"; 415 private static final String NETWORK_ARG = "networks"; 416 private static final String REQUEST_ARG = "requests"; 417 private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller"; 418 public static final String CLATEGRESS4RAWBPFMAP_ARG = "clatEgress4RawBpfMap"; 419 public static final String CLATINGRESS6RAWBPFMAP_ARG = "clatIngress6RawBpfMap"; 420 421 private static final boolean DBG = true; 422 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); 423 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 424 425 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 426 427 /** 428 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed 429 * by OEMs for configuration purposes, as this value is overridden by 430 * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL. 431 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose 432 * (preferably via runtime resource overlays). 433 */ 434 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL = 435 "http://connectivitycheck.gstatic.com/generate_204"; 436 437 // TODO: create better separation between radio types and network types 438 439 // how long to wait before switching back to a radio's default network 440 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 441 // system property that can override the above value 442 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 443 "android.telephony.apn-restore"; 444 445 // How long to wait before putting up a "This network doesn't have an Internet connection, 446 // connect anyway?" dialog after the user selects a network that doesn't validate. 447 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 448 449 // How long to wait before considering that a network is bad in the absence of any form 450 // of connectivity (valid, partial, captive portal). If none has been detected after this 451 // delay, the stack considers this network bad, which may affect how it's handled in ranking 452 // according to config_networkAvoidBadWifi. 453 // Timeout in case the "actively prefer bad wifi" feature is on 454 private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000; 455 // Timeout in case the "actively prefer bad wifi" feature is off 456 private static final int DEFAULT_EVALUATION_TIMEOUT_MS = 8 * 1000; 457 458 // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing. 459 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 460 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 461 private static final int DEFAULT_NASCENT_DELAY_MS = 5_000; 462 463 // Delimiter used when creating the broadcast delivery group for sending 464 // CONNECTIVITY_ACTION broadcast. 465 private static final char DELIVERY_GROUP_KEY_DELIMITER = ';'; 466 467 // The maximum value for the blocking validation result, in milliseconds. 468 public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000; 469 470 // The maximum number of network request allowed per uid before an exception is thrown. 471 @VisibleForTesting 472 static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 473 474 // The maximum number of network request allowed for system UIDs before an exception is thrown. 475 @VisibleForTesting 476 static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250; 477 478 @VisibleForTesting 479 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 480 @VisibleForTesting 481 protected int mNascentDelayMs; 482 // True if the cell radio of the device is capable of time-sharing. 483 @VisibleForTesting 484 protected boolean mCellularRadioTimesharingCapable = true; 485 486 // How long to delay to removal of a pending intent based request. 487 // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 488 private final int mReleasePendingIntentDelayMs; 489 490 private final MockableSystemProperties mSystemProperties; 491 492 private final PermissionMonitor mPermissionMonitor; 493 494 @VisibleForTesting 495 final RequestInfoPerUidCounter mNetworkRequestCounter; 496 @VisibleForTesting 497 final RequestInfoPerUidCounter mSystemNetworkRequestCounter; 498 499 private volatile boolean mLockdownEnabled; 500 501 private final boolean mRequestRestrictedWifiEnabled; 502 private final boolean mBackgroundFirewallChainEnabled; 503 504 private final boolean mUseDeclaredMethodsForCallbacksEnabled; 505 506 /** 507 * Uids ConnectivityService tracks blocked status of to send blocked status callbacks. 508 * Key is uid based on mAsUid of registered networkRequestInfo 509 * Value is count of registered networkRequestInfo 510 * 511 * This is necessary because when a firewall chain is enabled or disabled, that affects all UIDs 512 * on the system, not just UIDs on that firewall chain. For example, entering doze mode affects 513 * all UIDs that are not on the dozable chain. ConnectivityService doesn't know which UIDs are 514 * running. But it only needs to send onBlockedStatusChanged to UIDs that have at least one 515 * NetworkCallback registered. 516 * 517 * UIDs are added to this list on the binder thread when processing requestNetwork and similar 518 * IPCs. They are removed from this list on the handler thread, when the callback unregistration 519 * is fully processed. They cannot be unregistered when the unregister IPC is processed because 520 * sometimes requests are unregistered on the handler thread. 521 */ 522 @GuardedBy("mBlockedStatusTrackingUids") 523 private final SparseIntArray mBlockedStatusTrackingUids = new SparseIntArray(); 524 525 /** 526 * Stale copy of UID blocked reasons. This is used to send onBlockedStatusChanged 527 * callbacks. This is only used on the handler thread, so it does not require a lock. 528 * On U-, the blocked reasons come from NPMS. 529 * On V+, the blocked reasons come from the BPF map contents and only maintains blocked reasons 530 * of uids that register network callbacks. 531 */ 532 private final SparseIntArray mUidBlockedReasons = new SparseIntArray(); 533 534 private final Context mContext; 535 private final ConnectivityResources mResources; 536 private final int mWakeUpMark; 537 private final int mWakeUpMask; 538 // The Context is created for UserHandle.ALL. 539 private final Context mUserAllContext; 540 private final Dependencies mDeps; 541 private final ConnectivityFlags mFlags; 542 // 0 is full bad, 100 is full good 543 private int mDefaultInetConditionPublished = 0; 544 545 @VisibleForTesting 546 protected IDnsResolver mDnsResolver; 547 @VisibleForTesting 548 protected INetd mNetd; 549 private DscpPolicyTracker mDscpPolicyTracker = null; 550 private final NetworkStatsManager mStatsManager; 551 private final NetworkPolicyManager mPolicyManager; 552 private final BpfNetMaps mBpfNetMaps; 553 554 /** 555 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple 556 * instances. 557 */ 558 @GuardedBy("mTNSLock") 559 private TestNetworkService mTNS; 560 private final CompanionDeviceManagerProxyService mCdmps; 561 private final MulticastRoutingCoordinatorService mMulticastRoutingCoordinatorService; 562 private final RoutingCoordinatorService mRoutingCoordinatorService; 563 564 private final Object mTNSLock = new Object(); 565 566 private String mCurrentTcpBufferSizes; 567 568 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 569 new Class[] { 570 ConnectivityService.class, 571 NetworkAgent.class, 572 NetworkAgentInfo.class, 573 AutomaticOnOffKeepaliveTracker.class }); 574 575 private enum ReapUnvalidatedNetworks { 576 // Tear down networks that have no chance (e.g. even if validated) of becoming 577 // the highest scoring network satisfying a NetworkRequest. This should be passed when 578 // all networks have been rematched against all NetworkRequests. 579 REAP, 580 // Don't reap networks. This should be passed when some networks have not yet been 581 // rematched against all NetworkRequests. 582 DONT_REAP 583 } 584 585 private enum UnneededFor { 586 LINGER, // Determine whether this network is unneeded and should be lingered. 587 TEARDOWN, // Determine whether this network is unneeded and should be torn down. 588 } 589 590 /** 591 * For per-app preferences, requests contain an int to signify which request 592 * should have priority. The order is passed to netd which will use it together 593 * with UID ranges to generate the corresponding IP rule. This serves to 594 * direct device-originated data traffic of the specific UIDs to the correct 595 * default network for each app. 596 * Order ints passed to netd must be in the 0~999 range. Larger values code for 597 * a lower priority, see {@link NativeUidRangeConfig}. 598 * Note that only the highest priority preference is applied if the uid is the target of 599 * multiple preferences. 600 * 601 * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID. 602 * The default request uses PREFERENCE_ORDER_DEFAULT. 603 */ 604 // Used when sending to netd to code for "no order". 605 static final int PREFERENCE_ORDER_NONE = 0; 606 // Order for requests that don't code for a per-app preference. As it is 607 // out of the valid range, the corresponding order should be 608 // PREFERENCE_ORDER_NONE when sending to netd. 609 @VisibleForTesting 610 static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE; 611 // As a security feature, VPNs have the top priority. 612 static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN. 613 // Order of per-app OEM preference. See {@link #setOemNetworkPreference}. 614 @VisibleForTesting 615 static final int PREFERENCE_ORDER_OEM = 10; 616 // Order of per-profile preference, such as used by enterprise networks. 617 // See {@link #setProfileNetworkPreference}. 618 @VisibleForTesting 619 static final int PREFERENCE_ORDER_PROFILE = 20; 620 // Order of user setting to prefer mobile data even when networks with 621 // better scores are connected. 622 // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids} 623 @VisibleForTesting 624 static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30; 625 // Order of setting satellite network preference fallback when default message application 626 // with role_sms role and android.permission.SATELLITE_COMMUNICATION permission detected 627 @VisibleForTesting 628 static final int PREFERENCE_ORDER_SATELLITE_FALLBACK = 40; 629 // Preference order that signifies the network shouldn't be set as a default network for 630 // the UIDs, only give them access to it. TODO : replace this with a boolean 631 // in NativeUidRangeConfig 632 @VisibleForTesting 633 static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999; 634 // Bound for the lowest valid preference order. 635 static final int PREFERENCE_ORDER_LOWEST = 999; 636 637 /** 638 * used internally to clear a wakelock when transitioning 639 * from one net to another. Clear happens when we get a new 640 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 641 * after a timeout if no network is found (typically 1 min). 642 */ 643 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 644 645 /** 646 * used internally to reload global proxy settings 647 */ 648 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 649 650 /** 651 * PAC manager has received new port. 652 */ 653 private static final int EVENT_PAC_PROXY_HAS_CHANGED = 16; 654 655 /** 656 * used internally when registering NetworkProviders 657 * obj = NetworkProviderInfo 658 */ 659 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; 660 661 /** 662 * used internally when registering NetworkAgents 663 * obj = Messenger 664 */ 665 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 666 667 /** 668 * used to add a network request 669 * includes a NetworkRequestInfo 670 */ 671 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 672 673 /** 674 * indicates a timeout period is over - check if we had a network yet or not 675 * and if not, call the timeout callback (but leave the request live until they 676 * cancel it. 677 * includes a NetworkRequestInfo 678 */ 679 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 680 681 /** 682 * used to add a network listener - no request 683 * includes a NetworkRequestInfo 684 */ 685 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 686 687 /** 688 * used to remove a network request, either a listener or a real request 689 * arg1 = UID of caller 690 * obj = NetworkRequest 691 */ 692 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 693 694 /** 695 * used internally when registering NetworkProviders 696 * obj = Messenger 697 */ 698 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; 699 700 /** 701 * used internally to expire a wakelock when transitioning 702 * from one net to another. Expire happens when we fail to find 703 * a new network (typically after 1 minute) - 704 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 705 * a replacement network. 706 */ 707 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 708 709 /** 710 * used to add a network request with a pending intent 711 * obj = NetworkRequestInfo 712 */ 713 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 714 715 /** 716 * used to remove a pending intent and its associated network request. 717 * arg1 = UID of caller 718 * obj = PendingIntent 719 */ 720 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 721 722 /** 723 * used to specify whether a network should be used even if unvalidated. 724 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 725 * arg2 = whether to remember this choice in the future (1 or 0) 726 * obj = network 727 */ 728 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 729 730 /** 731 * used internally to (re)configure always-on networks. 732 */ 733 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; 734 735 /** 736 * used to add a network listener with a pending intent 737 * obj = NetworkRequestInfo 738 */ 739 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 740 741 /** 742 * used to specify whether a network should not be penalized when it becomes unvalidated. 743 */ 744 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 745 746 /** 747 * used to handle reported network connectivity. May trigger revalidation of a network. 748 */ 749 private static final int EVENT_REPORT_NETWORK_CONNECTIVITY = 36; 750 751 // Handle changes in Private DNS settings. 752 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; 753 754 // Handle private DNS validation status updates. 755 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; 756 757 /** 758 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has 759 * been tested. 760 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor. 761 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link 762 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null. 763 */ 764 private static final int EVENT_NETWORK_TESTED = 41; 765 766 /** 767 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS 768 * config was resolved. 769 * obj = PrivateDnsConfig 770 * arg2 = netid 771 */ 772 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; 773 774 /** 775 * Request ConnectivityService display provisioning notification. 776 * arg1 = Whether to make the notification visible. 777 * arg2 = NetID. 778 * obj = Intent to be launched when notification selected by user, null if !arg1. 779 */ 780 private static final int EVENT_PROVISIONING_NOTIFICATION = 43; 781 782 /** 783 * Used to specify whether a network should be used even if connectivity is partial. 784 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for 785 * false) 786 * arg2 = whether to remember this choice in the future (1 for true or 0 for false) 787 * obj = network 788 */ 789 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44; 790 791 /** 792 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed. 793 * Both of the arguments are bitmasks, and the value of bits come from 794 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*. 795 * arg1 = unused 796 * arg2 = netId 797 * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes. 798 */ 799 public static final int EVENT_PROBE_STATUS_CHANGED = 45; 800 801 /** 802 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed. 803 * arg1 = unused 804 * arg2 = netId 805 * obj = captive portal data 806 */ 807 private static final int EVENT_CAPPORT_DATA_CHANGED = 46; 808 809 /** 810 * Used by setRequireVpnForUids. 811 * arg1 = whether the specified UID ranges are required to use a VPN. 812 * obj = Array of UidRange objects. 813 */ 814 private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47; 815 816 /** 817 * Used internally when setting the default networks for OemNetworkPreferences. 818 * obj = Pair<OemNetworkPreferences, listener> 819 */ 820 private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48; 821 822 /** 823 * Used to indicate the system default network becomes active. 824 */ 825 private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49; 826 827 /** 828 * Used internally when setting a network preference for a user profile. 829 * obj = Pair<ProfileNetworkPreference, Listener> 830 */ 831 private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50; 832 833 /** 834 * Event to update blocked reasons for uids. 835 * obj = List of Pair(uid, blockedReasons) 836 */ 837 private static final int EVENT_BLOCKED_REASONS_CHANGED = 51; 838 839 /** 840 * Event to register a new network offer 841 * obj = NetworkOffer 842 */ 843 private static final int EVENT_REGISTER_NETWORK_OFFER = 52; 844 845 /** 846 * Event to unregister an existing network offer 847 * obj = INetworkOfferCallback 848 */ 849 private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53; 850 851 /** 852 * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed. 853 */ 854 private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54; 855 856 /** 857 * Event to set temporary allow bad wifi within a limited time to override 858 * {@code config_networkAvoidBadWifi}. 859 */ 860 private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55; 861 862 /** 863 * Used internally when INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting changes. 864 */ 865 private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56; 866 867 /** 868 * The initial evaluation period is over for this network. 869 * 870 * If no form of connectivity has been found on this network (valid, partial, captive portal) 871 * then the stack will now consider it to have been determined bad. 872 */ 873 private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57; 874 875 /** 876 * Used internally when the user does not want the network from captive portal app. 877 * obj = Network 878 */ 879 private static final int EVENT_USER_DOES_NOT_WANT = 58; 880 881 /** 882 * Event to set VPN as preferred network for specific apps. 883 * obj = VpnNetworkPreferenceInfo 884 */ 885 private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59; 886 887 /** 888 * Event to use low TCP polling timer used in automatic on/off keepalive temporarily. 889 */ 890 private static final int EVENT_SET_LOW_TCP_POLLING_UNTIL = 60; 891 892 /** 893 * Event to inform the ConnectivityService handler when a uid has been frozen or unfrozen. 894 */ 895 private static final int EVENT_UID_FROZEN_STATE_CHANGED = 61; 896 897 /** 898 * Event to update firewall socket destroy reasons for uids. 899 * obj = List of Pair(uid, socketDestroyReasons) 900 */ 901 private static final int EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS = 62; 902 903 /** 904 * Event to clear firewall socket destroy reasons for all uids. 905 * arg1 = socketDestroyReason 906 */ 907 private static final int EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS = 63; 908 909 /** 910 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 911 * should be shown. 912 */ 913 private static final int PROVISIONING_NOTIFICATION_SHOW = 1; 914 915 /** 916 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 917 * should be hidden. 918 */ 919 private static final int PROVISIONING_NOTIFICATION_HIDE = 0; 920 921 /** 922 * The maximum alive time to allow bad wifi configuration for testing. 923 */ 924 private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L; 925 926 /** 927 * The maximum alive time to decrease TCP polling timer in automatic on/off keepalive for 928 * testing. 929 */ 930 private static final long MAX_TEST_LOW_TCP_POLLING_UNTIL_MS = 5 * 60 * 1000L; 931 932 /** 933 * The priority of the tc police rate limiter -- smaller value is higher priority. 934 * This value needs to be coordinated with PRIO_CLAT, PRIO_TETHER4, and PRIO_TETHER6. 935 */ 936 private static final short TC_PRIO_POLICE = 1; 937 938 /** 939 * The BPF program attached to the tc-police hook to account for to-be-dropped traffic. 940 */ 941 private static final String TC_POLICE_BPF_PROG_PATH = 942 "/sys/fs/bpf/netd_shared/prog_netd_schedact_ingress_account"; 943 eventName(int what)944 private static String eventName(int what) { 945 return sMagicDecoderRing.get(what, Integer.toString(what)); 946 } 947 getDnsResolver(Context context)948 private static IDnsResolver getDnsResolver(Context context) { 949 final DnsResolverServiceManager dsm = context.getSystemService( 950 DnsResolverServiceManager.class); 951 return IDnsResolver.Stub.asInterface(dsm.getService()); 952 } 953 954 /** Handler thread used for all of the handlers below. */ 955 @VisibleForTesting 956 protected final HandlerThread mHandlerThread; 957 /** Handler used for internal events. */ 958 final private InternalHandler mHandler; 959 /** Handler used for incoming {@link NetworkStateTracker} events. */ 960 final private NetworkStateTrackerHandler mTrackerHandler; 961 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */ 962 @VisibleForTesting 963 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler; 964 965 private final DnsManager mDnsManager; 966 @VisibleForTesting 967 final NetworkRanker mNetworkRanker; 968 969 private boolean mSystemReady; 970 private Intent mInitialBroadcast; 971 972 private final PowerManager.WakeLock mNetTransitionWakeLock; 973 private final PowerManager.WakeLock mPendingIntentWakeLock; 974 975 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell 976 // the world when it changes. 977 private final ProxyTracker mProxyTracker; 978 979 final private SettingsObserver mSettingsObserver; 980 981 private final UserManager mUserManager; 982 983 // the set of network types that can only be enabled by system/sig apps 984 private final List<Integer> mProtectedNetworks; 985 986 private Set<String> mWolSupportedInterfaces; 987 988 private final TelephonyManager mTelephonyManager; 989 private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 990 private final AppOpsManager mAppOpsManager; 991 992 private final LocationPermissionChecker mLocationPermissionChecker; 993 994 private final AutomaticOnOffKeepaliveTracker mKeepaliveTracker; 995 private final QosCallbackTracker mQosCallbackTracker; 996 private final NetworkNotificationManager mNotifier; 997 private final LingerMonitor mLingerMonitor; 998 private final SatelliteAccessController mSatelliteAccessController; 999 1000 // sequence number of NetworkRequests 1001 private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID; 1002 1003 // Sequence number for NetworkProvider IDs. 1004 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( 1005 NetworkProvider.FIRST_PROVIDER_ID); 1006 1007 // NetworkRequest activity String log entries. 1008 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 1009 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 1010 1011 // NetworkInfo blocked and unblocked String log entries 1012 private static final int MAX_NETWORK_INFO_LOGS = 40; 1013 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 1014 1015 private static final int MAX_WAKELOCK_LOGS = 20; 1016 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS); 1017 private int mTotalWakelockAcquisitions = 0; 1018 private int mTotalWakelockReleases = 0; 1019 private long mTotalWakelockDurationMs = 0; 1020 private long mMaxWakelockDurationMs = 0; 1021 private long mLastWakeLockAcquireTimestamp = 0; 1022 1023 private final IpConnectivityLog mMetricsLog; 1024 1025 @Nullable private final NetworkRequestStateStatsMetrics mNetworkRequestStateStatsMetrics; 1026 1027 @GuardedBy("mBandwidthRequests") 1028 private final SparseArray<Integer> mBandwidthRequests = new SparseArray<>(10); 1029 1030 @VisibleForTesting 1031 final MultinetworkPolicyTracker mMultinetworkPolicyTracker; 1032 1033 @VisibleForTesting 1034 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks = 1035 new HashMap<>(); 1036 1037 // Rate limit applicable to all internet capable networks (-1 = disabled). This value is 1038 // configured via {@link 1039 // ConnectivitySettingsManager#INGRESS_RATE_LIMIT_BYTES_PER_SECOND} 1040 // Only the handler thread is allowed to access this field. 1041 private long mIngressRateLimit = -1; 1042 1043 // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This 1044 // value can be accessed from both handler thread and any random binder thread. Therefore, 1045 // accessing this value requires holding a lock. The cache is the same across all the users. 1046 @GuardedBy("mSelfCertifiedCapabilityCache") 1047 private final Map<String, ApplicationSelfCertifiedNetworkCapabilities> 1048 mSelfCertifiedCapabilityCache = new HashMap<>(); 1049 1050 // Flag to enable the feature of closing frozen app sockets. 1051 private final boolean mDestroyFrozenSockets; 1052 1053 // Flag to optimize closing app sockets by waiting for the cellular modem to wake up. 1054 private final boolean mDelayDestroySockets; 1055 1056 // Flag to allow SysUI to receive connectivity reports for wifi picker UI. 1057 private final boolean mAllowSysUiConnectivityReports; 1058 1059 // Uids that ConnectivityService is pending to close sockets of. 1060 // Key is uid and value is reasons of socket destroy 1061 private final SparseIntArray mDestroySocketPendingUids = new SparseIntArray(); 1062 1063 private static final int DESTROY_SOCKET_REASON_NONE = 0; 1064 private static final int DESTROY_SOCKET_REASON_FROZEN = 1 << 0; 1065 private static final int DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND = 1 << 1; 1066 1067 // Flag to drop packets to VPN addresses ingressing via non-VPN interfaces. 1068 private final boolean mIngressToVpnAddressFiltering; 1069 1070 /** 1071 * Implements support for the legacy "one network per network type" model. 1072 * 1073 * We used to have a static array of NetworkStateTrackers, one for each 1074 * network type, but that doesn't work any more now that we can have, 1075 * for example, more that one wifi network. This class stores all the 1076 * NetworkAgentInfo objects that support a given type, but the legacy 1077 * API will only see the first one. 1078 * 1079 * It serves two main purposes: 1080 * 1081 * 1. Provide information about "the network for a given type" (since this 1082 * API only supports one). 1083 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 1084 * the first network for a given type changes, or if the default network 1085 * changes. 1086 */ 1087 @VisibleForTesting 1088 static class LegacyTypeTracker { 1089 1090 private static final boolean DBG = true; 1091 private static final boolean VDBG = false; 1092 1093 /** 1094 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 1095 * Each list holds references to all NetworkAgentInfos that are used to 1096 * satisfy requests for that network type. 1097 * 1098 * This array is built out at startup such that an unsupported network 1099 * doesn't get an ArrayList instance, making this a tristate: 1100 * unsupported, supported but not active and active. 1101 * 1102 * The actual lists are populated when we scan the network types that 1103 * are supported on this device. 1104 * 1105 * Threading model: 1106 * - addSupportedType() is only called in the constructor 1107 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 1108 * They are therefore not thread-safe with respect to each other. 1109 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 1110 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 1111 * - getRestoreTimerForType(type) is also synchronized on mTypeLists. 1112 * - dump is thread-safe with respect to concurrent add and remove calls. 1113 */ 1114 private final ArrayList<NetworkAgentInfo>[] mTypeLists; 1115 @NonNull 1116 private final ConnectivityService mService; 1117 1118 // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without 1119 // an entry have no timer (equivalent to -1). Lazily loaded. 1120 @NonNull 1121 private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>(); 1122 LegacyTypeTracker(@onNull ConnectivityService service)1123 LegacyTypeTracker(@NonNull ConnectivityService service) { 1124 mService = service; 1125 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 1126 } 1127 1128 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is 1129 // addressed. 1130 @TargetApi(Build.VERSION_CODES.S) loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)1131 public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) { 1132 final PackageManager pm = ctx.getPackageManager(); 1133 if (pm.hasSystemFeature(FEATURE_WIFI)) { 1134 addSupportedType(TYPE_WIFI); 1135 } 1136 if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) { 1137 addSupportedType(TYPE_WIFI_P2P); 1138 } 1139 if (tm.isDataCapable()) { 1140 // Telephony does not have granular support for these types: they are either all 1141 // supported, or none is supported 1142 addSupportedType(TYPE_MOBILE); 1143 addSupportedType(TYPE_MOBILE_MMS); 1144 addSupportedType(TYPE_MOBILE_SUPL); 1145 addSupportedType(TYPE_MOBILE_DUN); 1146 addSupportedType(TYPE_MOBILE_HIPRI); 1147 addSupportedType(TYPE_MOBILE_FOTA); 1148 addSupportedType(TYPE_MOBILE_IMS); 1149 addSupportedType(TYPE_MOBILE_CBS); 1150 addSupportedType(TYPE_MOBILE_IA); 1151 addSupportedType(TYPE_MOBILE_EMERGENCY); 1152 } 1153 if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) { 1154 addSupportedType(TYPE_BLUETOOTH); 1155 } 1156 if (pm.hasSystemFeature(FEATURE_WATCH)) { 1157 // TYPE_PROXY is only used on Wear 1158 addSupportedType(TYPE_PROXY); 1159 } 1160 // Ethernet is often not specified in the configs, although many devices can use it via 1161 // USB host adapters. Add it as long as the ethernet service is here. 1162 if (deviceSupportsEthernet(ctx)) { 1163 addSupportedType(TYPE_ETHERNET); 1164 } 1165 1166 // Always add TYPE_VPN as a supported type 1167 addSupportedType(TYPE_VPN); 1168 } 1169 addSupportedType(int type)1170 private void addSupportedType(int type) { 1171 if (mTypeLists[type] != null) { 1172 throw new IllegalStateException( 1173 "legacy list for type " + type + "already initialized"); 1174 } 1175 mTypeLists[type] = new ArrayList<>(); 1176 } 1177 isTypeSupported(int type)1178 public boolean isTypeSupported(int type) { 1179 return isNetworkTypeValid(type) && mTypeLists[type] != null; 1180 } 1181 getNetworkForType(int type)1182 public NetworkAgentInfo getNetworkForType(int type) { 1183 synchronized (mTypeLists) { 1184 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 1185 return mTypeLists[type].get(0); 1186 } 1187 } 1188 return null; 1189 } 1190 getRestoreTimerForType(int type)1191 public int getRestoreTimerForType(int type) { 1192 synchronized (mTypeLists) { 1193 if (mRestoreTimers == null) { 1194 mRestoreTimers = loadRestoreTimers(); 1195 } 1196 return mRestoreTimers.getOrDefault(type, -1); 1197 } 1198 } 1199 loadRestoreTimers()1200 private ArrayMap<Integer, Integer> loadRestoreTimers() { 1201 final String[] configs = mService.mResources.get().getStringArray( 1202 R.array.config_legacy_networktype_restore_timers); 1203 final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length); 1204 for (final String config : configs) { 1205 final String[] splits = TextUtils.split(config, ","); 1206 if (splits.length != 2) { 1207 logwtf("Invalid restore timer token count: " + config); 1208 continue; 1209 } 1210 try { 1211 ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1])); 1212 } catch (NumberFormatException e) { 1213 logwtf("Invalid restore timer number format: " + config, e); 1214 } 1215 } 1216 return ret; 1217 } 1218 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)1219 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 1220 boolean isDefaultNetwork) { 1221 if (DBG) { 1222 log("Sending " + state 1223 + " broadcast for type " + type + " " + nai.toShortString() 1224 + " isDefaultNetwork=" + isDefaultNetwork); 1225 } 1226 } 1227 1228 // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying 1229 // network type, to preserve previous behaviour. maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)1230 private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) { 1231 if (vpnNai != mService.getLegacyLockdownNai()) return; 1232 1233 if (vpnNai.declaredUnderlyingNetworks == null 1234 || vpnNai.declaredUnderlyingNetworks.length != 1) { 1235 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: " 1236 + Arrays.toString(vpnNai.declaredUnderlyingNetworks)); 1237 return; 1238 } 1239 final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork( 1240 vpnNai.declaredUnderlyingNetworks[0]); 1241 if (underlyingNai == null) return; 1242 1243 final int type = underlyingNai.networkInfo.getType(); 1244 final DetailedState state = DetailedState.CONNECTED; 1245 maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */); 1246 mService.sendLegacyNetworkBroadcast(underlyingNai, state, type); 1247 } 1248 1249 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)1250 public void add(int type, NetworkAgentInfo nai) { 1251 if (!isTypeSupported(type)) { 1252 return; // Invalid network type. 1253 } 1254 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 1255 1256 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1257 if (list.contains(nai)) { 1258 return; 1259 } 1260 synchronized (mTypeLists) { 1261 list.add(nai); 1262 } 1263 1264 // Send a broadcast if this is the first network of its type or if it's the default. 1265 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); 1266 1267 // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts 1268 // to preserve previous behaviour. 1269 final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED); 1270 if ((list.size() == 1) || isDefaultNetwork) { 1271 maybeLogBroadcast(nai, state, type, isDefaultNetwork); 1272 mService.sendLegacyNetworkBroadcast(nai, state, type); 1273 } 1274 1275 if (type == TYPE_VPN && state == DetailedState.CONNECTED) { 1276 maybeSendLegacyLockdownBroadcast(nai); 1277 } 1278 } 1279 1280 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)1281 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 1282 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1283 if (list == null || list.isEmpty()) { 1284 return; 1285 } 1286 final boolean wasFirstNetwork = list.get(0).equals(nai); 1287 1288 synchronized (mTypeLists) { 1289 if (!list.remove(nai)) { 1290 return; 1291 } 1292 } 1293 1294 if (wasFirstNetwork || wasDefault) { 1295 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault); 1296 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type); 1297 } 1298 1299 if (!list.isEmpty() && wasFirstNetwork) { 1300 if (DBG) log("Other network available for type " + type + 1301 ", sending connected broadcast"); 1302 final NetworkAgentInfo replacement = list.get(0); 1303 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type, 1304 mService.isDefaultNetwork(replacement)); 1305 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type); 1306 } 1307 } 1308 1309 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)1310 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 1311 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 1312 for (int type = 0; type < mTypeLists.length; type++) { 1313 remove(type, nai, wasDefault); 1314 } 1315 } 1316 1317 // send out another legacy broadcast - currently only used for suspend/unsuspend toggle update(NetworkAgentInfo nai)1318 public void update(NetworkAgentInfo nai) { 1319 final boolean isDefault = mService.isDefaultNetwork(nai); 1320 final DetailedState state = nai.networkInfo.getDetailedState(); 1321 for (int type = 0; type < mTypeLists.length; type++) { 1322 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1323 final boolean contains = (list != null && list.contains(nai)); 1324 final boolean isFirst = contains && (nai == list.get(0)); 1325 if (isFirst || contains && isDefault) { 1326 maybeLogBroadcast(nai, state, type, isDefault); 1327 mService.sendLegacyNetworkBroadcast(nai, state, type); 1328 } 1329 } 1330 } 1331 dump(IndentingPrintWriter pw)1332 public void dump(IndentingPrintWriter pw) { 1333 pw.println("mLegacyTypeTracker:"); 1334 pw.increaseIndent(); 1335 pw.print("Supported types:"); 1336 for (int type = 0; type < mTypeLists.length; type++) { 1337 if (mTypeLists[type] != null) pw.print(" " + type); 1338 } 1339 pw.println(); 1340 pw.println("Current state:"); 1341 pw.increaseIndent(); 1342 synchronized (mTypeLists) { 1343 for (int type = 0; type < mTypeLists.length; type++) { 1344 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 1345 for (NetworkAgentInfo nai : mTypeLists[type]) { 1346 pw.println(type + " " + nai.toShortString()); 1347 } 1348 } 1349 } 1350 pw.decreaseIndent(); 1351 pw.decreaseIndent(); 1352 pw.println(); 1353 } 1354 } 1355 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this); 1356 1357 final LocalPriorityDump mPriorityDumper = new LocalPriorityDump(); 1358 /** 1359 * Helper class which parses out priority arguments and dumps sections according to their 1360 * priority. If priority arguments are omitted, function calls the legacy dump command. 1361 */ 1362 private class LocalPriorityDump { 1363 private static final String PRIORITY_ARG = "--dump-priority"; 1364 private static final String PRIORITY_ARG_HIGH = "HIGH"; 1365 private static final String PRIORITY_ARG_NORMAL = "NORMAL"; 1366 private static final int DUMPSYS_DEFAULT_TIMEOUT_MS = 10_000; 1367 LocalPriorityDump()1368 LocalPriorityDump() {} 1369 dumpHigh(FileDescriptor fd, PrintWriter pw)1370 private void dumpHigh(FileDescriptor fd, PrintWriter pw) { 1371 if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> { 1372 doDump(fd, pw, new String[]{DIAG_ARG}); 1373 doDump(fd, pw, new String[]{SHORT_ARG}); 1374 }, DUMPSYS_DEFAULT_TIMEOUT_MS)) { 1375 pw.println("dumpHigh timeout"); 1376 } 1377 } 1378 dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1379 private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { 1380 if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> doDump(fd, pw, args), 1381 DUMPSYS_DEFAULT_TIMEOUT_MS)) { 1382 pw.println("dumpNormal timeout"); 1383 } 1384 } 1385 dump(FileDescriptor fd, PrintWriter pw, String[] args)1386 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1387 if (args == null) { 1388 dumpNormal(fd, pw, args); 1389 return; 1390 } 1391 1392 String priority = null; 1393 for (int argIndex = 0; argIndex < args.length; argIndex++) { 1394 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) { 1395 argIndex++; 1396 priority = args[argIndex]; 1397 } 1398 } 1399 1400 if (PRIORITY_ARG_HIGH.equals(priority)) { 1401 dumpHigh(fd, pw); 1402 } else if (PRIORITY_ARG_NORMAL.equals(priority)) { 1403 dumpNormal(fd, pw, args); 1404 } else { 1405 // ConnectivityService publishes binder service using publishBinderService() with 1406 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send 1407 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the 1408 // legacy output for dumpsys connectivity. 1409 // TODO: Integrate into signal dump. 1410 dumpNormal(fd, pw, args); 1411 } 1412 } 1413 } 1414 1415 /** 1416 * Dependencies of ConnectivityService, for injection in tests. 1417 */ 1418 @VisibleForTesting 1419 public static class Dependencies { getCallingUid()1420 public int getCallingUid() { 1421 return Binder.getCallingUid(); 1422 } 1423 isAtLeastS()1424 public boolean isAtLeastS() { 1425 return SdkLevel.isAtLeastS(); 1426 } 1427 isAtLeastT()1428 public boolean isAtLeastT() { 1429 return SdkLevel.isAtLeastT(); 1430 } 1431 isAtLeastU()1432 public boolean isAtLeastU() { 1433 return SdkLevel.isAtLeastU(); 1434 } 1435 isAtLeastV()1436 public boolean isAtLeastV() { 1437 return SdkLevel.isAtLeastV(); 1438 } 1439 1440 /** 1441 * Get system properties to use in ConnectivityService. 1442 */ getSystemProperties()1443 public MockableSystemProperties getSystemProperties() { 1444 return new MockableSystemProperties(); 1445 } 1446 1447 /** 1448 * Get the {@link ConnectivityResources} to use in ConnectivityService. 1449 */ getResources(@onNull Context ctx)1450 public ConnectivityResources getResources(@NonNull Context ctx) { 1451 return new ConnectivityResources(ctx); 1452 } 1453 1454 /** 1455 * Create a HandlerThread to use in ConnectivityService. 1456 */ makeHandlerThread(@onNull final String tag)1457 public HandlerThread makeHandlerThread(@NonNull final String tag) { 1458 return new HandlerThread(tag); 1459 } 1460 1461 /** 1462 * Get a reference to the ModuleNetworkStackClient. 1463 */ getNetworkStack()1464 public NetworkStackClientBase getNetworkStack() { 1465 return ModuleNetworkStackClient.getInstance(null); 1466 } 1467 1468 /** 1469 * @see ProxyTracker 1470 */ makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1471 public ProxyTracker makeProxyTracker(@NonNull Context context, 1472 @NonNull Handler connServiceHandler) { 1473 return new ProxyTracker(context, connServiceHandler, EVENT_PAC_PROXY_HAS_CHANGED); 1474 } 1475 1476 /** 1477 * @see NetIdManager 1478 */ makeNetIdManager()1479 public NetIdManager makeNetIdManager() { 1480 return new NetIdManager(); 1481 } 1482 1483 /** 1484 * @see NetworkUtils#queryUserAccess(int, int) 1485 */ queryUserAccess(int uid, Network network, ConnectivityService cs)1486 public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) { 1487 return cs.queryUserAccess(uid, network); 1488 } 1489 1490 /** 1491 * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets 1492 * requires CAP_NET_ADMIN, which the unit tests do not have. 1493 */ getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1494 public int getConnectionOwnerUid(int protocol, InetSocketAddress local, 1495 InetSocketAddress remote) { 1496 return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote); 1497 } 1498 1499 /** 1500 * @see MultinetworkPolicyTracker 1501 */ makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1502 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( 1503 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { 1504 return new MultinetworkPolicyTracker(c, h, r); 1505 } 1506 1507 /** 1508 * @see AutomaticOnOffKeepaliveTracker 1509 */ makeAutomaticOnOffKeepaliveTracker( @onNull Context c, @NonNull Handler h)1510 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker( 1511 @NonNull Context c, @NonNull Handler h) { 1512 return new AutomaticOnOffKeepaliveTracker(c, h); 1513 } 1514 makeMulticastRoutingCoordinatorService( @onNull Handler h)1515 public MulticastRoutingCoordinatorService makeMulticastRoutingCoordinatorService( 1516 @NonNull Handler h) { 1517 try { 1518 return new MulticastRoutingCoordinatorService(h); 1519 } catch (UnsupportedOperationException e) { 1520 // Multicast routing is not supported by the kernel 1521 Log.i(TAG, "Skipping unsupported MulticastRoutingCoordinatorService"); 1522 return null; 1523 } 1524 } 1525 1526 /** 1527 * @see NetworkRequestStateStatsMetrics 1528 */ makeNetworkRequestStateStatsMetrics( Context context)1529 public NetworkRequestStateStatsMetrics makeNetworkRequestStateStatsMetrics( 1530 Context context) { 1531 // We currently have network requests metric for Watch devices only 1532 if (context.getPackageManager().hasSystemFeature(FEATURE_WATCH)) { 1533 return new NetworkRequestStateStatsMetrics(); 1534 } else { 1535 return null; 1536 } 1537 } 1538 1539 /** 1540 * @see BatteryStatsManager 1541 */ reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1542 public void reportNetworkInterfaceForTransports(Context context, String iface, 1543 int[] transportTypes) { 1544 final BatteryStatsManager batteryStats = 1545 context.getSystemService(BatteryStatsManager.class); 1546 batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes); 1547 } 1548 getCellular464XlatEnabled()1549 public boolean getCellular464XlatEnabled() { 1550 return NetworkProperties.isCellular464XlatEnabled().orElse(true); 1551 } 1552 1553 /** 1554 * @see PendingIntent#intentFilterEquals 1555 */ intentFilterEquals(PendingIntent a, PendingIntent b)1556 public boolean intentFilterEquals(PendingIntent a, PendingIntent b) { 1557 return a.intentFilterEquals(b); 1558 } 1559 1560 /** 1561 * @see LocationPermissionChecker 1562 */ makeLocationPermissionChecker(Context context)1563 public LocationPermissionChecker makeLocationPermissionChecker(Context context) { 1564 return new LocationPermissionChecker(context); 1565 } 1566 1567 /** 1568 * @see CarrierPrivilegeAuthenticator 1569 * 1570 * This method returns null in versions before T, where carrier privilege 1571 * authentication is not supported. 1572 */ 1573 @Nullable makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm, boolean requestRestrictedWifiEnabled, @NonNull BiConsumer<Integer, Integer> listener, @NonNull final Handler connectivityServiceHandler)1574 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 1575 @NonNull final Context context, 1576 @NonNull final TelephonyManager tm, 1577 boolean requestRestrictedWifiEnabled, 1578 @NonNull BiConsumer<Integer, Integer> listener, 1579 @NonNull final Handler connectivityServiceHandler) { 1580 if (isAtLeastT()) { 1581 return new CarrierPrivilegeAuthenticator(context, tm, requestRestrictedWifiEnabled, 1582 listener, connectivityServiceHandler); 1583 } else { 1584 return null; 1585 } 1586 } 1587 1588 /** 1589 * @see SatelliteAccessController 1590 */ 1591 @Nullable makeSatelliteAccessController( @onNull final Context context, Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, @NonNull final Handler connectivityServiceInternalHandler)1592 public SatelliteAccessController makeSatelliteAccessController( 1593 @NonNull final Context context, 1594 Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, 1595 @NonNull final Handler connectivityServiceInternalHandler) { 1596 return new SatelliteAccessController(context, updateSatelliteNetworkFallbackUidCallback, 1597 connectivityServiceInternalHandler); 1598 } 1599 1600 /** 1601 * @see DeviceConfigUtils#isTetheringFeatureEnabled 1602 */ isFeatureEnabled(Context context, String name)1603 public boolean isFeatureEnabled(Context context, String name) { 1604 return DeviceConfigUtils.isTetheringFeatureEnabled(context, name); 1605 } 1606 1607 /** 1608 * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut 1609 */ isFeatureNotChickenedOut(Context context, String name)1610 public boolean isFeatureNotChickenedOut(Context context, String name) { 1611 return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name); 1612 } 1613 1614 /** 1615 * Get the BpfNetMaps implementation to use in ConnectivityService. 1616 * @param netd a netd binder 1617 * @return BpfNetMaps implementation. 1618 */ getBpfNetMaps(Context context, INetd netd)1619 public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { 1620 return new BpfNetMaps(context, netd); 1621 } 1622 1623 /** 1624 * @see ClatCoordinator 1625 */ 1626 @RequiresApi(Build.VERSION_CODES.TIRAMISU) getClatCoordinator(INetd netd)1627 public ClatCoordinator getClatCoordinator(INetd netd) { 1628 return new ClatCoordinator( 1629 new ClatCoordinator.Dependencies() { 1630 @NonNull 1631 public INetd getNetd() { 1632 return netd; 1633 } 1634 }); 1635 } 1636 1637 /** 1638 * Wraps {@link TcUtils#tcFilterAddDevIngressPolice} 1639 */ enableIngressRateLimit(String iface, long rateInBytesPerSecond)1640 public void enableIngressRateLimit(String iface, long rateInBytesPerSecond) { 1641 final InterfaceParams params = InterfaceParams.getByName(iface); 1642 if (params == null) { 1643 // the interface might have disappeared. 1644 logw("Failed to get interface params for interface " + iface); 1645 return; 1646 } 1647 try { 1648 // converting rateInBytesPerSecond from long to int is safe here because the 1649 // setting's range is limited to INT_MAX. 1650 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice. 1651 Log.i(TAG, 1652 "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s"); 1653 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL, 1654 (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH); 1655 } catch (IOException e) { 1656 loge("TcUtils.tcFilterAddDevIngressPolice(ifaceIndex=" + params.index 1657 + ", PRIO_POLICE, ETH_P_ALL, rateInBytesPerSecond=" 1658 + rateInBytesPerSecond + ", bpfProgPath=" + TC_POLICE_BPF_PROG_PATH 1659 + ") failure: ", e); 1660 } 1661 } 1662 1663 /** 1664 * Wraps {@link TcUtils#tcFilterDelDev} 1665 */ disableIngressRateLimit(String iface)1666 public void disableIngressRateLimit(String iface) { 1667 final InterfaceParams params = InterfaceParams.getByName(iface); 1668 if (params == null) { 1669 // the interface might have disappeared. 1670 logw("Failed to get interface params for interface " + iface); 1671 return; 1672 } 1673 try { 1674 Log.i(TAG, 1675 "disableIngressRateLimit on " + iface); 1676 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL); 1677 } catch (IOException e) { 1678 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index 1679 + ", ingress=true, PRIO_POLICE, ETH_P_ALL) failure: ", e); 1680 } 1681 } 1682 1683 /** 1684 * Get BPF program Id from CGROUP. See {@link BpfUtils#getProgramId}. 1685 */ getBpfProgramId(final int attachType)1686 public int getBpfProgramId(final int attachType) 1687 throws IOException { 1688 return BpfUtils.getProgramId(attachType); 1689 } 1690 1691 /** 1692 * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)} 1693 */ 1694 // TODO: when available in all active branches: 1695 // @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 1696 @RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT) makeBroadcastOptionsShim(BroadcastOptions options)1697 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 1698 return BroadcastOptionsShimImpl.newInstance(options); 1699 } 1700 1701 /** 1702 * Wrapper method for 1703 * {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}. 1704 * 1705 * @param changeId The ID of the compatibility change in question. 1706 * @param packageName The package name of the app in question. 1707 * @param user The user that the operation is done for. 1708 * @return {@code true} if the change is enabled for the specified package. 1709 */ isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)1710 public boolean isChangeEnabled(long changeId, @NonNull final String packageName, 1711 @NonNull final UserHandle user) { 1712 return CompatChanges.isChangeEnabled(changeId, packageName, user); 1713 } 1714 1715 /** 1716 * As above but with a UID. 1717 * @see CompatChanges#isChangeEnabled(long, int) 1718 */ isChangeEnabled(final long changeId, final int uid)1719 public boolean isChangeEnabled(final long changeId, final int uid) { 1720 return CompatChanges.isChangeEnabled(changeId, uid); 1721 } 1722 1723 /** 1724 * Call {@link InetDiagMessage#destroyLiveTcpSockets(Set, Set)} 1725 * 1726 * @param ranges target uid ranges 1727 * @param exemptUids uids to skip close socket 1728 */ destroyLiveTcpSockets(@onNull final Set<Range<Integer>> ranges, @NonNull final Set<Integer> exemptUids)1729 public void destroyLiveTcpSockets(@NonNull final Set<Range<Integer>> ranges, 1730 @NonNull final Set<Integer> exemptUids) 1731 throws SocketException, InterruptedIOException, ErrnoException { 1732 InetDiagMessage.destroyLiveTcpSockets(ranges, exemptUids); 1733 } 1734 1735 /** 1736 * Call {@link InetDiagMessage#destroyLiveTcpSocketsByOwnerUids(Set)} 1737 * 1738 * @param ownerUids target uids to close sockets 1739 */ destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)1740 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) 1741 throws SocketException, InterruptedIOException, ErrnoException { 1742 InetDiagMessage.destroyLiveTcpSocketsByOwnerUids(ownerUids); 1743 } 1744 1745 /** 1746 * Schedule the evaluation timeout. 1747 * 1748 * When a network connects, it's "not evaluated" yet. Detection events cause the network 1749 * to be "evaluated" (typically, validation or detection of a captive portal). If none 1750 * of these events happen, this time will run out, after which the network is considered 1751 * "evaluated" even if nothing happened to it. Notionally that means the system gave up 1752 * on this network and considers it won't provide connectivity. In particular, that means 1753 * it's when the system prefers it to cell if it's wifi and configuration says it should 1754 * prefer bad wifi to cell. 1755 */ scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)1756 public void scheduleEvaluationTimeout(@NonNull Handler handler, 1757 @NonNull final Network network, final long delayMs) { 1758 handler.sendMessageDelayed( 1759 handler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs); 1760 } 1761 } 1762 1763 public ConnectivityService(Context context) { 1764 this(context, getDnsResolver(context), new IpConnectivityLog(), 1765 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), 1766 new Dependencies()); 1767 } 1768 1769 @VisibleForTesting 1770 protected ConnectivityService(Context context, IDnsResolver dnsresolver, 1771 IpConnectivityLog logger, INetd netd, Dependencies deps) { 1772 if (DBG) log("ConnectivityService starting up"); 1773 1774 mDeps = Objects.requireNonNull(deps, "missing Dependencies"); 1775 mFlags = new ConnectivityFlags(); 1776 mSystemProperties = mDeps.getSystemProperties(); 1777 mNetIdManager = mDeps.makeNetIdManager(); 1778 mContext = Objects.requireNonNull(context, "missing Context"); 1779 mResources = deps.getResources(mContext); 1780 // The legacy PerUidCounter is buggy and throwing exception at count == limit. 1781 // Pass limit - 1 to maintain backward compatibility. 1782 // TODO: Remove the workaround. 1783 mNetworkRequestCounter = 1784 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_UID - 1); 1785 mSystemNetworkRequestCounter = 1786 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1); 1787 1788 mMetricsLog = logger; 1789 mNetworkRequestStateStatsMetrics = mDeps.makeNetworkRequestStateStatsMetrics(mContext); 1790 final NetworkRequest defaultInternetRequest = createDefaultRequest(); 1791 mDefaultRequest = new NetworkRequestInfo( 1792 Process.myUid(), defaultInternetRequest, null, 1793 null /* binder */, NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1794 null /* attributionTags */); 1795 mNetworkRequests.put(defaultInternetRequest, mDefaultRequest); 1796 mDefaultNetworkRequests.add(mDefaultRequest); 1797 mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest); 1798 1799 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( 1800 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); 1801 1802 // The default WiFi request is a background request so that apps using WiFi are 1803 // migrated to a better network (typically ethernet) when one comes up, instead 1804 // of staying on WiFi forever. 1805 mDefaultWifiRequest = createDefaultInternetRequestForTransport( 1806 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); 1807 1808 mDefaultVehicleRequest = createAlwaysOnRequestForCapability( 1809 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL, 1810 NetworkRequest.Type.BACKGROUND_REQUEST); 1811 1812 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 1813 // TODO: Consider making the timer customizable. 1814 mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS; 1815 mCellularRadioTimesharingCapable = 1816 mResources.get().getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1817 1818 int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark); 1819 int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask); 1820 1821 if (SdkLevel.isAtLeastU()) { 1822 // U+ default value of both mark & mask, this is the top bit of the skb->mark, 1823 // see //system/netd/include/FwMark.h union Fwmark, field ingress_cpu_wakeup 1824 final int defaultUMarkMask = 0x80000000; // u32 1825 1826 if ((mark == 0) || (mask == 0)) { 1827 // simply treat unset/disabled as the default U value 1828 mark = defaultUMarkMask; 1829 mask = defaultUMarkMask; 1830 } 1831 if ((mark != defaultUMarkMask) || (mask != defaultUMarkMask)) { 1832 // invalid device overlay settings 1833 throw new IllegalArgumentException( 1834 "Bad config_networkWakeupPacketMark/Mask " + mark + "/" + mask); 1835 } 1836 } 1837 1838 mWakeUpMark = mark; 1839 mWakeUpMask = mask; 1840 1841 mNetd = netd; 1842 mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd); 1843 mHandlerThread = mDeps.makeHandlerThread("ConnectivityServiceThread"); 1844 mPermissionMonitor = 1845 new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mHandlerThread); 1846 mHandlerThread.start(); 1847 mHandler = new InternalHandler(mHandlerThread.getLooper()); 1848 // Temporary hack to report netbpfload result. 1849 // TODO: remove in 2024-09 when netbpfload starts loading mainline bpf programs. 1850 if (!mDeps.isAtLeastV()) { 1851 mHandler.postDelayed(() -> { 1852 // Test Log.wtf reporting pipeline. Ignore this Log.wtf if it shows up in the logs. 1853 final Random r = new Random(); 1854 if (Build.TYPE.equals("user") && r.nextInt(1000) == 0) { 1855 Log.wtf(TAG, "NOT A FAILURE, PLEASE IGNORE! Ensure netbpfload result reported"); 1856 } 1857 // Did netbpfload create the map? 1858 try { 1859 Os.access("/sys/fs/bpf/net_shared/map_gentle_test", F_OK); 1860 } catch (ErrnoException e) { 1861 Log.wtf(TAG, "netbpfload did not create map", e); 1862 } 1863 // Did netbpfload create the program? 1864 try { 1865 Os.access("/sys/fs/bpf/net_shared/prog_gentle_skfilter_accept", F_OK); 1866 } catch (ErrnoException e) { 1867 Log.wtf(TAG, "netbpfload did not create program", e); 1868 } 1869 // Did netbpfload run to completion? 1870 try { 1871 Os.access("/sys/fs/bpf/netd_shared/mainline_done", F_OK); 1872 } catch (ErrnoException e) { 1873 Log.wtf(TAG, "netbpfload did not run to completion", e); 1874 } 1875 }, 30_000 /* delayMillis */); 1876 } 1877 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 1878 mConnectivityDiagnosticsHandler = 1879 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper()); 1880 1881 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 1882 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 1883 1884 mStatsManager = mContext.getSystemService(NetworkStatsManager.class); 1885 mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); 1886 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver"); 1887 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); 1888 1889 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1890 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 1891 mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); 1892 mRequestRestrictedWifiEnabled = mDeps.isAtLeastU() 1893 && mDeps.isFeatureEnabled(context, REQUEST_RESTRICTED_WIFI); 1894 mBackgroundFirewallChainEnabled = mDeps.isAtLeastV() && mDeps.isFeatureNotChickenedOut( 1895 context, ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN); 1896 mUseDeclaredMethodsForCallbacksEnabled = mDeps.isFeatureEnabled(context, 1897 ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS); 1898 mCarrierPrivilegeAuthenticator = mDeps.makeCarrierPrivilegeAuthenticator( 1899 mContext, mTelephonyManager, mRequestRestrictedWifiEnabled, 1900 this::handleUidCarrierPrivilegesLost, mHandler); 1901 1902 if (mDeps.isAtLeastU() 1903 && mDeps 1904 .isFeatureNotChickenedOut(mContext, ALLOW_SATALLITE_NETWORK_FALLBACK)) { 1905 mSatelliteAccessController = mDeps.makeSatelliteAccessController( 1906 mContext, this::updateSatelliteNetworkPreferenceUids, mHandler); 1907 } else { 1908 mSatelliteAccessController = null; 1909 } 1910 1911 // To ensure uid state is synchronized with Network Policy, register for 1912 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService 1913 // reading existing policy from disk. 1914 // If shouldTrackUidsForBlockedStatusCallbacks() is true (On V+), ConnectivityService 1915 // updates blocked reasons when firewall chain and data saver status is updated based on 1916 // bpf map contents instead of receiving callbacks from NPMS 1917 if (!shouldTrackUidsForBlockedStatusCallbacks()) { 1918 mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback); 1919 } 1920 1921 final PowerManager powerManager = (PowerManager) context.getSystemService( 1922 Context.POWER_SERVICE); 1923 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1924 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1925 1926 mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager); 1927 mProtectedNetworks = new ArrayList<>(); 1928 int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks); 1929 for (int p : protectedNetworks) { 1930 if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) { 1931 mProtectedNetworks.add(p); 1932 } else { 1933 if (DBG) loge("Ignoring protectedNetwork " + p); 1934 } 1935 } 1936 1937 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 1938 1939 mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */); 1940 // Listen for user add/removes to inform PermissionMonitor. 1941 // Should run on mHandler to avoid any races. 1942 final IntentFilter userIntentFilter = new IntentFilter(); 1943 userIntentFilter.addAction(Intent.ACTION_USER_ADDED); 1944 userIntentFilter.addAction(Intent.ACTION_USER_REMOVED); 1945 mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter, 1946 null /* broadcastPermission */, mHandler); 1947 1948 // Listen to package add/removes for netd 1949 final IntentFilter packageIntentFilter = new IntentFilter(); 1950 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 1951 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1952 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 1953 packageIntentFilter.addDataScheme("package"); 1954 mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter, 1955 null /* broadcastPermission */, mHandler); 1956 1957 // This is needed for pre-V devices to propagate the data saver status 1958 // to the BPF map. This isn't supported before Android T because BPF maps are 1959 // unsupported, and it's also unnecessary on Android V and later versions, 1960 // as the platform code handles data saver bit updates. Additionally, checking 1961 // the initial data saver status here is superfluous because the intent won't 1962 // be sent until the system is ready. 1963 if (mDeps.isAtLeastT() && !mDeps.isAtLeastV()) { 1964 final IntentFilter dataSaverIntentFilter = 1965 new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED); 1966 mUserAllContext.registerReceiver(mDataSaverReceiver, dataSaverIntentFilter, 1967 null /* broadcastPermission */, mHandler); 1968 } 1969 1970 // TrackMultiNetworkActivities feature should be enabled by trunk stable flag. 1971 // But reading the trunk stable flags from mainline modules is not supported yet. 1972 // So enabling this feature on V+ release. 1973 mTrackMultiNetworkActivities = mDeps.isAtLeastV(); 1974 mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNetd, mHandler, 1975 mTrackMultiNetworkActivities); 1976 1977 final NetdCallback netdCallback = new NetdCallback(); 1978 try { 1979 mNetd.registerUnsolicitedEventListener(netdCallback); 1980 } catch (RemoteException | ServiceSpecificException e) { 1981 loge("Error registering event listener :" + e); 1982 } 1983 1984 mSettingsObserver = new SettingsObserver(mContext, mHandler); 1985 registerSettingsCallbacks(); 1986 1987 mKeepaliveTracker = mDeps.makeAutomaticOnOffKeepaliveTracker(mContext, mHandler); 1988 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager); 1989 mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter); 1990 1991 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 1992 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 1993 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 1994 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 1995 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 1996 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 1997 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 1998 1999 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( 2000 mContext, mHandler, () -> updateAvoidBadWifi()); 2001 mNetworkRanker = 2002 new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi())); 2003 2004 mMultinetworkPolicyTracker.start(); 2005 2006 mDnsManager = new DnsManager(mContext, mDnsResolver); 2007 registerPrivateDnsSettingsCallbacks(); 2008 2009 // This NAI is a sentinel used to offer no service to apps that are on a multi-layer 2010 // request that doesn't allow fallback to the default network. It should never be visible 2011 // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal 2012 // arguments like the handler or the DnsResolver. 2013 // TODO : remove this ; it is probably better handled with a sentinel request. 2014 mNoServiceNetwork = new NetworkAgentInfo(null, 2015 new Network(INetd.UNREACHABLE_NET_ID), 2016 new NetworkInfo(TYPE_NONE, 0, "", ""), 2017 new LinkProperties(), new NetworkCapabilities(), null /* localNetworkConfig */, 2018 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, 2019 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, 2020 mLingerDelayMs, mQosCallbackTracker, mDeps); 2021 2022 try { 2023 // DscpPolicyTracker cannot run on S because on S the tethering module can only load 2024 // BPF programs/maps into /sys/fs/tethering/bpf, which the system server cannot access. 2025 // Even if it could, running on S would at least require mocking out the BPF map, 2026 // otherwise the unit tests will fail on pre-T devices where the seccomp filter blocks 2027 // the bpf syscall. http://aosp/1907693 2028 if (mDeps.isAtLeastT()) { 2029 mDscpPolicyTracker = new DscpPolicyTracker(); 2030 } 2031 } catch (ErrnoException e) { 2032 loge("Unable to create DscpPolicyTracker"); 2033 } 2034 2035 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 2036 mContext); 2037 2038 if (mDeps.isAtLeastT()) { 2039 mCdmps = new CompanionDeviceManagerProxyService(context); 2040 } else { 2041 mCdmps = null; 2042 } 2043 2044 mRoutingCoordinatorService = new RoutingCoordinatorService(netd); 2045 mMulticastRoutingCoordinatorService = 2046 mDeps.makeMulticastRoutingCoordinatorService(mHandler); 2047 2048 mDestroyFrozenSockets = mDeps.isAtLeastV() || (mDeps.isAtLeastU() 2049 && mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION)); 2050 mDelayDestroySockets = mDeps.isFeatureNotChickenedOut(context, DELAY_DESTROY_SOCKETS); 2051 mAllowSysUiConnectivityReports = mDeps.isFeatureNotChickenedOut( 2052 mContext, ALLOW_SYSUI_CONNECTIVITY_REPORTS); 2053 if (mDestroyFrozenSockets) { 2054 final UidFrozenStateChangedCallback frozenStateChangedCallback = 2055 new UidFrozenStateChangedCallback() { 2056 @Override 2057 public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) { 2058 if (uids.length != frozenStates.length) { 2059 Log.wtf(TAG, "uids has length " + uids.length 2060 + " but frozenStates has length " + frozenStates.length); 2061 return; 2062 } 2063 2064 final UidFrozenStateChangedArgs args = 2065 new UidFrozenStateChangedArgs(uids, frozenStates); 2066 2067 mHandler.sendMessage( 2068 mHandler.obtainMessage(EVENT_UID_FROZEN_STATE_CHANGED, args)); 2069 } 2070 }; 2071 2072 final ActivityManager activityManager = 2073 mContext.getSystemService(ActivityManager.class); 2074 activityManager.registerUidFrozenStateChangedCallback( 2075 (Runnable r) -> r.run(), frozenStateChangedCallback); 2076 } 2077 mIngressToVpnAddressFiltering = mDeps.isAtLeastT() 2078 && mDeps.isFeatureNotChickenedOut(mContext, INGRESS_TO_VPN_ADDRESS_FILTERING); 2079 } 2080 2081 /** 2082 * Check whether or not the device supports Ethernet transport. 2083 */ 2084 public static boolean deviceSupportsEthernet(final Context context) { 2085 final PackageManager pm = context.getPackageManager(); 2086 return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET) 2087 || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST); 2088 } 2089 2090 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { 2091 return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton( 2092 new UidRange(uid, uid))); 2093 } 2094 2095 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet( 2096 @NonNull final Set<UidRange> uidRangeSet) { 2097 final NetworkCapabilities netCap = new NetworkCapabilities(); 2098 netCap.addCapability(NET_CAPABILITY_INTERNET); 2099 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 2100 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 2101 netCap.setUids(UidRange.toIntRanges(uidRangeSet)); 2102 return netCap; 2103 } 2104 2105 private NetworkRequest createDefaultRequest() { 2106 return createDefaultInternetRequestForTransport( 2107 TYPE_NONE, NetworkRequest.Type.REQUEST); 2108 } 2109 2110 private NetworkRequest createVpnRequest() { 2111 final NetworkCapabilities netCap = new NetworkCapabilities.Builder() 2112 .withoutDefaultCapabilities() 2113 .addTransportType(TRANSPORT_VPN) 2114 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 2115 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 2116 .build(); 2117 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2118 return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap); 2119 } 2120 2121 private NetworkRequest createDefaultInternetRequestForTransport( 2122 int transportType, NetworkRequest.Type type) { 2123 final NetworkCapabilities netCap = new NetworkCapabilities(); 2124 netCap.addCapability(NET_CAPABILITY_INTERNET); 2125 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 2126 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2127 if (transportType > TYPE_NONE) { 2128 netCap.addTransportType(transportType); 2129 } 2130 return createNetworkRequest(type, netCap); 2131 } 2132 2133 private NetworkRequest createNetworkRequest( 2134 NetworkRequest.Type type, NetworkCapabilities netCap) { 2135 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 2136 } 2137 2138 private NetworkRequest createAlwaysOnRequestForCapability(int capability, 2139 NetworkRequest.Type type) { 2140 final NetworkCapabilities netCap = new NetworkCapabilities(); 2141 netCap.clearAll(); 2142 netCap.addCapability(capability); 2143 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2144 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 2145 } 2146 2147 // Used only for testing. 2148 // TODO: Delete this and either: 2149 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires 2150 // changing ContentResolver to make registerContentObserver non-final). 2151 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 2152 // by subclassing SettingsObserver. 2153 @VisibleForTesting 2154 void updateAlwaysOnNetworks() { 2155 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2156 } 2157 2158 // See FakeSettingsProvider comment above. 2159 @VisibleForTesting 2160 void updatePrivateDnsSettings() { 2161 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 2162 } 2163 2164 @VisibleForTesting 2165 void updateMobileDataPreferredUids() { 2166 mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 2167 } 2168 2169 @VisibleForTesting 2170 void updateIngressRateLimit() { 2171 mHandler.sendEmptyMessage(EVENT_INGRESS_RATE_LIMIT_CHANGED); 2172 } 2173 2174 @VisibleForTesting 2175 void simulateUpdateProxyInfo(@Nullable final Network network, 2176 @NonNull final ProxyInfo proxyInfo) { 2177 Message.obtain(mHandler, EVENT_PAC_PROXY_HAS_CHANGED, 2178 new Pair<>(network, proxyInfo)).sendToTarget(); 2179 } 2180 2181 /** 2182 * Called when satellite network fallback uids at {@link SatelliteAccessController} 2183 * cache was updated based on {@link 2184 * android.app.role.OnRoleHoldersChangedListener#onRoleHoldersChanged(String, UserHandle)}, 2185 * to create multilayer request with preference order 2186 * {@link #PREFERENCE_ORDER_SATELLITE_FALLBACK} there on. 2187 * 2188 */ 2189 private void updateSatelliteNetworkPreferenceUids(Set<Integer> satelliteNetworkFallbackUids) { 2190 handleSetSatelliteNetworkPreference(satelliteNetworkFallbackUids); 2191 } 2192 2193 private void handleAlwaysOnNetworkRequest( 2194 NetworkRequest networkRequest, String settingName, boolean defaultValue) { 2195 final boolean enable = toBool(Settings.Global.getInt( 2196 mContext.getContentResolver(), settingName, encodeBool(defaultValue))); 2197 handleAlwaysOnNetworkRequest(networkRequest, enable); 2198 } 2199 2200 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) { 2201 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); 2202 if (enable == isEnabled) { 2203 return; // Nothing to do. 2204 } 2205 2206 if (enable) { 2207 handleRegisterNetworkRequest(new NetworkRequestInfo( 2208 Process.myUid(), networkRequest, null /* messenger */, null /* binder */, 2209 NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 2210 null /* attributionTags */)); 2211 } else { 2212 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, 2213 /* callOnUnavailable */ false); 2214 } 2215 } 2216 2217 private void handleConfigureAlwaysOnNetworks() { 2218 handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest, 2219 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */); 2220 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, 2221 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */); 2222 final boolean vehicleAlwaysRequested = mResources.get().getBoolean( 2223 R.bool.config_vehicleInternalNetworkAlwaysRequested); 2224 handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested); 2225 } 2226 2227 // Note that registering observer for setting do not get initial callback when registering, 2228 // callers must fetch the initial value of the setting themselves if needed. 2229 private void registerSettingsCallbacks() { 2230 // Watch for global HTTP proxy changes. 2231 mSettingsObserver.observe( 2232 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 2233 EVENT_APPLY_GLOBAL_HTTP_PROXY); 2234 2235 // Watch for whether to keep mobile data always on. 2236 mSettingsObserver.observe( 2237 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON), 2238 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2239 2240 // Watch for whether to keep wifi always on. 2241 mSettingsObserver.observe( 2242 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED), 2243 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2244 2245 // Watch for mobile data preferred uids changes. 2246 mSettingsObserver.observe( 2247 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS), 2248 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 2249 2250 // Watch for ingress rate limit changes. 2251 mSettingsObserver.observe( 2252 Settings.Global.getUriFor( 2253 ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND), 2254 EVENT_INGRESS_RATE_LIMIT_CHANGED); 2255 } 2256 2257 private void registerPrivateDnsSettingsCallbacks() { 2258 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { 2259 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 2260 } 2261 } 2262 2263 private synchronized int nextNetworkRequestId() { 2264 // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if 2265 // doing that. 2266 return mNextNetworkRequestId++; 2267 } 2268 2269 @VisibleForTesting 2270 @Nullable 2271 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 2272 if (network == null) { 2273 return null; 2274 } 2275 return getNetworkAgentInfoForNetId(network.getNetId()); 2276 } 2277 2278 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { 2279 synchronized (mNetworkForNetId) { 2280 return mNetworkForNetId.get(netId); 2281 } 2282 } 2283 2284 // TODO: determine what to do when more than one VPN applies to |uid|. 2285 @Nullable 2286 private NetworkAgentInfo getVpnForUid(int uid) { 2287 synchronized (mNetworkForNetId) { 2288 for (int i = 0; i < mNetworkForNetId.size(); i++) { 2289 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 2290 if (nai.isVPN() && nai.everConnected() 2291 && nai.networkCapabilities.appliesToUid(uid)) { 2292 return nai; 2293 } 2294 } 2295 } 2296 return null; 2297 } 2298 2299 @Nullable 2300 private Network[] getVpnUnderlyingNetworks(int uid) { 2301 if (mLockdownEnabled) return null; 2302 final NetworkAgentInfo nai = getVpnForUid(uid); 2303 if (nai != null) return nai.declaredUnderlyingNetworks; 2304 return null; 2305 } 2306 2307 private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) { 2308 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2309 2310 final Network[] networks = getVpnUnderlyingNetworks(uid); 2311 if (networks != null) { 2312 // getUnderlyingNetworks() returns: 2313 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 2314 // empty array => the VPN explicitly said "no default network". 2315 // non-empty array => the VPN specified one or more default networks; we use the 2316 // first one. 2317 if (networks.length > 0) { 2318 nai = getNetworkAgentInfoForNetwork(networks[0]); 2319 } else { 2320 nai = null; 2321 } 2322 } 2323 return nai; 2324 } 2325 2326 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 2327 private boolean hasInternetPermission(final int uid) { 2328 return (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) != 0; 2329 } 2330 2331 /** 2332 * Check if UID should be blocked from using the specified network. 2333 */ 2334 private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc, 2335 final int uid, final boolean ignoreBlocked) { 2336 // Networks aren't blocked when ignoring blocked status 2337 if (ignoreBlocked) { 2338 return false; 2339 } 2340 if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true; 2341 final long ident = Binder.clearCallingIdentity(); 2342 try { 2343 final boolean metered = nc == null ? true : nc.isMetered(); 2344 if (mDeps.isAtLeastV()) { 2345 final boolean hasInternetPermission = hasInternetPermission(uid); 2346 final boolean blockedByUidRules = mBpfNetMaps.isUidNetworkingBlocked(uid, metered); 2347 if (mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid)) { 2348 return blockedByUidRules || !hasInternetPermission; 2349 } else { 2350 return hasInternetPermission && blockedByUidRules; 2351 } 2352 } else { 2353 return mPolicyManager.isUidNetworkingBlocked(uid, metered); 2354 } 2355 } finally { 2356 Binder.restoreCallingIdentity(ident); 2357 } 2358 } 2359 2360 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 2361 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 2362 return; 2363 } 2364 final boolean blocked; 2365 synchronized (mBlockedAppUids) { 2366 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 2367 blocked = true; 2368 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 2369 blocked = false; 2370 } else { 2371 return; 2372 } 2373 } 2374 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 2375 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid)); 2376 mNetworkInfoBlockingLogs.log(action + " " + uid); 2377 } 2378 2379 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) { 2380 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { 2381 return; 2382 } 2383 final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED"; 2384 final int requestId = nri.getActiveRequest() != null 2385 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId; 2386 mNetworkInfoBlockingLogs.log(String.format( 2387 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(), 2388 Integer.toHexString(blocked))); 2389 } 2390 2391 /** 2392 * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For 2393 * example, this may mark the network as {@link DetailedState#BLOCKED} based 2394 * on {@link #isNetworkWithCapabilitiesBlocked}. 2395 */ 2396 @NonNull 2397 private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type, 2398 @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) { 2399 final NetworkInfo filtered = new NetworkInfo(networkInfo); 2400 // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network 2401 // but only exists if an app asks about them or requests them. Ensure the requesting app 2402 // gets the type it asks for. 2403 filtered.setType(type); 2404 if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) { 2405 filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */, 2406 null /* extraInfo */); 2407 } 2408 filterForLegacyLockdown(filtered); 2409 return filtered; 2410 } 2411 2412 private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, 2413 boolean ignoreBlocked) { 2414 return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), 2415 nai.networkCapabilities, uid, ignoreBlocked); 2416 } 2417 2418 /** 2419 * Return NetworkInfo for the active (i.e., connected) network interface. 2420 * It is assumed that at most one network is active at a time. If more 2421 * than one is active, it is indeterminate which will be returned. 2422 * @return the info for the active network, or {@code null} if none is 2423 * active 2424 */ 2425 @Override 2426 @Nullable 2427 public NetworkInfo getActiveNetworkInfo() { 2428 enforceAccessPermission(); 2429 final int uid = mDeps.getCallingUid(); 2430 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2431 if (nai == null) return null; 2432 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false /* ignoreBlocked */); 2433 maybeLogBlockedNetworkInfo(networkInfo, uid); 2434 return networkInfo; 2435 } 2436 2437 @Override 2438 @Nullable 2439 public Network getActiveNetwork() { 2440 enforceAccessPermission(); 2441 return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false); 2442 } 2443 2444 @Override 2445 @Nullable 2446 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 2447 enforceNetworkStackPermission(mContext); 2448 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 2449 } 2450 2451 @Nullable 2452 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 2453 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 2454 if (vpnNai != null) { 2455 final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid); 2456 if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) { 2457 return vpnNai.network; 2458 } 2459 } 2460 2461 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2462 if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, 2463 ignoreBlocked)) { 2464 return null; 2465 } 2466 return nai.network; 2467 } 2468 2469 @Override 2470 @Nullable 2471 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 2472 enforceNetworkStackPermission(mContext); 2473 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2474 if (nai == null) return null; 2475 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2476 } 2477 2478 /** Returns a NetworkInfo object for a network that doesn't exist. */ 2479 private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) { 2480 final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */, 2481 getNetworkTypeName(networkType), "" /* subtypeName */); 2482 info.setIsAvailable(true); 2483 // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when 2484 // background data is restricted. 2485 final NetworkCapabilities nc = new NetworkCapabilities(); // Metered. 2486 final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false) 2487 ? DetailedState.BLOCKED 2488 : DetailedState.DISCONNECTED; 2489 info.setDetailedState(state, null /* reason */, null /* extraInfo */); 2490 filterForLegacyLockdown(info); 2491 return info; 2492 } 2493 2494 private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) { 2495 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2496 return null; 2497 } 2498 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2499 if (nai == null) { 2500 return makeFakeNetworkInfo(networkType, uid); 2501 } 2502 return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid, 2503 false); 2504 } 2505 2506 @Override 2507 @Nullable 2508 public NetworkInfo getNetworkInfo(int networkType) { 2509 enforceAccessPermission(); 2510 final int uid = mDeps.getCallingUid(); 2511 if (getVpnUnderlyingNetworks(uid) != null) { 2512 // A VPN is active, so we may need to return one of its underlying networks. This 2513 // information is not available in LegacyTypeTracker, so we have to get it from 2514 // getNetworkAgentInfoForUid. 2515 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2516 if (nai == null) return null; 2517 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 2518 if (networkInfo.getType() == networkType) { 2519 return networkInfo; 2520 } 2521 } 2522 return getFilteredNetworkInfoForType(networkType, uid); 2523 } 2524 2525 @Override 2526 @Nullable 2527 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 2528 enforceAccessPermission(); 2529 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2530 if (nai == null) return null; 2531 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2532 } 2533 2534 @Override 2535 public NetworkInfo[] getAllNetworkInfo() { 2536 enforceAccessPermission(); 2537 final ArrayList<NetworkInfo> result = new ArrayList<>(); 2538 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 2539 networkType++) { 2540 NetworkInfo info = getNetworkInfo(networkType); 2541 if (info != null) { 2542 result.add(info); 2543 } 2544 } 2545 return result.toArray(new NetworkInfo[result.size()]); 2546 } 2547 2548 @Override 2549 @Nullable 2550 public Network getNetworkForType(int networkType) { 2551 enforceAccessPermission(); 2552 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2553 return null; 2554 } 2555 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2556 if (nai == null) { 2557 return null; 2558 } 2559 final int uid = mDeps.getCallingUid(); 2560 if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) { 2561 return null; 2562 } 2563 return nai.network; 2564 } 2565 2566 @Override 2567 @NonNull 2568 public Network[] getAllNetworks() { 2569 enforceAccessPermission(); 2570 synchronized (mNetworkForNetId) { 2571 final Network[] result = new Network[mNetworkForNetId.size()]; 2572 for (int i = 0; i < mNetworkForNetId.size(); i++) { 2573 result[i] = mNetworkForNetId.valueAt(i).network; 2574 } 2575 return result; 2576 } 2577 } 2578 2579 @Override 2580 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser( 2581 int userId, String callingPackageName, @Nullable String callingAttributionTag) { 2582 // The basic principle is: if an app's traffic could possibly go over a 2583 // network, without the app doing anything multinetwork-specific, 2584 // (hence, by "default"), then include that network's capabilities in 2585 // the array. 2586 // 2587 // In the normal case, app traffic only goes over the system's default 2588 // network connection, so that's the only network returned. 2589 // 2590 // With a VPN in force, some app traffic may go into the VPN, and thus 2591 // over whatever underlying networks the VPN specifies, while other app 2592 // traffic may go over the system default network (e.g.: a split-tunnel 2593 // VPN, or an app disallowed by the VPN), so the set of networks 2594 // returned includes the VPN's underlying networks and the system 2595 // default. 2596 enforceAccessPermission(); 2597 2598 HashMap<Network, NetworkCapabilities> result = new HashMap<>(); 2599 2600 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 2601 if (!nri.isBeingSatisfied()) { 2602 continue; 2603 } 2604 final NetworkAgentInfo nai = nri.getSatisfier(); 2605 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 2606 if (null != nc 2607 && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 2608 && !result.containsKey(nai.network)) { 2609 result.put( 2610 nai.network, 2611 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2612 nc, false /* includeLocationSensitiveInfo */, 2613 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2614 callingAttributionTag)); 2615 } 2616 } 2617 2618 // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null. 2619 final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid()); 2620 if (null != networks) { 2621 for (final Network network : networks) { 2622 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 2623 if (null != nc) { 2624 result.put( 2625 network, 2626 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2627 nc, 2628 false /* includeLocationSensitiveInfo */, 2629 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2630 callingAttributionTag)); 2631 } 2632 } 2633 } 2634 2635 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 2636 out = result.values().toArray(out); 2637 return out; 2638 } 2639 2640 // Because StatsEvent is not usable in tests (everything inside it is hidden), this 2641 // method is used to convert a ConnectivityStateSample into a StatsEvent, so that tests 2642 // can call sampleConnectivityState and make the checks on it. 2643 @NonNull 2644 private StatsEvent sampleConnectivityStateToStatsEvent() { 2645 final ConnectivityStateSample sample = sampleConnectivityState(); 2646 return ConnectivityStatsLog.buildStatsEvent( 2647 ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE, 2648 sample.getNetworkCountPerTransports().toByteArray(), 2649 sample.getConnectionDurationPerTransports().toByteArray(), 2650 sample.getNetworkRequestCount().toByteArray(), 2651 sample.getNetworks().toByteArray()); 2652 } 2653 2654 /** 2655 * Gather and return a snapshot of the current connectivity state, to be used as a sample. 2656 * 2657 * This is used for metrics. These snapshots will be sampled and constitute a base for 2658 * statistics about connectivity state of devices. 2659 */ 2660 @VisibleForTesting 2661 @NonNull 2662 public ConnectivityStateSample sampleConnectivityState() { 2663 ensureRunningOnConnectivityServiceThread(); 2664 final ConnectivityStateSample.Builder builder = ConnectivityStateSample.newBuilder(); 2665 builder.setNetworkCountPerTransports(sampleNetworkCount(mNetworkAgentInfos)); 2666 builder.setConnectionDurationPerTransports(sampleConnectionDuration(mNetworkAgentInfos)); 2667 builder.setNetworkRequestCount(sampleNetworkRequestCount(mNetworkRequests.values())); 2668 builder.setNetworks(sampleNetworks(mNetworkAgentInfos)); 2669 return builder.build(); 2670 } 2671 2672 private static NetworkCountPerTransports sampleNetworkCount( 2673 @NonNull final ArraySet<NetworkAgentInfo> nais) { 2674 final SparseIntArray countPerTransports = new SparseIntArray(); 2675 for (final NetworkAgentInfo nai : nais) { 2676 int transports = (int) nai.networkCapabilities.getTransportTypesInternal(); 2677 countPerTransports.put(transports, 1 + countPerTransports.get(transports, 0)); 2678 } 2679 final NetworkCountPerTransports.Builder builder = NetworkCountPerTransports.newBuilder(); 2680 for (int i = countPerTransports.size() - 1; i >= 0; --i) { 2681 final NetworkCountForTransports.Builder c = NetworkCountForTransports.newBuilder(); 2682 c.setTransportTypes(countPerTransports.keyAt(i)); 2683 c.setNetworkCount(countPerTransports.valueAt(i)); 2684 builder.addNetworkCountForTransports(c); 2685 } 2686 return builder.build(); 2687 } 2688 2689 private static ConnectionDurationPerTransports sampleConnectionDuration( 2690 @NonNull final ArraySet<NetworkAgentInfo> nais) { 2691 final ConnectionDurationPerTransports.Builder builder = 2692 ConnectionDurationPerTransports.newBuilder(); 2693 for (final NetworkAgentInfo nai : nais) { 2694 final ConnectionDurationForTransports.Builder c = 2695 ConnectionDurationForTransports.newBuilder(); 2696 c.setTransportTypes((int) nai.networkCapabilities.getTransportTypesInternal()); 2697 final long durationMillis = SystemClock.elapsedRealtime() - nai.getConnectedTime(); 2698 final long millisPerSecond = TimeUnit.SECONDS.toMillis(1); 2699 // Add millisPerSecond/2 to round up or down to the nearest value 2700 c.setDurationSec((int) ((durationMillis + millisPerSecond / 2) / millisPerSecond)); 2701 builder.addConnectionDurationForTransports(c); 2702 } 2703 return builder.build(); 2704 } 2705 2706 private static NetworkRequestCount sampleNetworkRequestCount( 2707 @NonNull final Collection<NetworkRequestInfo> nris) { 2708 final NetworkRequestCount.Builder builder = NetworkRequestCount.newBuilder(); 2709 final SparseIntArray countPerType = new SparseIntArray(); 2710 for (final NetworkRequestInfo nri : nris) { 2711 final int type; 2712 if (Process.SYSTEM_UID == nri.mAsUid) { 2713 // The request is filed "as" the system, so it's the system on its own behalf. 2714 type = RequestType.RT_SYSTEM.getNumber(); 2715 } else if (Process.SYSTEM_UID == nri.mUid) { 2716 // The request is filed by the system as some other app, so it's the system on 2717 // behalf of an app. 2718 type = RequestType.RT_SYSTEM_ON_BEHALF_OF_APP.getNumber(); 2719 } else { 2720 // Not the system, so it's an app requesting on its own behalf. 2721 type = RequestType.RT_APP.getNumber(); 2722 } 2723 countPerType.put(type, countPerType.get(type, 0) + 1); 2724 } 2725 for (int i = countPerType.size() - 1; i >= 0; --i) { 2726 final RequestCountForType.Builder r = RequestCountForType.newBuilder(); 2727 r.setRequestType(RequestType.forNumber(countPerType.keyAt(i))); 2728 r.setRequestCount(countPerType.valueAt(i)); 2729 builder.addRequestCountForType(r); 2730 } 2731 return builder.build(); 2732 } 2733 2734 private static NetworkList sampleNetworks(@NonNull final ArraySet<NetworkAgentInfo> nais) { 2735 final NetworkList.Builder builder = NetworkList.newBuilder(); 2736 for (final NetworkAgentInfo nai : nais) { 2737 final NetworkCapabilities nc = nai.networkCapabilities; 2738 final NetworkDescription.Builder d = NetworkDescription.newBuilder(); 2739 d.setTransportTypes((int) nc.getTransportTypesInternal()); 2740 final MeteredState meteredState; 2741 if (nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)) { 2742 meteredState = MeteredState.METERED_TEMPORARILY_UNMETERED; 2743 } else if (nc.hasCapability(NET_CAPABILITY_NOT_METERED)) { 2744 meteredState = MeteredState.METERED_NO; 2745 } else { 2746 meteredState = MeteredState.METERED_YES; 2747 } 2748 d.setMeteredState(meteredState); 2749 final ValidatedState validatedState; 2750 if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { 2751 validatedState = ValidatedState.VS_PORTAL; 2752 } else if (nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) { 2753 validatedState = ValidatedState.VS_PARTIAL; 2754 } else if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) { 2755 validatedState = ValidatedState.VS_VALID; 2756 } else { 2757 validatedState = ValidatedState.VS_INVALID; 2758 } 2759 d.setValidatedState(validatedState); 2760 d.setScorePolicies(nai.getScore().getPoliciesInternal()); 2761 d.setCapabilities(nc.getCapabilitiesInternal()); 2762 d.setEnterpriseId(nc.getEnterpriseIdsInternal()); 2763 builder.addNetworkDescription(d); 2764 } 2765 return builder.build(); 2766 } 2767 2768 @Override 2769 public boolean isNetworkSupported(int networkType) { 2770 enforceAccessPermission(); 2771 return mLegacyTypeTracker.isTypeSupported(networkType); 2772 } 2773 2774 /** 2775 * Return LinkProperties for the active (i.e., connected) default 2776 * network interface for the calling uid. 2777 * @return the ip properties for the active network, or {@code null} if 2778 * none is active 2779 */ 2780 @Override 2781 public LinkProperties getActiveLinkProperties() { 2782 enforceAccessPermission(); 2783 final int uid = mDeps.getCallingUid(); 2784 NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2785 if (nai == null) return null; 2786 return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties, 2787 Binder.getCallingPid(), uid); 2788 } 2789 2790 @Override 2791 public LinkProperties getLinkPropertiesForType(int networkType) { 2792 enforceAccessPermission(); 2793 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2794 final LinkProperties lp = getLinkProperties(nai); 2795 if (lp == null) return null; 2796 return linkPropertiesRestrictedForCallerPermissions( 2797 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2798 } 2799 2800 // TODO - this should be ALL networks 2801 @Override 2802 public LinkProperties getLinkProperties(Network network) { 2803 enforceAccessPermission(); 2804 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network)); 2805 if (lp == null) return null; 2806 return linkPropertiesRestrictedForCallerPermissions( 2807 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2808 } 2809 2810 @Nullable 2811 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) { 2812 if (nai == null) { 2813 return null; 2814 } 2815 synchronized (nai) { 2816 return nai.linkProperties; 2817 } 2818 } 2819 2820 @Override 2821 @Nullable 2822 public LinkProperties getRedactedLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid, 2823 @NonNull String packageName, @Nullable String callingAttributionTag) { 2824 Objects.requireNonNull(packageName); 2825 Objects.requireNonNull(lp); 2826 enforceNetworkStackOrSettingsPermission(); 2827 if (!hasAccessPermission(-1 /* pid */, uid)) { 2828 return null; 2829 } 2830 return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid); 2831 } 2832 2833 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) { 2834 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 2835 } 2836 2837 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 2838 if (nai == null) return null; 2839 synchronized (nai) { 2840 return networkCapabilitiesRestrictedForCallerPermissions( 2841 nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid()); 2842 } 2843 } 2844 2845 @Override 2846 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName, 2847 @Nullable String callingAttributionTag) { 2848 mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName); 2849 enforceAccessPermission(); 2850 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2851 getNetworkCapabilitiesInternal(network), 2852 false /* includeLocationSensitiveInfo */, 2853 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag); 2854 } 2855 2856 @Override 2857 public NetworkCapabilities getRedactedNetworkCapabilitiesForPackage( 2858 @NonNull NetworkCapabilities nc, int uid, @NonNull String packageName, 2859 @Nullable String callingAttributionTag) { 2860 Objects.requireNonNull(nc); 2861 Objects.requireNonNull(packageName); 2862 enforceNetworkStackOrSettingsPermission(); 2863 if (!hasAccessPermission(-1 /* pid */, uid)) { 2864 return null; 2865 } 2866 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2867 networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid), 2868 true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName, 2869 callingAttributionTag); 2870 } 2871 2872 private void redactUnderlyingNetworksForCapabilities(NetworkCapabilities nc, int pid, int uid) { 2873 if (nc.getUnderlyingNetworks() != null 2874 && !hasNetworkFactoryOrSettingsPermission(pid, uid)) { 2875 nc.setUnderlyingNetworks(null); 2876 } 2877 } 2878 2879 private boolean canSeeAllowedUids(final int pid, final int uid, final int netOwnerUid) { 2880 return Process.SYSTEM_UID == uid 2881 || netOwnerUid == uid 2882 || hasAnyPermissionOf(mContext, pid, uid, 2883 android.Manifest.permission.NETWORK_FACTORY); 2884 } 2885 2886 @VisibleForTesting 2887 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( 2888 NetworkCapabilities nc, int callerPid, int callerUid) { 2889 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 2890 // this would be expensive (one more permission check every time any NC callback is 2891 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 2892 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 2893 // send the callback) it would crash the system server with NPE. 2894 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 2895 if (!hasSettingsPermission(callerPid, callerUid)) { 2896 newNc.setUids(null); 2897 newNc.setSSID(null); 2898 } 2899 if (newNc.getNetworkSpecifier() != null) { 2900 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); 2901 } 2902 if (!hasAnyPermissionOf(mContext, callerPid, callerUid, 2903 android.Manifest.permission.NETWORK_STACK, 2904 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) { 2905 newNc.setAdministratorUids(new int[0]); 2906 } 2907 if (!canSeeAllowedUids(callerPid, callerUid, newNc.getOwnerUid())) { 2908 newNc.setAllowedUids(new ArraySet<>()); 2909 } 2910 redactUnderlyingNetworksForCapabilities(newNc, callerPid, callerUid); 2911 2912 return newNc; 2913 } 2914 2915 /** 2916 * Wrapper used to cache the permission check results performed for the corresponding 2917 * app. This avoids performing multiple permission checks for different fields in 2918 * NetworkCapabilities. 2919 * Note: This wrapper does not support any sort of invalidation and thus must not be 2920 * persistent or long-lived. It may only be used for the time necessary to 2921 * compute the redactions required by one particular NetworkCallback or 2922 * synchronous call. 2923 */ 2924 private class RedactionPermissionChecker { 2925 private final int mCallingPid; 2926 private final int mCallingUid; 2927 @NonNull private final String mCallingPackageName; 2928 @Nullable private final String mCallingAttributionTag; 2929 2930 private Boolean mHasLocationPermission = null; 2931 private Boolean mHasLocalMacAddressPermission = null; 2932 private Boolean mHasSettingsPermission = null; 2933 2934 RedactionPermissionChecker(int callingPid, int callingUid, 2935 @NonNull String callingPackageName, @Nullable String callingAttributionTag) { 2936 mCallingPid = callingPid; 2937 mCallingUid = callingUid; 2938 mCallingPackageName = callingPackageName; 2939 mCallingAttributionTag = callingAttributionTag; 2940 } 2941 2942 private boolean hasLocationPermissionInternal() { 2943 final long token = Binder.clearCallingIdentity(); 2944 try { 2945 return mLocationPermissionChecker.checkLocationPermission( 2946 mCallingPackageName, mCallingAttributionTag, mCallingUid, 2947 null /* message */); 2948 } finally { 2949 Binder.restoreCallingIdentity(token); 2950 } 2951 } 2952 2953 /** 2954 * Returns whether the app holds location permission or not (might return cached result 2955 * if the permission was already checked before). 2956 */ 2957 public boolean hasLocationPermission() { 2958 if (mHasLocationPermission == null) { 2959 // If there is no cached result, perform the check now. 2960 mHasLocationPermission = hasLocationPermissionInternal(); 2961 } 2962 return mHasLocationPermission; 2963 } 2964 2965 /** 2966 * Returns whether the app holds local mac address permission or not (might return cached 2967 * result if the permission was already checked before). 2968 */ 2969 @CheckResult 2970 public boolean hasLocalMacAddressPermission() { 2971 if (mHasLocalMacAddressPermission == null) { 2972 // If there is no cached result, perform the check now. 2973 mHasLocalMacAddressPermission = ConnectivityService.this 2974 .hasLocalMacAddressPermission(mCallingPid, mCallingUid); 2975 } 2976 return mHasLocalMacAddressPermission; 2977 } 2978 2979 /** 2980 * Returns whether the app holds settings permission or not (might return cached 2981 * result if the permission was already checked before). 2982 */ 2983 @CheckResult 2984 public boolean hasSettingsPermission() { 2985 if (mHasSettingsPermission == null) { 2986 // If there is no cached result, perform the check now. 2987 mHasSettingsPermission = 2988 ConnectivityService.this.hasSettingsPermission(mCallingPid, mCallingUid); 2989 } 2990 return mHasSettingsPermission; 2991 } 2992 } 2993 2994 private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions, 2995 @NetworkCapabilities.NetCapability long redaction) { 2996 return (redactions & redaction) != 0; 2997 } 2998 2999 /** 3000 * Use the provided |applicableRedactions| to check the receiving app's 3001 * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask 3002 * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities 3003 * before being sent to the corresponding app. 3004 */ 3005 private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions( 3006 @NetworkCapabilities.RedactionType long applicableRedactions, 3007 @NonNull RedactionPermissionChecker redactionPermissionChecker, 3008 boolean includeLocationSensitiveInfo) { 3009 long redactions = applicableRedactions; 3010 if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) { 3011 if (includeLocationSensitiveInfo 3012 && redactionPermissionChecker.hasLocationPermission()) { 3013 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION; 3014 } 3015 } 3016 if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) { 3017 if (redactionPermissionChecker.hasLocalMacAddressPermission()) { 3018 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS; 3019 } 3020 } 3021 if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) { 3022 if (redactionPermissionChecker.hasSettingsPermission()) { 3023 redactions &= ~REDACT_FOR_NETWORK_SETTINGS; 3024 } 3025 } 3026 return redactions; 3027 } 3028 3029 @VisibleForTesting 3030 @Nullable 3031 NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled( 3032 @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, 3033 int callingPid, int callingUid, @NonNull String callingPkgName, 3034 @Nullable String callingAttributionTag) { 3035 if (nc == null) { 3036 return null; 3037 } 3038 // Avoid doing location permission check if the transport info has no location sensitive 3039 // data. 3040 final RedactionPermissionChecker redactionPermissionChecker = 3041 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName, 3042 callingAttributionTag); 3043 final long redactions = retrieveRequiredRedactions( 3044 nc.getApplicableRedactions(), redactionPermissionChecker, 3045 includeLocationSensitiveInfo); 3046 final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions); 3047 // Reset owner uid if not destined for the owner app. 3048 // TODO : calling UID is redacted because apps should generally not know what UID is 3049 // bringing up the VPN, but this should not apply to some very privileged apps like settings 3050 if (callingUid != nc.getOwnerUid()) { 3051 newNc.setOwnerUid(INVALID_UID); 3052 return newNc; 3053 } 3054 // Allow VPNs to see ownership of their own VPN networks - not location sensitive. 3055 if (nc.hasTransport(TRANSPORT_VPN)) { 3056 // Owner UIDs already checked above. No need to re-check. 3057 return newNc; 3058 } 3059 // If the calling does not want location sensitive data & target SDK >= S, then mask info. 3060 // Else include the owner UID iff the calling has location permission to provide backwards 3061 // compatibility for older apps. 3062 if (!includeLocationSensitiveInfo 3063 && isTargetSdkAtleast( 3064 Build.VERSION_CODES.S, callingUid, callingPkgName)) { 3065 newNc.setOwnerUid(INVALID_UID); 3066 return newNc; 3067 } 3068 // Reset owner uid if the app has no location permission. 3069 if (!redactionPermissionChecker.hasLocationPermission()) { 3070 newNc.setOwnerUid(INVALID_UID); 3071 } 3072 return newNc; 3073 } 3074 3075 @NonNull 3076 private LinkProperties linkPropertiesRestrictedForCallerPermissions( 3077 LinkProperties lp, int callerPid, int callerUid) { 3078 if (lp == null) return new LinkProperties(); 3079 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 3080 // this would be expensive (one more permission check every time any LP callback is 3081 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 3082 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 3083 // send the callback) it would crash the system server with NPE. 3084 3085 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls. 3086 final boolean needsSanitization = 3087 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null); 3088 if (!needsSanitization) { 3089 return new LinkProperties(lp); 3090 } 3091 3092 if (hasSettingsPermission(callerPid, callerUid)) { 3093 return new LinkProperties(lp, true /* parcelSensitiveFields */); 3094 } 3095 3096 final LinkProperties newLp = new LinkProperties(lp); 3097 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the 3098 // object gets parceled. 3099 newLp.setCaptivePortalApiUrl(null); 3100 newLp.setCaptivePortalData(null); 3101 return newLp; 3102 } 3103 3104 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, 3105 int callerUid, String callerPackageName) { 3106 // There is no need to track the effective UID of the request here. If the caller 3107 // lacks the settings permission, the effective UID is the same as the calling ID. 3108 if (!hasSettingsPermission()) { 3109 // Unprivileged apps can only pass in null or their own UID. 3110 if (nc.getUids() == null) { 3111 // If the caller passes in null, the callback will also match networks that do not 3112 // apply to its UID, similarly to what it would see if it called getAllNetworks. 3113 // In this case, redact everything in the request immediately. This ensures that the 3114 // app is not able to get any redacted information by filing an unredacted request 3115 // and observing whether the request matches something. 3116 if (nc.getNetworkSpecifier() != null) { 3117 nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact()); 3118 } 3119 } else { 3120 nc.setSingleUid(callerUid); 3121 } 3122 } 3123 nc.setRequestorUidAndPackageName(callerUid, callerPackageName); 3124 nc.setAdministratorUids(new int[0]); 3125 3126 // Clear owner UID; this can never come from an app. 3127 nc.setOwnerUid(INVALID_UID); 3128 } 3129 3130 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) { 3131 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) { 3132 nc.addCapability(NET_CAPABILITY_FOREGROUND); 3133 } 3134 } 3135 3136 private void maybeDisableLocalNetworkMatching(NetworkCapabilities nc, int callingUid) { 3137 if (mDeps.isChangeEnabled(ENABLE_MATCH_LOCAL_NETWORK, callingUid)) { 3138 return; 3139 } 3140 // If NET_CAPABILITY_LOCAL_NETWORK is not added to capability, request should not be 3141 // satisfied by local networks. 3142 if (!nc.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)) { 3143 nc.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK); 3144 } 3145 } 3146 3147 private void restrictRequestNetworkCapabilitiesForCaller(NetworkCapabilities nc, 3148 int callingUid, String callerPackageName) { 3149 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callerPackageName); 3150 maybeDisableLocalNetworkMatching(nc, callingUid); 3151 } 3152 3153 @Override 3154 public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() { 3155 enforceAccessPermission(); 3156 final int callerUid = Binder.getCallingUid(); 3157 final long token = Binder.clearCallingIdentity(); 3158 try { 3159 return mPolicyManager.getRestrictBackgroundStatus(callerUid); 3160 } finally { 3161 Binder.restoreCallingIdentity(token); 3162 } 3163 } 3164 3165 // TODO: Consider delete this function or turn it into a no-op method. 3166 @Override 3167 public NetworkState[] getAllNetworkState() { 3168 // This contains IMSI details, so make sure the caller is privileged. 3169 enforceNetworkStackPermission(mContext); 3170 3171 final ArrayList<NetworkState> result = new ArrayList<>(); 3172 for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) { 3173 // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the 3174 // NetworkAgentInfo. 3175 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork()); 3176 if (nai != null && nai.networkInfo.isConnected()) { 3177 result.add(new NetworkState(new NetworkInfo(nai.networkInfo), 3178 snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(), 3179 snapshot.getNetwork(), snapshot.getSubscriberId())); 3180 } 3181 } 3182 return result.toArray(new NetworkState[0]); 3183 } 3184 3185 @Override 3186 @NonNull 3187 public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() { 3188 // This contains IMSI details, so make sure the caller is privileged. 3189 enforceNetworkStackOrSettingsPermission(); 3190 3191 final ArrayList<NetworkStateSnapshot> result = new ArrayList<>(); 3192 for (Network network : getAllNetworks()) { 3193 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3194 final boolean includeNetwork = (nai != null) && nai.isCreated(); 3195 if (includeNetwork) { 3196 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the 3197 // NetworkCapabilities, which may contain UIDs of apps to which the 3198 // network applies. Should the UIDs be cleared so as not to leak or 3199 // interfere ? 3200 result.add(nai.getNetworkStateSnapshot()); 3201 } 3202 } 3203 return result; 3204 } 3205 3206 @Override 3207 public boolean isActiveNetworkMetered() { 3208 enforceAccessPermission(); 3209 3210 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork()); 3211 if (caps != null) { 3212 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 3213 } else { 3214 // Always return the most conservative value 3215 return true; 3216 } 3217 } 3218 3219 /** 3220 * Ensures that the system cannot call a particular method. 3221 */ 3222 private boolean disallowedBecauseSystemCaller() { 3223 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling 3224 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost 3225 // for devices launched with Q and above. However, existing devices upgrading to Q and 3226 // above must continued to be supported for few more releases. 3227 if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt( 3228 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) { 3229 log("This method exists only for app backwards compatibility" 3230 + " and must not be called by system services."); 3231 return true; 3232 } 3233 return false; 3234 } 3235 3236 /** 3237 * Ensure that a network route exists to deliver traffic to the specified 3238 * host via the specified network interface. 3239 * @param networkType the type of the network over which traffic to the 3240 * specified host is to be routed 3241 * @param hostAddress the IP address of the host to which the route is 3242 * desired 3243 * @return {@code true} on success, {@code false} on failure 3244 */ 3245 @Override 3246 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, 3247 String callingPackageName, String callingAttributionTag) { 3248 if (disallowedBecauseSystemCaller()) { 3249 return false; 3250 } 3251 PermissionUtils.enforcePackageNameMatchesUid( 3252 mContext, mDeps.getCallingUid(), callingPackageName); 3253 enforceChangePermission(callingPackageName, callingAttributionTag); 3254 if (mProtectedNetworks.contains(networkType)) { 3255 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 3256 } 3257 3258 InetAddress addr; 3259 try { 3260 addr = InetAddress.getByAddress(hostAddress); 3261 } catch (UnknownHostException e) { 3262 if (DBG) log("requestRouteToHostAddress got " + e); 3263 return false; 3264 } 3265 3266 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 3267 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 3268 return false; 3269 } 3270 3271 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 3272 if (nai == null) { 3273 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 3274 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 3275 } else { 3276 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 3277 } 3278 return false; 3279 } 3280 3281 DetailedState netState; 3282 synchronized (nai) { 3283 netState = nai.networkInfo.getDetailedState(); 3284 } 3285 3286 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 3287 if (VDBG) { 3288 log("requestRouteToHostAddress on down network " 3289 + "(" + networkType + ") - dropped" 3290 + " netState=" + netState); 3291 } 3292 return false; 3293 } 3294 3295 final int uid = mDeps.getCallingUid(); 3296 final long token = Binder.clearCallingIdentity(); 3297 try { 3298 LinkProperties lp; 3299 int netId; 3300 synchronized (nai) { 3301 lp = nai.linkProperties; 3302 netId = nai.network.getNetId(); 3303 } 3304 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 3305 if (DBG) { 3306 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok); 3307 } 3308 return ok; 3309 } finally { 3310 Binder.restoreCallingIdentity(token); 3311 } 3312 } 3313 3314 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 3315 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 3316 if (bestRoute == null) { 3317 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 3318 } else { 3319 String iface = bestRoute.getInterface(); 3320 if (bestRoute.getGateway().equals(addr)) { 3321 // if there is no better route, add the implied hostroute for our gateway 3322 bestRoute = RouteInfo.makeHostRoute(addr, iface); 3323 } else { 3324 // if we will connect to this through another route, add a direct route 3325 // to it's gateway 3326 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 3327 } 3328 } 3329 if (DBG) log("Adding legacy route " + bestRoute + 3330 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 3331 3332 final String dst = bestRoute.getDestinationLinkAddress().toString(); 3333 final String nextHop = bestRoute.hasGateway() 3334 ? bestRoute.getGateway().getHostAddress() : ""; 3335 try { 3336 mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid); 3337 } catch (RemoteException | ServiceSpecificException e) { 3338 if (DBG) loge("Exception trying to add a route: " + e); 3339 return false; 3340 } 3341 return true; 3342 } 3343 3344 class DnsResolverUnsolicitedEventCallback extends 3345 IDnsResolverUnsolicitedEventListener.Stub { 3346 @Override 3347 public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { 3348 try { 3349 mHandler.sendMessage(mHandler.obtainMessage( 3350 EVENT_PRIVATE_DNS_VALIDATION_UPDATE, 3351 new PrivateDnsValidationUpdate(event.netId, 3352 InetAddresses.parseNumericAddress(event.ipAddress), 3353 event.hostname, event.validation))); 3354 } catch (IllegalArgumentException e) { 3355 loge("Error parsing ip address in validation event"); 3356 } 3357 } 3358 3359 @Override 3360 public void onDnsHealthEvent(final DnsHealthEventParcel event) { 3361 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); 3362 // Netd event only allow registrants from system. Each NetworkMonitor thread is under 3363 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd 3364 // event callback for certain nai. e.g. cellular. Register here to pass to 3365 // NetworkMonitor instead. 3366 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allows one 3367 // callback from each caller type. Need to re-factor NetdEventListenerService to allow 3368 // multiple NetworkMonitor registrants. 3369 if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { 3370 nai.networkMonitor().notifyDnsResponse(event.healthResult); 3371 } 3372 } 3373 3374 @Override 3375 public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { 3376 mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, 3377 event.prefixAddress, event.prefixLength)); 3378 } 3379 3380 @Override 3381 public int getInterfaceVersion() { 3382 return this.VERSION; 3383 } 3384 3385 @Override 3386 public String getInterfaceHash() { 3387 return this.HASH; 3388 } 3389 } 3390 3391 @VisibleForTesting 3392 protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = 3393 new DnsResolverUnsolicitedEventCallback(); 3394 3395 private void registerDnsResolverUnsolicitedEventListener() { 3396 try { 3397 mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); 3398 } catch (Exception e) { 3399 loge("Error registering DnsResolver unsolicited event callback: " + e); 3400 } 3401 } 3402 3403 private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() { 3404 @Override 3405 public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 3406 if (shouldTrackUidsForBlockedStatusCallbacks()) { 3407 Log.wtf(TAG, "Received unexpected NetworkPolicy callback"); 3408 return; 3409 } 3410 mHandler.sendMessage(mHandler.obtainMessage( 3411 EVENT_BLOCKED_REASONS_CHANGED, 3412 List.of(new Pair<>(uid, blockedReasons)))); 3413 } 3414 }; 3415 3416 private boolean shouldTrackUidsForBlockedStatusCallbacks() { 3417 return mDeps.isAtLeastV(); 3418 } 3419 3420 @VisibleForTesting 3421 void handleBlockedReasonsChanged(List<Pair<Integer, Integer>> reasonsList) { 3422 for (Pair<Integer, Integer> reasons: reasonsList) { 3423 final int uid = reasons.first; 3424 final int blockedReasons = reasons.second; 3425 if (shouldTrackUidsForBlockedStatusCallbacks()) { 3426 synchronized (mBlockedStatusTrackingUids) { 3427 if (mBlockedStatusTrackingUids.get(uid) == 0) { 3428 // This uid is not tracked anymore. 3429 // This can happen if the network request is unregistered while 3430 // EVENT_BLOCKED_REASONS_CHANGED is posted but not processed yet. 3431 continue; 3432 } 3433 } 3434 } 3435 maybeNotifyNetworkBlockedForNewState(uid, blockedReasons); 3436 setUidBlockedReasons(uid, blockedReasons); 3437 } 3438 } 3439 3440 static final class UidFrozenStateChangedArgs { 3441 final int[] mUids; 3442 final int[] mFrozenStates; 3443 3444 UidFrozenStateChangedArgs(int[] uids, int[] frozenStates) { 3445 mUids = uids; 3446 mFrozenStates = frozenStates; 3447 } 3448 } 3449 3450 /** 3451 * Check if the cell network is idle. 3452 * @return true if the cell network state is idle 3453 * false if the cell network state is active or unknown 3454 */ 3455 private boolean isCellNetworkIdle() { 3456 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 3457 if (defaultNai == null 3458 || !defaultNai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { 3459 // mNetworkActivityTracker only tracks the activity of the default network. So if the 3460 // cell network is not the default network, cell network state is unknown. 3461 // TODO(b/279380356): Track cell network state when the cell is not the default network 3462 return false; 3463 } 3464 3465 return !mNetworkActivityTracker.isDefaultNetworkActive(); 3466 } 3467 3468 private boolean shouldTrackFirewallDestroySocketReasons() { 3469 return mDeps.isAtLeastV(); 3470 } 3471 3472 private void updateDestroySocketReasons(final int uid, final int reason, 3473 final boolean addReason) { 3474 final int destroyReasons = mDestroySocketPendingUids.get(uid, DESTROY_SOCKET_REASON_NONE); 3475 if (addReason) { 3476 mDestroySocketPendingUids.put(uid, destroyReasons | reason); 3477 } else { 3478 final int newDestroyReasons = destroyReasons & ~reason; 3479 if (newDestroyReasons == DESTROY_SOCKET_REASON_NONE) { 3480 mDestroySocketPendingUids.delete(uid); 3481 } else { 3482 mDestroySocketPendingUids.put(uid, newDestroyReasons); 3483 } 3484 } 3485 } 3486 3487 private void handleFrozenUids(int[] uids, int[] frozenStates) { 3488 ensureRunningOnConnectivityServiceThread(); 3489 for (int i = 0; i < uids.length; i++) { 3490 final int uid = uids[i]; 3491 final boolean addReason = frozenStates[i] == UID_FROZEN_STATE_FROZEN; 3492 updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FROZEN, addReason); 3493 } 3494 3495 if (!mDelayDestroySockets || !isCellNetworkIdle()) { 3496 destroyPendingSockets(); 3497 } 3498 } 3499 3500 private void handleUpdateFirewallDestroySocketReasons( 3501 List<Pair<Integer, Integer>> reasonsList) { 3502 if (!shouldTrackFirewallDestroySocketReasons()) { 3503 Log.wtf(TAG, "handleUpdateFirewallDestroySocketReasons is called unexpectedly"); 3504 return; 3505 } 3506 ensureRunningOnConnectivityServiceThread(); 3507 3508 for (Pair<Integer, Integer> uidSocketDestroyReasons: reasonsList) { 3509 final int uid = uidSocketDestroyReasons.first; 3510 final int reasons = uidSocketDestroyReasons.second; 3511 final boolean destroyByFirewallBackground = 3512 (reasons & DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND) 3513 != DESTROY_SOCKET_REASON_NONE; 3514 updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND, 3515 destroyByFirewallBackground); 3516 } 3517 3518 if (!mDelayDestroySockets || !isCellNetworkIdle()) { 3519 destroyPendingSockets(); 3520 } 3521 } 3522 3523 private void handleClearFirewallDestroySocketReasons(final int reason) { 3524 if (!shouldTrackFirewallDestroySocketReasons()) { 3525 Log.wtf(TAG, "handleClearFirewallDestroySocketReasons is called uexpectedly"); 3526 return; 3527 } 3528 ensureRunningOnConnectivityServiceThread(); 3529 3530 // Unset reason from all pending uids 3531 for (int i = mDestroySocketPendingUids.size() - 1; i >= 0; i--) { 3532 final int uid = mDestroySocketPendingUids.keyAt(i); 3533 updateDestroySocketReasons(uid, reason, false /* addReason */); 3534 } 3535 } 3536 3537 private void destroyPendingSockets() { 3538 ensureRunningOnConnectivityServiceThread(); 3539 if (mDestroySocketPendingUids.size() == 0) { 3540 return; 3541 } 3542 3543 Set<Integer> uids = new ArraySet<>(); 3544 for (int i = 0; i < mDestroySocketPendingUids.size(); i++) { 3545 uids.add(mDestroySocketPendingUids.keyAt(i)); 3546 } 3547 3548 try { 3549 mDeps.destroyLiveTcpSocketsByOwnerUids(uids); 3550 } catch (SocketException | InterruptedIOException | ErrnoException e) { 3551 loge("Failed to destroy sockets: " + e); 3552 } 3553 mDestroySocketPendingUids.clear(); 3554 } 3555 3556 private void handleReportNetworkActivity(final NetworkActivityParams params) { 3557 mNetworkActivityTracker.handleReportNetworkActivity(params); 3558 3559 final boolean isCellNetworkActivity; 3560 if (mTrackMultiNetworkActivities) { 3561 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(params.label); 3562 // nai could be null if netd receives a netlink message and calls the network 3563 // activity change callback after the network is unregistered from ConnectivityService. 3564 isCellNetworkActivity = nai != null 3565 && nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3566 } else { 3567 isCellNetworkActivity = params.label == TRANSPORT_CELLULAR; 3568 } 3569 3570 if (mDelayDestroySockets && params.isActive && isCellNetworkActivity) { 3571 destroyPendingSockets(); 3572 } 3573 } 3574 3575 /** 3576 * If the cellular network is no longer the default network, destroy pending sockets. 3577 * 3578 * @param newNetwork new default network 3579 * @param oldNetwork old default network 3580 */ 3581 private void maybeDestroyPendingSockets(NetworkAgentInfo newNetwork, 3582 NetworkAgentInfo oldNetwork) { 3583 final boolean isOldNetworkCellular = oldNetwork != null 3584 && oldNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3585 final boolean isNewNetworkCellular = newNetwork != null 3586 && newNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3587 3588 if (isOldNetworkCellular && !isNewNetworkCellular) { 3589 destroyPendingSockets(); 3590 } 3591 } 3592 3593 private void dumpDestroySockets(IndentingPrintWriter pw) { 3594 pw.println("DestroySockets:"); 3595 pw.increaseIndent(); 3596 pw.print("mDestroyFrozenSockets="); pw.println(mDestroyFrozenSockets); 3597 pw.print("mDelayDestroySockets="); pw.println(mDelayDestroySockets); 3598 pw.print("mDestroySocketPendingUids:"); 3599 pw.increaseIndent(); 3600 for (int i = 0; i < mDestroySocketPendingUids.size(); i++) { 3601 final int uid = mDestroySocketPendingUids.keyAt(i); 3602 final int reasons = mDestroySocketPendingUids.valueAt(i); 3603 pw.print(uid + ": reasons=" + reasons); 3604 } 3605 pw.decreaseIndent(); 3606 pw.decreaseIndent(); 3607 } 3608 3609 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 3610 private void dumpBpfProgramStatus(IndentingPrintWriter pw) { 3611 pw.println("Bpf Program Status:"); 3612 pw.increaseIndent(); 3613 try { 3614 pw.print("CGROUP_INET_INGRESS: "); 3615 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS)); 3616 pw.print("CGROUP_INET_EGRESS: "); 3617 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS)); 3618 3619 pw.print("CGROUP_INET_SOCK_CREATE: "); 3620 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE)); 3621 3622 pw.print("CGROUP_INET4_BIND: "); 3623 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND)); 3624 pw.print("CGROUP_INET6_BIND: "); 3625 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND)); 3626 3627 pw.print("CGROUP_INET4_CONNECT: "); 3628 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_CONNECT)); 3629 pw.print("CGROUP_INET6_CONNECT: "); 3630 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_CONNECT)); 3631 3632 pw.print("CGROUP_UDP4_SENDMSG: "); 3633 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_SENDMSG)); 3634 pw.print("CGROUP_UDP6_SENDMSG: "); 3635 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_SENDMSG)); 3636 3637 pw.print("CGROUP_UDP4_RECVMSG: "); 3638 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_RECVMSG)); 3639 pw.print("CGROUP_UDP6_RECVMSG: "); 3640 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_RECVMSG)); 3641 3642 pw.print("CGROUP_GETSOCKOPT: "); 3643 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_GETSOCKOPT)); 3644 pw.print("CGROUP_SETSOCKOPT: "); 3645 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_SETSOCKOPT)); 3646 3647 pw.print("CGROUP_INET_SOCK_RELEASE: "); 3648 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_RELEASE)); 3649 } catch (IOException e) { 3650 pw.println(" IOException"); 3651 } 3652 pw.decreaseIndent(); 3653 } 3654 3655 @VisibleForTesting 3656 static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version"; 3657 3658 @VisibleForTesting 3659 public static final String ALLOW_SYSUI_CONNECTIVITY_REPORTS = 3660 "allow_sysui_connectivity_reports"; 3661 3662 public static final String ALLOW_SATALLITE_NETWORK_FALLBACK = 3663 "allow_satallite_network_fallback"; 3664 3665 private void enforceInternetPermission() { 3666 mContext.enforceCallingOrSelfPermission( 3667 android.Manifest.permission.INTERNET, 3668 "ConnectivityService"); 3669 } 3670 3671 private void enforceAccessPermission() { 3672 mContext.enforceCallingOrSelfPermission( 3673 android.Manifest.permission.ACCESS_NETWORK_STATE, 3674 "ConnectivityService"); 3675 } 3676 3677 @CheckResult 3678 private boolean hasAccessPermission(int pid, int uid) { 3679 return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid) 3680 == PERMISSION_GRANTED; 3681 } 3682 3683 /** 3684 * Performs a strict and comprehensive check of whether a calling package is allowed to 3685 * change the state of network, as the condition differs for pre-M, M+, and 3686 * privileged/preinstalled apps. The caller is expected to have either the 3687 * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these 3688 * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and 3689 * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal 3690 * permission and cannot be revoked. See http://b/23597341 3691 * 3692 * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation 3693 * of this app will be updated to the current time. 3694 */ 3695 private void enforceChangePermission(String callingPkg, String callingAttributionTag) { 3696 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) 3697 == PackageManager.PERMISSION_GRANTED) { 3698 return; 3699 } 3700 3701 if (callingPkg == null) { 3702 throw new SecurityException("Calling package name is null."); 3703 } 3704 3705 final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class); 3706 final int uid = mDeps.getCallingUid(); 3707 final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid, 3708 callingPkg, callingAttributionTag, null /* message */); 3709 3710 if (mode == AppOpsManager.MODE_ALLOWED) { 3711 return; 3712 } 3713 3714 if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission( 3715 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) { 3716 return; 3717 } 3718 3719 throw new SecurityException(callingPkg + " was not granted either of these permissions:" 3720 + android.Manifest.permission.CHANGE_NETWORK_STATE + "," 3721 + android.Manifest.permission.WRITE_SETTINGS + "."); 3722 } 3723 3724 private void enforceSettingsPermission() { 3725 enforceAnyPermissionOf(mContext, 3726 android.Manifest.permission.NETWORK_SETTINGS, 3727 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3728 } 3729 3730 private void enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission() { 3731 enforceAnyPermissionOf(mContext, 3732 android.Manifest.permission.NETWORK_SETTINGS, 3733 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3734 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3735 Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS); 3736 } 3737 3738 private void enforceNetworkFactoryPermission() { 3739 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3740 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3741 enforceAnyPermissionOf(mContext, 3742 android.Manifest.permission.NETWORK_FACTORY, 3743 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3744 } 3745 3746 private void enforceNetworkFactoryOrSettingsPermission() { 3747 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3748 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3749 enforceAnyPermissionOf(mContext, 3750 android.Manifest.permission.NETWORK_SETTINGS, 3751 android.Manifest.permission.NETWORK_FACTORY, 3752 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3753 } 3754 3755 private void enforceNetworkFactoryOrTestNetworksPermission() { 3756 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3757 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3758 enforceAnyPermissionOf(mContext, 3759 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3760 android.Manifest.permission.NETWORK_FACTORY, 3761 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3762 } 3763 3764 @CheckResult 3765 private boolean hasNetworkFactoryOrSettingsPermission(int pid, int uid) { 3766 return PERMISSION_GRANTED == mContext.checkPermission( 3767 android.Manifest.permission.NETWORK_FACTORY, pid, uid) 3768 || PERMISSION_GRANTED == mContext.checkPermission( 3769 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3770 || PERMISSION_GRANTED == mContext.checkPermission( 3771 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid) 3772 || UserHandle.getAppId(uid) == Process.BLUETOOTH_UID; 3773 } 3774 3775 @CheckResult 3776 private boolean hasSettingsPermission() { 3777 return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS, 3778 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3779 } 3780 3781 @CheckResult 3782 private boolean hasSettingsPermission(int pid, int uid) { 3783 return PERMISSION_GRANTED == mContext.checkPermission( 3784 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3785 || PERMISSION_GRANTED == mContext.checkPermission( 3786 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid); 3787 } 3788 3789 private void enforceNetworkStackOrSettingsPermission() { 3790 enforceNetworkStackPermissionOr(mContext, 3791 android.Manifest.permission.NETWORK_SETTINGS); 3792 } 3793 3794 private void enforceNetworkStackSettingsOrSetup() { 3795 enforceNetworkStackPermissionOr(mContext, 3796 android.Manifest.permission.NETWORK_SETTINGS, 3797 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3798 } 3799 3800 private void enforceAirplaneModePermission() { 3801 enforceNetworkStackPermissionOr(mContext, 3802 android.Manifest.permission.NETWORK_AIRPLANE_MODE, 3803 android.Manifest.permission.NETWORK_SETTINGS, 3804 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3805 } 3806 3807 private void enforceOemNetworkPreferencesPermission() { 3808 mContext.enforceCallingOrSelfPermission( 3809 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, 3810 "ConnectivityService"); 3811 } 3812 3813 private void enforceManageTestNetworksPermission() { 3814 mContext.enforceCallingOrSelfPermission( 3815 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3816 "ConnectivityService"); 3817 } 3818 3819 @CheckResult 3820 private boolean hasNetworkStackPermission() { 3821 return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_STACK, 3822 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3823 } 3824 3825 @CheckResult 3826 private boolean hasNetworkStackPermission(int pid, int uid) { 3827 return hasAnyPermissionOf(mContext, pid, uid, android.Manifest.permission.NETWORK_STACK, 3828 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3829 } 3830 3831 @CheckResult 3832 private boolean hasSystemBarServicePermission(int pid, int uid) { 3833 return hasAnyPermissionOf(mContext, pid, uid, 3834 android.Manifest.permission.STATUS_BAR_SERVICE); 3835 } 3836 3837 @CheckResult 3838 private boolean hasNetworkSignalStrengthWakeupPermission(int pid, int uid) { 3839 return hasAnyPermissionOf(mContext, pid, uid, 3840 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, 3841 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3842 android.Manifest.permission.NETWORK_SETTINGS); 3843 } 3844 3845 @CheckResult 3846 private boolean hasConnectivityRestrictedNetworksPermission(int callingUid, 3847 boolean checkUidsAllowedList) { 3848 if (hasAnyPermissionOf(mContext, 3849 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)) { 3850 return true; 3851 } 3852 3853 // fallback to ConnectivityInternalPermission 3854 // TODO: Remove this fallback check after all apps have declared 3855 // CONNECTIVITY_USE_RESTRICTED_NETWORKS. 3856 if (hasAnyPermissionOf(mContext, android.Manifest.permission.CONNECTIVITY_INTERNAL)) { 3857 return true; 3858 } 3859 3860 // Check whether uid is in allowed on restricted networks list. 3861 if (checkUidsAllowedList 3862 && mPermissionMonitor.isUidAllowedOnRestrictedNetworks(callingUid)) { 3863 return true; 3864 } 3865 return false; 3866 } 3867 3868 private void enforceConnectivityRestrictedNetworksPermission(boolean checkUidsAllowedList) { 3869 final int callingUid = mDeps.getCallingUid(); 3870 if (!hasConnectivityRestrictedNetworksPermission(callingUid, checkUidsAllowedList)) { 3871 throw new SecurityException("ConnectivityService: user " + callingUid 3872 + " has no permission to access restricted network."); 3873 } 3874 } 3875 3876 private void enforceKeepalivePermission() { 3877 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 3878 } 3879 3880 @CheckResult 3881 private boolean hasLocalMacAddressPermission(int pid, int uid) { 3882 return PERMISSION_GRANTED == mContext.checkPermission( 3883 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid); 3884 } 3885 3886 private void sendConnectedBroadcast(NetworkInfo info) { 3887 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 3888 } 3889 3890 private void sendInetConditionBroadcast(NetworkInfo info) { 3891 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 3892 } 3893 3894 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 3895 Intent intent = new Intent(bcastType); 3896 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 3897 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 3898 if (info.isFailover()) { 3899 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 3900 info.setFailover(false); 3901 } 3902 if (info.getReason() != null) { 3903 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 3904 } 3905 if (info.getExtraInfo() != null) { 3906 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 3907 info.getExtraInfo()); 3908 } 3909 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 3910 return intent; 3911 } 3912 3913 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 3914 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 3915 } 3916 3917 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 3918 @SuppressLint("NewApi") 3919 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 3920 @TargetApi(Build.VERSION_CODES.S) 3921 private void sendStickyBroadcast(Intent intent) { 3922 synchronized (this) { 3923 if (!mSystemReady 3924 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 3925 mInitialBroadcast = new Intent(intent); 3926 } 3927 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3928 if (VDBG) { 3929 log("sendStickyBroadcast: action=" + intent.getAction()); 3930 } 3931 3932 Bundle options = null; 3933 final long ident = Binder.clearCallingIdentity(); 3934 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 3935 final NetworkInfo ni = intent.getParcelableExtra( 3936 ConnectivityManager.EXTRA_NETWORK_INFO); 3937 final BroadcastOptions opts = BroadcastOptions.makeBasic(); 3938 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 3939 applyMostRecentPolicyForConnectivityAction(opts, ni); 3940 options = opts.toBundle(); 3941 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 3942 } 3943 try { 3944 mUserAllContext.sendStickyBroadcast(intent, options); 3945 } finally { 3946 Binder.restoreCallingIdentity(ident); 3947 } 3948 } 3949 } 3950 3951 private void applyMostRecentPolicyForConnectivityAction(BroadcastOptions options, 3952 NetworkInfo info) { 3953 // Delivery group policy APIs are only available on U+. 3954 if (!mDeps.isAtLeastU()) return; 3955 3956 final BroadcastOptionsShim optsShim = mDeps.makeBroadcastOptionsShim(options); 3957 try { 3958 // This allows us to discard older broadcasts still waiting to be delivered 3959 // which have the same namespace and key. 3960 optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT); 3961 optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION, 3962 createDeliveryGroupKeyForConnectivityAction(info)); 3963 optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE); 3964 } catch (UnsupportedApiLevelException e) { 3965 Log.wtf(TAG, "Using unsupported API" + e); 3966 } 3967 } 3968 3969 @VisibleForTesting 3970 static String createDeliveryGroupKeyForConnectivityAction(NetworkInfo info) { 3971 final StringBuilder sb = new StringBuilder(); 3972 sb.append(info.getType()).append(DELIVERY_GROUP_KEY_DELIMITER); 3973 sb.append(info.getSubtype()).append(DELIVERY_GROUP_KEY_DELIMITER); 3974 sb.append(info.getExtraInfo()); 3975 return sb.toString(); 3976 } 3977 3978 /** 3979 * Called by SystemServer through ConnectivityManager when the system is ready. 3980 */ 3981 @Override 3982 public void systemReady() { 3983 if (mDeps.getCallingUid() != Process.SYSTEM_UID) { 3984 throw new SecurityException("Calling Uid is not system uid."); 3985 } 3986 systemReadyInternal(); 3987 } 3988 3989 /** 3990 * Called when ConnectivityService can initialize remaining components. 3991 */ 3992 @VisibleForTesting 3993 public void systemReadyInternal() { 3994 // Load flags after PackageManager is ready to query module version 3995 mFlags.loadFlags(mDeps, mContext); 3996 3997 // Since mApps in PermissionMonitor needs to be populated first to ensure that 3998 // listening network request which is sent by MultipathPolicyTracker won't be added 3999 // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must 4000 // be called after PermissionMonitor#startMonitoring(). 4001 // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the 4002 // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady() 4003 // to ensure the tracking will be initialized correctly. 4004 final ConditionVariable startMonitoringDone = new ConditionVariable(); 4005 mHandler.post(() -> { 4006 mPermissionMonitor.startMonitoring(); 4007 startMonitoringDone.open(); 4008 }); 4009 mProxyTracker.loadGlobalProxy(); 4010 registerDnsResolverUnsolicitedEventListener(); 4011 4012 synchronized (this) { 4013 mSystemReady = true; 4014 if (mInitialBroadcast != null) { 4015 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 4016 mInitialBroadcast = null; 4017 } 4018 } 4019 4020 // Create network requests for always-on networks. 4021 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); 4022 4023 // Update mobile data preference if necessary. 4024 // Note that updating can be skipped here if the list is empty only because no uid 4025 // rules are applied before system ready. Normally, the empty uid list means to clear 4026 // the uids rules on netd. 4027 if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) { 4028 updateMobileDataPreferredUids(); 4029 } 4030 4031 if (mSatelliteAccessController != null) { 4032 mSatelliteAccessController.start(); 4033 } 4034 4035 if (mCarrierPrivilegeAuthenticator != null) { 4036 mCarrierPrivilegeAuthenticator.start(); 4037 } 4038 4039 // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom 4040 if (mDeps.isAtLeastT()) { 4041 mBpfNetMaps.setPullAtomCallback(mContext); 4042 } 4043 ConnectivitySampleMetricsHelper.start(mContext, mHandler, 4044 CONNECTIVITY_STATE_SAMPLE, this::sampleConnectivityStateToStatsEvent); 4045 // Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't 4046 // have permission problem. While CV#block() is unbounded in time and can in principle block 4047 // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which 4048 // could have blocked forever too. 4049 startMonitoringDone.block(); 4050 } 4051 4052 /** 4053 * Start listening for default data network activity state changes. 4054 */ 4055 @Override 4056 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 4057 mNetworkActivityTracker.registerNetworkActivityListener(l); 4058 } 4059 4060 /** 4061 * Stop listening for default data network activity state changes. 4062 */ 4063 @Override 4064 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 4065 mNetworkActivityTracker.unregisterNetworkActivityListener(l); 4066 } 4067 4068 /** 4069 * Check whether the default network radio is currently active. 4070 */ 4071 @Override 4072 public boolean isDefaultNetworkActive() { 4073 return mNetworkActivityTracker.isDefaultNetworkActive(); 4074 } 4075 4076 /** 4077 * Reads the network specific MTU size from resources. 4078 * and set it on it's iface. 4079 */ 4080 private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 4081 final String iface = newLp.getInterfaceName(); 4082 final int mtu = newLp.getMtu(); 4083 if (mtu == 0) { 4084 // Silently ignore unset MTU value. 4085 return; 4086 } 4087 if (oldLp != null && newLp.isIdenticalMtu(oldLp) 4088 && TextUtils.equals(oldLp.getInterfaceName(), iface)) { 4089 if (VDBG) log("identical MTU and iface - not setting"); 4090 return; 4091 } 4092 // Cannot set MTU without interface name 4093 if (TextUtils.isEmpty(iface)) { 4094 if (VDBG) log("Setting MTU size with null iface."); 4095 return; 4096 } 4097 4098 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) { 4099 loge("Unexpected mtu value: " + mtu + ", " + iface); 4100 return; 4101 } 4102 4103 try { 4104 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); 4105 mNetd.interfaceSetMtu(iface, mtu); 4106 } catch (RemoteException | ServiceSpecificException e) { 4107 loge("exception in interfaceSetMtu()" + e); 4108 } 4109 } 4110 4111 @VisibleForTesting 4112 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 4113 4114 private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) { 4115 String[] values = null; 4116 if (tcpBufferSizes != null) { 4117 values = tcpBufferSizes.split(","); 4118 } 4119 4120 if (values == null || values.length != 6) { 4121 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 4122 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 4123 values = tcpBufferSizes.split(","); 4124 } 4125 4126 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 4127 4128 try { 4129 if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes); 4130 4131 String rmemValues = String.join(" ", values[0], values[1], values[2]); 4132 String wmemValues = String.join(" ", values[3], values[4], values[5]); 4133 mNetd.setTcpRWmemorySize(rmemValues, wmemValues); 4134 mCurrentTcpBufferSizes = tcpBufferSizes; 4135 } catch (RemoteException | ServiceSpecificException e) { 4136 loge("Can't set TCP buffer sizes:" + e); 4137 } 4138 } 4139 4140 @Override 4141 public int getRestoreDefaultNetworkDelay(int networkType) { 4142 String restoreDefaultNetworkDelayStr = mSystemProperties.get( 4143 NETWORK_RESTORE_DELAY_PROP_NAME); 4144 if(restoreDefaultNetworkDelayStr != null && 4145 restoreDefaultNetworkDelayStr.length() != 0) { 4146 try { 4147 return Integer.parseInt(restoreDefaultNetworkDelayStr); 4148 } catch (NumberFormatException e) { 4149 } 4150 } 4151 // if the system property isn't set, use the value for the apn type 4152 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 4153 4154 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 4155 ret = mLegacyTypeTracker.getRestoreTimerForType(networkType); 4156 } 4157 return ret; 4158 } 4159 4160 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 4161 final List<NetworkDiagnostics> netDiags = new ArrayList<>(); 4162 final long DIAG_TIME_MS = 5000; 4163 for (NetworkAgentInfo nai : networksSortedById()) { 4164 PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network); 4165 // Start gathering diagnostic information. 4166 netDiags.add(new NetworkDiagnostics( 4167 nai.network, 4168 new LinkProperties(nai.linkProperties), // Must be a copy. 4169 privateDnsCfg, 4170 DIAG_TIME_MS)); 4171 } 4172 4173 for (NetworkDiagnostics netDiag : netDiags) { 4174 pw.println(); 4175 netDiag.waitForMeasurements(); 4176 netDiag.dump(pw); 4177 } 4178 } 4179 4180 @Override 4181 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, 4182 @Nullable String[] args) { 4183 if (!hasDumpPermission(mContext, TAG, writer)) return; 4184 4185 mPriorityDumper.dump(fd, writer, args); 4186 } 4187 4188 @CheckResult 4189 private boolean hasDumpPermission(Context context, String tag, PrintWriter pw) { 4190 if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4191 != PackageManager.PERMISSION_GRANTED) { 4192 pw.println("Permission Denial: can't dump " + tag + " from from pid=" 4193 + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid() 4194 + " due to missing android.permission.DUMP permission"); 4195 return false; 4196 } else { 4197 return true; 4198 } 4199 } 4200 4201 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) { 4202 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 4203 4204 if (CollectionUtils.contains(args, DIAG_ARG)) { 4205 dumpNetworkDiagnostics(pw); 4206 return; 4207 } else if (CollectionUtils.contains(args, NETWORK_ARG)) { 4208 dumpNetworks(pw); 4209 return; 4210 } else if (CollectionUtils.contains(args, REQUEST_ARG)) { 4211 dumpNetworkRequests(pw); 4212 return; 4213 } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) { 4214 boolean verbose = !CollectionUtils.contains(args, SHORT_ARG); 4215 dumpTrafficController(pw, fd, verbose); 4216 return; 4217 } else if (CollectionUtils.contains(args, CLATEGRESS4RAWBPFMAP_ARG)) { 4218 dumpClatBpfRawMap(pw, true /* isEgress4Map */); 4219 return; 4220 } else if (CollectionUtils.contains(args, CLATINGRESS6RAWBPFMAP_ARG)) { 4221 dumpClatBpfRawMap(pw, false /* isEgress4Map */); 4222 return; 4223 } 4224 4225 pw.println("NetworkProviders for:"); 4226 pw.increaseIndent(); 4227 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 4228 pw.println(npi.providerId + ": " + npi.name); 4229 } 4230 pw.decreaseIndent(); 4231 pw.println(); 4232 4233 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 4234 pw.print("Active default network: "); 4235 if (defaultNai == null) { 4236 pw.println("none"); 4237 } else { 4238 pw.println(defaultNai.network.getNetId()); 4239 } 4240 pw.println(); 4241 4242 pw.println("Current network preferences: "); 4243 pw.increaseIndent(); 4244 dumpNetworkPreferences(pw); 4245 pw.decreaseIndent(); 4246 pw.println(); 4247 4248 pw.println("Current Networks:"); 4249 pw.increaseIndent(); 4250 dumpNetworks(pw); 4251 pw.decreaseIndent(); 4252 pw.println(); 4253 4254 pw.println("Status for known UIDs:"); 4255 pw.increaseIndent(); 4256 final int size = mUidBlockedReasons.size(); 4257 for (int i = 0; i < size; i++) { 4258 // Don't crash if the array is modified while dumping in bugreports. 4259 try { 4260 final int uid = mUidBlockedReasons.keyAt(i); 4261 final int blockedReasons = mUidBlockedReasons.valueAt(i); 4262 pw.println("UID=" + uid + " blockedReasons=" 4263 + Integer.toHexString(blockedReasons)); 4264 } catch (ArrayIndexOutOfBoundsException e) { 4265 pw.println(" ArrayIndexOutOfBoundsException"); 4266 } catch (ConcurrentModificationException e) { 4267 pw.println(" ConcurrentModificationException"); 4268 } 4269 } 4270 pw.println(); 4271 pw.decreaseIndent(); 4272 4273 pw.println("Network Requests:"); 4274 pw.increaseIndent(); 4275 dumpNetworkRequests(pw); 4276 pw.decreaseIndent(); 4277 pw.println(); 4278 4279 pw.println("Network Offers:"); 4280 pw.increaseIndent(); 4281 for (final NetworkOfferInfo offerInfo : mNetworkOffers) { 4282 pw.println(offerInfo.offer); 4283 } 4284 pw.decreaseIndent(); 4285 pw.println(); 4286 4287 mLegacyTypeTracker.dump(pw); 4288 4289 pw.println(); 4290 mKeepaliveTracker.dump(pw); 4291 4292 pw.println(); 4293 dumpAvoidBadWifiSettings(pw); 4294 4295 pw.println(); 4296 dumpDestroySockets(pw); 4297 4298 if (mDeps.isAtLeastT()) { 4299 // R: https://android.googlesource.com/platform/system/core/+/refs/heads/android11-release/rootdir/init.rc 4300 // shows /dev/cg2_bpf 4301 // S: https://android.googlesource.com/platform/system/core/+/refs/heads/android12-release/rootdir/init.rc 4302 // does not 4303 // Thus cgroups are mounted at /dev/cg2_bpf on R and not on /sys/fs/cgroup 4304 // so the following won't work (on R) anyway. 4305 // The /sys/fs/cgroup path is only actually enforced/required starting with U, 4306 // but it is very likely to already be the case (though not guaranteed) on T. 4307 // I'm not at all sure about S - let's just skip it to get rid of lint warnings. 4308 pw.println(); 4309 dumpBpfProgramStatus(pw); 4310 } 4311 4312 if (null != mCarrierPrivilegeAuthenticator) { 4313 pw.println(); 4314 mCarrierPrivilegeAuthenticator.dump(pw); 4315 } 4316 4317 pw.println(); 4318 4319 if (!CollectionUtils.contains(args, SHORT_ARG)) { 4320 pw.println(); 4321 pw.println("mNetworkRequestInfoLogs (most recent first):"); 4322 pw.increaseIndent(); 4323 mNetworkRequestInfoLogs.reverseDump(pw); 4324 pw.decreaseIndent(); 4325 4326 pw.println(); 4327 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 4328 pw.increaseIndent(); 4329 mNetworkInfoBlockingLogs.reverseDump(pw); 4330 pw.decreaseIndent(); 4331 4332 pw.println(); 4333 pw.println("NetTransition WakeLock activity (most recent first):"); 4334 pw.increaseIndent(); 4335 pw.println("total acquisitions: " + mTotalWakelockAcquisitions); 4336 pw.println("total releases: " + mTotalWakelockReleases); 4337 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s"); 4338 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s"); 4339 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) { 4340 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 4341 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); 4342 } 4343 mWakelockLogs.reverseDump(pw); 4344 4345 pw.println(); 4346 pw.println("bandwidth update requests (by uid):"); 4347 pw.increaseIndent(); 4348 synchronized (mBandwidthRequests) { 4349 for (int i = 0; i < mBandwidthRequests.size(); i++) { 4350 pw.println("[" + mBandwidthRequests.keyAt(i) 4351 + "]: " + mBandwidthRequests.valueAt(i)); 4352 } 4353 } 4354 pw.decreaseIndent(); 4355 pw.decreaseIndent(); 4356 4357 pw.println(); 4358 pw.println("mOemNetworkPreferencesLogs (most recent first):"); 4359 pw.increaseIndent(); 4360 mOemNetworkPreferencesLogs.reverseDump(pw); 4361 pw.decreaseIndent(); 4362 } 4363 4364 pw.println(); 4365 4366 pw.println(); 4367 pw.println("Permission Monitor:"); 4368 pw.increaseIndent(); 4369 mPermissionMonitor.dump(pw); 4370 pw.decreaseIndent(); 4371 4372 pw.println(); 4373 pw.println("Legacy network activity:"); 4374 pw.increaseIndent(); 4375 mNetworkActivityTracker.dump(pw); 4376 pw.decreaseIndent(); 4377 4378 pw.println(); 4379 pw.println("Multicast routing supported: " + 4380 (mMulticastRoutingCoordinatorService != null)); 4381 4382 pw.println(); 4383 pw.println("Background firewall chain enabled: " + mBackgroundFirewallChainEnabled); 4384 } 4385 4386 private void dumpNetworks(IndentingPrintWriter pw) { 4387 for (NetworkAgentInfo nai : networksSortedById()) { 4388 pw.println(nai.toString()); 4389 pw.increaseIndent(); 4390 pw.println("Nat464Xlat:"); 4391 pw.increaseIndent(); 4392 nai.dumpNat464Xlat(pw); 4393 pw.decreaseIndent(); 4394 pw.println(String.format( 4395 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d", 4396 nai.numForegroundNetworkRequests(), 4397 nai.numNetworkRequests() - nai.numRequestNetworkRequests(), 4398 nai.numBackgroundNetworkRequests(), 4399 nai.numNetworkRequests())); 4400 pw.increaseIndent(); 4401 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4402 pw.println(nai.requestAt(i).toString()); 4403 } 4404 pw.decreaseIndent(); 4405 pw.println("Inactivity Timers:"); 4406 pw.increaseIndent(); 4407 nai.dumpInactivityTimers(pw); 4408 pw.decreaseIndent(); 4409 pw.decreaseIndent(); 4410 } 4411 } 4412 4413 private void dumpNetworkPreferences(IndentingPrintWriter pw) { 4414 if (!mProfileNetworkPreferences.isEmpty()) { 4415 pw.println("Profile preferences:"); 4416 pw.increaseIndent(); 4417 pw.println(mProfileNetworkPreferences); 4418 pw.decreaseIndent(); 4419 } 4420 if (!mOemNetworkPreferences.isEmpty()) { 4421 pw.println("OEM preferences:"); 4422 pw.increaseIndent(); 4423 pw.println(mOemNetworkPreferences); 4424 pw.decreaseIndent(); 4425 } 4426 if (!mMobileDataPreferredUids.isEmpty()) { 4427 pw.println("Mobile data preferred UIDs:"); 4428 pw.increaseIndent(); 4429 pw.println(mMobileDataPreferredUids); 4430 pw.decreaseIndent(); 4431 } 4432 4433 pw.println("Default requests:"); 4434 pw.increaseIndent(); 4435 dumpPerAppDefaultRequests(pw); 4436 pw.decreaseIndent(); 4437 } 4438 4439 private void dumpPerAppDefaultRequests(IndentingPrintWriter pw) { 4440 for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) { 4441 if (mDefaultRequest == defaultRequest) { 4442 continue; 4443 } 4444 4445 final NetworkAgentInfo satisfier = defaultRequest.getSatisfier(); 4446 final String networkOutput; 4447 if (null == satisfier) { 4448 networkOutput = "null"; 4449 } else if (mNoServiceNetwork.equals(satisfier)) { 4450 networkOutput = "no service network"; 4451 } else { 4452 networkOutput = String.valueOf(satisfier.network.netId); 4453 } 4454 final String asUidString = (defaultRequest.mAsUid == defaultRequest.mUid) 4455 ? "" : " asUid: " + defaultRequest.mAsUid; 4456 final String requestInfo = "Request: [uid/pid:" + defaultRequest.mUid + "/" 4457 + defaultRequest.mPid + asUidString + "]"; 4458 final String satisfierOutput = "Satisfier: [" + networkOutput + "]" 4459 + " Preference order: " + defaultRequest.mPreferenceOrder 4460 + " Tracked UIDs: " + defaultRequest.getUids(); 4461 pw.println(requestInfo + " - " + satisfierOutput); 4462 } 4463 } 4464 4465 private void dumpNetworkRequests(IndentingPrintWriter pw) { 4466 NetworkRequestInfo[] infos = null; 4467 while (infos == null) { 4468 try { 4469 infos = requestsSortedById(); 4470 } catch (ConcurrentModificationException e) { 4471 // mNetworkRequests should only be accessed from handler thread, except dump(). 4472 // As dump() is never called in normal usage, it would be needlessly expensive 4473 // to lock the collection only for its benefit. Instead, retry getting the 4474 // requests if ConcurrentModificationException is thrown during dump(). 4475 } 4476 } 4477 for (NetworkRequestInfo nri : infos) { 4478 pw.println(nri.toString()); 4479 } 4480 } 4481 4482 private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd, 4483 boolean verbose) { 4484 try { 4485 mBpfNetMaps.dump(pw, fd, verbose); 4486 } catch (ServiceSpecificException e) { 4487 pw.println(e.getMessage()); 4488 } catch (IOException e) { 4489 loge("Dump BPF maps failed, " + e); 4490 } 4491 } 4492 4493 private void dumpClatBpfRawMap(IndentingPrintWriter pw, boolean isEgress4Map) { 4494 for (NetworkAgentInfo nai : networksSortedById()) { 4495 if (nai.clatd != null) { 4496 nai.clatd.dumpRawBpfMap(pw, isEgress4Map); 4497 break; 4498 } 4499 } 4500 } 4501 4502 private void dumpAllRequestInfoLogsToLogcat() { 4503 try (PrintWriter logPw = new PrintWriter(new Writer() { 4504 @Override 4505 public void write(final char[] cbuf, final int off, final int len) { 4506 // This method is called with 0-length and 1-length arrays for empty strings 4507 // or strings containing only the DEL character. 4508 if (len <= 1) return; 4509 Log.e(TAG, new String(cbuf, off, len)); 4510 } 4511 @Override public void flush() {} 4512 @Override public void close() {} 4513 })) { 4514 mNetworkRequestInfoLogs.dump(logPw); 4515 } 4516 } 4517 4518 /** 4519 * Return an array of all current NetworkAgentInfos sorted by network id. 4520 */ 4521 private NetworkAgentInfo[] networksSortedById() { 4522 NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; 4523 networks = mNetworkAgentInfos.toArray(networks); 4524 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId())); 4525 return networks; 4526 } 4527 4528 /** 4529 * Return an array of all current NetworkRequest sorted by request id. 4530 */ 4531 @VisibleForTesting 4532 NetworkRequestInfo[] requestsSortedById() { 4533 NetworkRequestInfo[] requests = new NetworkRequestInfo[0]; 4534 requests = getNrisFromGlobalRequests().toArray(requests); 4535 // Sort the array based off the NRI containing the min requestId in its requests. 4536 Arrays.sort(requests, 4537 Comparator.comparingInt(nri -> Collections.min(nri.mRequests, 4538 Comparator.comparingInt(req -> req.requestId)).requestId 4539 ) 4540 ); 4541 return requests; 4542 } 4543 4544 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 4545 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 4546 if (officialNai != null && officialNai.equals(nai)) return true; 4547 if (officialNai != null || VDBG) { 4548 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 4549 " - " + nai); 4550 } 4551 return false; 4552 } 4553 4554 private boolean isDisconnectRequest(Message msg) { 4555 if (msg.what != NetworkAgent.EVENT_NETWORK_INFO_CHANGED) return false; 4556 final NetworkInfo info = (NetworkInfo) ((Pair) msg.obj).second; 4557 return info.getState() == NetworkInfo.State.DISCONNECTED; 4558 } 4559 4560 // must be stateless - things change under us. 4561 private class NetworkStateTrackerHandler extends Handler { 4562 public NetworkStateTrackerHandler(Looper looper) { 4563 super(looper); 4564 } 4565 4566 private void maybeHandleNetworkAgentMessage(Message msg) { 4567 final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj; 4568 final NetworkAgentInfo nai = arg.first; 4569 if (!mNetworkAgentInfos.contains(nai)) { 4570 if (VDBG) { 4571 log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); 4572 } 4573 return; 4574 } 4575 4576 // If the network has been destroyed, the only thing that it can do is disconnect. 4577 if (nai.isDestroyed() && !isDisconnectRequest(msg)) { 4578 return; 4579 } 4580 4581 switch (msg.what) { 4582 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 4583 final NetworkCapabilities proposed = (NetworkCapabilities) arg.second; 4584 if (!nai.respectsNcStructuralConstraints(proposed)) { 4585 Log.wtf(TAG, "Agent " + nai + " violates nc structural constraints : " 4586 + nai.networkCapabilities + " -> " + proposed); 4587 disconnectAndDestroyNetwork(nai); 4588 return; 4589 } 4590 nai.setDeclaredCapabilities(proposed); 4591 final NetworkCapabilities sanitized = 4592 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator); 4593 maybeUpdateWifiRoamTimestamp(nai, sanitized); 4594 updateCapabilities(nai.getScore(), nai, sanitized); 4595 break; 4596 } 4597 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 4598 LinkProperties newLp = (LinkProperties) arg.second; 4599 processLinkPropertiesFromAgent(nai, newLp); 4600 handleUpdateLinkProperties(nai, newLp); 4601 break; 4602 } 4603 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 4604 NetworkInfo info = (NetworkInfo) arg.second; 4605 updateNetworkInfo(nai, info); 4606 break; 4607 } 4608 case NetworkAgent.EVENT_LOCAL_NETWORK_CONFIG_CHANGED: { 4609 final LocalNetworkConfig config = (LocalNetworkConfig) arg.second; 4610 handleUpdateLocalNetworkConfig(nai, nai.localNetworkConfig, config); 4611 break; 4612 } 4613 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 4614 updateNetworkScore(nai, (NetworkScore) arg.second); 4615 break; 4616 } 4617 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 4618 if (nai.everConnected()) { 4619 loge("ERROR: cannot call explicitlySelected on already-connected network"); 4620 // Note that if the NAI had been connected, this would affect the 4621 // score, and therefore would require re-mixing the score and performing 4622 // a rematch. 4623 } 4624 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1); 4625 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2); 4626 // Mark the network as temporarily accepting partial connectivity so that it 4627 // will be validated (and possibly become default) even if it only provides 4628 // partial internet access. Note that if user connects to partial connectivity 4629 // and choose "don't ask again", then wifi disconnected by some reasons(maybe 4630 // out of wifi coverage) and if the same wifi is available again, the device 4631 // will auto connect to this wifi even though the wifi has "no internet". 4632 // TODO: Evaluate using a separate setting in IpMemoryStore. 4633 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2); 4634 break; 4635 } 4636 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { 4637 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2); 4638 break; 4639 } 4640 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { 4641 // TODO: prevent loops, e.g., if a network declares itself as underlying. 4642 final List<Network> underlying = (List<Network>) arg.second; 4643 4644 if (isLegacyLockdownNai(nai) 4645 && (underlying == null || underlying.size() != 1)) { 4646 Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString() 4647 + " must have exactly one underlying network: " + underlying); 4648 } 4649 4650 final Network[] oldUnderlying = nai.declaredUnderlyingNetworks; 4651 nai.declaredUnderlyingNetworks = (underlying != null) 4652 ? underlying.toArray(new Network[0]) : null; 4653 4654 if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) { 4655 if (DBG) { 4656 log(nai.toShortString() + " changed underlying networks to " 4657 + Arrays.toString(nai.declaredUnderlyingNetworks)); 4658 } 4659 updateCapabilitiesForNetwork(nai); 4660 notifyIfacesChangedForNetworkStats(); 4661 } 4662 break; 4663 } 4664 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: { 4665 if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 4666 nai.teardownDelayMs = msg.arg1; 4667 } else { 4668 logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1); 4669 } 4670 break; 4671 } 4672 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: { 4673 nai.setLingerDuration((int) arg.second); 4674 break; 4675 } 4676 case NetworkAgent.EVENT_ADD_DSCP_POLICY: { 4677 DscpPolicy policy = (DscpPolicy) arg.second; 4678 if (mDscpPolicyTracker != null) { 4679 mDscpPolicyTracker.addDscpPolicy(nai, policy); 4680 } 4681 break; 4682 } 4683 case NetworkAgent.EVENT_REMOVE_DSCP_POLICY: { 4684 if (mDscpPolicyTracker != null) { 4685 mDscpPolicyTracker.removeDscpPolicy(nai, (int) arg.second); 4686 } 4687 break; 4688 } 4689 case NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES: { 4690 if (mDscpPolicyTracker != null) { 4691 mDscpPolicyTracker.removeAllDscpPolicies(nai, true); 4692 } 4693 break; 4694 } 4695 case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: { 4696 if (!nai.everConnected()) { 4697 Log.d(TAG, "unregisterAfterReplacement on never-connected " 4698 + nai.toShortString() + ", tearing down instead"); 4699 teardownUnneededNetwork(nai); 4700 break; 4701 } 4702 4703 if (nai.isDestroyed()) { 4704 Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString() 4705 + ", ignoring"); 4706 break; 4707 } 4708 4709 final int timeoutMs = (int) arg.second; 4710 if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 4711 Log.e(TAG, "Invalid network replacement timer " + timeoutMs 4712 + ", must be between 0 and " + NetworkAgent.MAX_TEARDOWN_DELAY_MS); 4713 } 4714 4715 // Marking a network awaiting replacement is used to ensure that any requests 4716 // satisfied by the network do not switch to another network until a 4717 // replacement is available or the wait for a replacement times out. 4718 // If the network is inactive (i.e., nascent or lingering), then there are no 4719 // such requests, and there is no point keeping it. Just tear it down. 4720 // Note that setLingerDuration(0) cannot be used to do this because the network 4721 // could be nascent. 4722 nai.clearInactivityState(); 4723 if (unneeded(nai, UnneededFor.TEARDOWN)) { 4724 Log.d(TAG, nai.toShortString() 4725 + " marked awaiting replacement is unneeded, tearing down instead"); 4726 teardownUnneededNetwork(nai); 4727 break; 4728 } 4729 4730 Log.d(TAG, "Marking " + nai.toShortString() 4731 + " destroyed, awaiting replacement within " + timeoutMs + "ms"); 4732 destroyNativeNetwork(nai); 4733 4734 // TODO: deduplicate this call with the one in disconnectAndDestroyNetwork. 4735 // This is not trivial because KeepaliveTracker#handleStartKeepalive does not 4736 // consider the fact that the network could already have disconnected or been 4737 // destroyed. Fix the code to send ERROR_INVALID_NETWORK when this happens 4738 // (taking care to ensure no dup'd FD leaks), then remove the code duplication 4739 // and move this code to a sensible location (destroyNativeNetwork perhaps?). 4740 mKeepaliveTracker.handleStopAllKeepalives(nai, 4741 SocketKeepalive.ERROR_INVALID_NETWORK); 4742 4743 nai.updateScoreForNetworkAgentUpdate(); 4744 // This rematch is almost certainly not going to result in any changes, because 4745 // the destroyed flag is only just above the "current satisfier wins" 4746 // tie-breaker. But technically anything that affects scoring should rematch. 4747 rematchAllNetworksAndRequests(); 4748 mHandler.postDelayed(() -> nai.disconnect(), timeoutMs); 4749 break; 4750 } 4751 } 4752 } 4753 4754 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 4755 final int netId = msg.arg2; 4756 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 4757 // If a network has already been destroyed, all NetworkMonitor updates are ignored. 4758 if (nai != null && nai.isDestroyed()) return true; 4759 switch (msg.what) { 4760 default: 4761 return false; 4762 case EVENT_PROBE_STATUS_CHANGED: { 4763 if (nai == null) { 4764 break; 4765 } 4766 final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first; 4767 final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second; 4768 final boolean probePrivateDnsCompleted = 4769 ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0); 4770 final boolean privateDnsBroken = 4771 ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0); 4772 if (probePrivateDnsCompleted) { 4773 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) { 4774 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken); 4775 updateCapabilitiesForNetwork(nai); 4776 } 4777 // Only show the notification when the private DNS is broken and the 4778 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid. 4779 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) { 4780 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN); 4781 } 4782 nai.networkAgentConfig.hasShownBroken = privateDnsBroken; 4783 } else if (nai.networkCapabilities.isPrivateDnsBroken()) { 4784 // If probePrivateDnsCompleted is false but nai.networkCapabilities says 4785 // private DNS is broken, it means this network is being reevaluated. 4786 // Either probing private DNS is not necessary any more or it hasn't been 4787 // done yet. In either case, the networkCapabilities should be updated to 4788 // reflect the new status. 4789 nai.networkCapabilities.setPrivateDnsBroken(false); 4790 updateCapabilitiesForNetwork(nai); 4791 nai.networkAgentConfig.hasShownBroken = false; 4792 } 4793 break; 4794 } 4795 case EVENT_NETWORK_TESTED: { 4796 final NetworkTestedResults results = (NetworkTestedResults) msg.obj; 4797 4798 if (nai == null) break; 4799 4800 handleNetworkTested(nai, results.mTestResult, 4801 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl); 4802 break; 4803 } 4804 case EVENT_PROVISIONING_NOTIFICATION: { 4805 final boolean visible = toBool(msg.arg1); 4806 // If captive portal status has changed, update capabilities or disconnect. 4807 if (!visible) { 4808 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other 4809 // notifications belong to the same network may be cleared unexpectedly. 4810 mNotifier.clearNotification(netId, NotificationType.SIGN_IN); 4811 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH); 4812 } else { 4813 if (nai == null) { 4814 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 4815 break; 4816 } 4817 if (!nai.networkAgentConfig.provisioningNotificationDisabled) { 4818 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 4819 (PendingIntent) msg.obj, 4820 nai.networkAgentConfig.explicitlySelected); 4821 } 4822 } 4823 break; 4824 } 4825 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { 4826 if (nai == null) break; 4827 4828 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); 4829 break; 4830 } 4831 case EVENT_CAPPORT_DATA_CHANGED: { 4832 if (nai == null) break; 4833 handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj); 4834 break; 4835 } 4836 } 4837 return true; 4838 } 4839 4840 private void handleNetworkTested( 4841 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) { 4842 final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0; 4843 final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0; 4844 final boolean portal = !TextUtils.isEmpty(redirectUrl); 4845 4846 // If there is any kind of working networking, then the NAI has been evaluated 4847 // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is 4848 // the first time this ever happened. 4849 final boolean someConnectivity = (valid || partial || portal); 4850 final boolean becameEvaluated = someConnectivity && nai.setEvaluated(); 4851 // Because of b/245893397, if the score is updated when updateCapabilities is called, 4852 // any callback that receives onAvailable for that rematch receives an extra caps 4853 // callback. To prevent that, update the score in the agent so the updates below won't 4854 // see an update to both caps and score at the same time. 4855 // TODO : fix b/245893397 and remove this. 4856 if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate(); 4857 4858 if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) { 4859 // Assume the validation failure is due to a temporary failure after roaming 4860 // and ignore it. NetworkMonitor will continue to retry validation. If it 4861 // continues to fail after the block timeout expires, the network will be 4862 // marked unvalidated. If it succeeds, then validation state will not change. 4863 return; 4864 } 4865 4866 final boolean wasValidated = nai.isValidated(); 4867 final boolean wasPartial = nai.partialConnectivity(); 4868 final boolean wasPortal = nai.captivePortalDetected(); 4869 nai.setPartialConnectivity(partial); 4870 nai.setCaptivePortalDetected(portal); 4871 nai.updateScoreForNetworkAgentUpdate(); 4872 final boolean partialConnectivityChanged = (wasPartial != partial); 4873 final boolean portalChanged = (wasPortal != portal); 4874 4875 if (DBG) { 4876 final String logMsg = !TextUtils.isEmpty(redirectUrl) 4877 ? " with redirect to " + redirectUrl 4878 : ""; 4879 final String statusMsg; 4880 if (valid) { 4881 statusMsg = "passed"; 4882 } else if (!TextUtils.isEmpty(redirectUrl)) { 4883 statusMsg = "detected a portal"; 4884 } else { 4885 statusMsg = "failed"; 4886 } 4887 log(nai.toShortString() + " validation " + statusMsg + logMsg); 4888 } 4889 if (valid != wasValidated) { 4890 final FullScore oldScore = nai.getScore(); 4891 nai.setValidated(valid); 4892 updateCapabilities(oldScore, nai, nai.networkCapabilities); 4893 if (valid) { 4894 handleFreshlyValidatedNetwork(nai); 4895 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and 4896 // LOST_INTERNET notifications if network becomes valid. 4897 mNotifier.clearNotification(nai.network.getNetId(), 4898 NotificationType.NO_INTERNET); 4899 mNotifier.clearNotification(nai.network.getNetId(), 4900 NotificationType.LOST_INTERNET); 4901 mNotifier.clearNotification(nai.network.getNetId(), 4902 NotificationType.PARTIAL_CONNECTIVITY); 4903 mNotifier.clearNotification(nai.network.getNetId(), 4904 NotificationType.PRIVATE_DNS_BROKEN); 4905 // If network becomes valid, the hasShownBroken should be reset for 4906 // that network so that the notification will be fired when the private 4907 // DNS is broken again. 4908 nai.networkAgentConfig.hasShownBroken = false; 4909 } 4910 } else if (partialConnectivityChanged) { 4911 updateCapabilitiesForNetwork(nai); 4912 } else if (portalChanged) { 4913 if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID 4914 == getCaptivePortalMode(nai)) { 4915 if (DBG) log("Avoiding captive portal network: " + nai.toShortString()); 4916 nai.onPreventAutomaticReconnect(); 4917 teardownUnneededNetwork(nai); 4918 return; 4919 } else { 4920 updateCapabilitiesForNetwork(nai); 4921 } 4922 } else if (becameEvaluated) { 4923 // If valid or partial connectivity changed, updateCapabilities* has 4924 // done the rematch. 4925 rematchAllNetworksAndRequests(); 4926 } 4927 updateInetCondition(nai); 4928 4929 // Let the NetworkAgent know the state of its network 4930 // TODO: Evaluate to update partial connectivity to status to NetworkAgent. 4931 nai.onValidationStatusChanged( 4932 valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK, 4933 redirectUrl); 4934 4935 // If NetworkMonitor detects partial connectivity before 4936 // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification 4937 // immediately. Re-notify partial connectivity silently if no internet 4938 // notification already there. 4939 if (!wasPartial && nai.partialConnectivity()) { 4940 // Remove delayed message if there is a pending message. 4941 mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network); 4942 handleInitialEvaluationTimeout(nai.network); 4943 } 4944 4945 if (wasValidated && !nai.isValidated()) { 4946 handleNetworkUnvalidated(nai); 4947 } 4948 } 4949 4950 private int getCaptivePortalMode(@NonNull NetworkAgentInfo nai) { 4951 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) && 4952 mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)) { 4953 // Do not avoid captive portal when network is wear proxy. 4954 return ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT; 4955 } 4956 4957 return Settings.Global.getInt(mContext.getContentResolver(), 4958 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, 4959 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 4960 } 4961 4962 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 4963 switch (msg.what) { 4964 default: 4965 return false; 4966 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 4967 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 4968 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 4969 handleLingerComplete(nai); 4970 } 4971 break; 4972 } 4973 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: { 4974 handleNetworkAgentRegistered(msg); 4975 break; 4976 } 4977 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: { 4978 handleNetworkAgentDisconnected(msg); 4979 break; 4980 } 4981 } 4982 return true; 4983 } 4984 4985 @Override 4986 public void handleMessage(@NonNull Message msg) { 4987 if (!maybeHandleNetworkMonitorMessage(msg) 4988 && !maybeHandleNetworkAgentInfoMessage(msg)) { 4989 maybeHandleNetworkAgentMessage(msg); 4990 } 4991 } 4992 } 4993 4994 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub { 4995 private final int mNetId; 4996 private final AutodestructReference<NetworkAgentInfo> mNai; 4997 4998 private NetworkMonitorCallbacks(NetworkAgentInfo nai) { 4999 mNetId = nai.network.getNetId(); 5000 mNai = new AutodestructReference<>(nai); 5001 } 5002 5003 @Override 5004 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 5005 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, 5006 new Pair<>(mNai.getAndDestroy(), networkMonitor))); 5007 } 5008 5009 @Override 5010 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { 5011 // Legacy version of notifyNetworkTestedWithExtras. 5012 // Would only be called if the system has a NetworkStack module older than the 5013 // framework, which does not happen in practice. 5014 Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken"); 5015 } 5016 5017 @Override 5018 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) { 5019 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use 5020 // the same looper so messages will be processed in sequence. 5021 final Message msg = mTrackerHandler.obtainMessage( 5022 EVENT_NETWORK_TESTED, 5023 0, mNetId, 5024 new NetworkTestedResults( 5025 mNetId, p.result, p.timestampMillis, p.redirectUrl)); 5026 mTrackerHandler.sendMessage(msg); 5027 5028 // Invoke ConnectivityReport generation for this Network test event. 5029 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId); 5030 if (nai == null) return; 5031 5032 // NetworkMonitor reports the network validation result as a bitmask while 5033 // ConnectivityDiagnostics treats this value as an int. Convert the result to a single 5034 // logical value for ConnectivityDiagnostics. 5035 final int validationResult = networkMonitorValidationResultToConnDiagsValidationResult( 5036 p.result); 5037 5038 final PersistableBundle extras = new PersistableBundle(); 5039 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, validationResult); 5040 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded); 5041 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted); 5042 5043 ConnectivityReportEvent reportEvent = 5044 new ConnectivityReportEvent(p.timestampMillis, nai, extras); 5045 final Message m = mConnectivityDiagnosticsHandler.obtainMessage( 5046 ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent); 5047 mConnectivityDiagnosticsHandler.sendMessage(m); 5048 } 5049 5050 @Override 5051 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) { 5052 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5053 EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 5054 0, mNetId, PrivateDnsConfig.fromParcel(config))); 5055 } 5056 5057 @Override 5058 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) { 5059 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5060 EVENT_PROBE_STATUS_CHANGED, 5061 0, mNetId, new Pair<>(probesCompleted, probesSucceeded))); 5062 } 5063 5064 @Override 5065 public void notifyCaptivePortalDataChanged(CaptivePortalData data) { 5066 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5067 EVENT_CAPPORT_DATA_CHANGED, 5068 0, mNetId, data)); 5069 } 5070 5071 @Override 5072 public void showProvisioningNotification(String action, String packageName) { 5073 final Intent intent = new Intent(action); 5074 intent.setPackage(packageName); 5075 5076 final PendingIntent pendingIntent; 5077 // Only the system server can register notifications with package "android" 5078 final long token = Binder.clearCallingIdentity(); 5079 try { 5080 pendingIntent = PendingIntent.getBroadcast( 5081 mContext, 5082 0 /* requestCode */, 5083 intent, 5084 PendingIntent.FLAG_IMMUTABLE); 5085 } finally { 5086 Binder.restoreCallingIdentity(token); 5087 } 5088 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5089 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW, 5090 mNetId, pendingIntent)); 5091 } 5092 5093 @Override 5094 public void hideProvisioningNotification() { 5095 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5096 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); 5097 } 5098 5099 @Override 5100 public void notifyDataStallSuspected(DataStallReportParcelable p) { 5101 ConnectivityService.this.notifyDataStallSuspected(p, mNetId); 5102 } 5103 5104 @Override 5105 public int getInterfaceVersion() { 5106 return this.VERSION; 5107 } 5108 5109 @Override 5110 public String getInterfaceHash() { 5111 return this.HASH; 5112 } 5113 } 5114 5115 /** 5116 * Converts the given NetworkMonitor-specific validation result bitmask to a 5117 * ConnectivityDiagnostics-specific validation result int. 5118 */ 5119 private int networkMonitorValidationResultToConnDiagsValidationResult(int validationResult) { 5120 if ((validationResult & NETWORK_VALIDATION_RESULT_SKIPPED) != 0) { 5121 return ConnectivityReport.NETWORK_VALIDATION_RESULT_SKIPPED; 5122 } 5123 if ((validationResult & NETWORK_VALIDATION_RESULT_VALID) == 0) { 5124 return ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID; 5125 } 5126 return (validationResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0 5127 ? ConnectivityReport.NETWORK_VALIDATION_RESULT_PARTIALLY_VALID 5128 : ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID; 5129 } 5130 5131 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) { 5132 log("Data stall detected with methods: " + p.detectionMethod); 5133 5134 final PersistableBundle extras = new PersistableBundle(); 5135 int detectionMethod = 0; 5136 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 5137 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); 5138 detectionMethod |= DETECTION_METHOD_DNS_EVENTS; 5139 } 5140 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 5141 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); 5142 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, 5143 p.tcpMetricsCollectionPeriodMillis); 5144 detectionMethod |= DETECTION_METHOD_TCP_METRICS; 5145 } 5146 5147 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( 5148 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId, 5149 new Pair<>(p.timestampMillis, extras)); 5150 5151 // NetworkStateTrackerHandler currently doesn't take any actions based on data 5152 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid 5153 // the cost of going through two handlers. 5154 mConnectivityDiagnosticsHandler.sendMessage(msg); 5155 } 5156 5157 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) { 5158 return (p.detectionMethod & detectionMethod) != 0; 5159 } 5160 5161 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { 5162 return isPrivateDnsValidationRequired(nai.networkCapabilities); 5163 } 5164 5165 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { 5166 if (nai == null) return; 5167 // If the Private DNS mode is opportunistic, reprogram the DNS servers 5168 // in order to restart a validation pass from within netd. 5169 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 5170 if (cfg.inOpportunisticMode()) { 5171 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 5172 } 5173 } 5174 5175 private void handlePrivateDnsSettingsChanged() { 5176 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 5177 5178 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 5179 handlePerNetworkPrivateDnsConfig(nai, cfg); 5180 if (networkRequiresPrivateDnsValidation(nai)) { 5181 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5182 } 5183 } 5184 } 5185 5186 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 5187 // Private DNS only ever applies to networks that might provide 5188 // Internet access and therefore also require validation. 5189 if (!networkRequiresPrivateDnsValidation(nai)) return; 5190 5191 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or 5192 // schedule DNS resolutions. If a DNS resolution is required the 5193 // result will be sent back to us. 5194 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel()); 5195 5196 // With Private DNS bypass support, we can proceed to update the 5197 // Private DNS config immediately, even if we're in strict mode 5198 // and have not yet resolved the provider name into a set of IPs. 5199 updatePrivateDns(nai, cfg); 5200 } 5201 5202 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 5203 mDnsManager.updatePrivateDns(nai.network, newCfg); 5204 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 5205 } 5206 5207 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 5208 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 5209 if (nai == null) { 5210 return; 5211 } 5212 mDnsManager.updatePrivateDnsValidation(update); 5213 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5214 } 5215 5216 private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, 5217 int prefixLength) { 5218 NetworkAgentInfo nai = mNetworkForNetId.get(netId); 5219 if (nai == null) return; 5220 5221 log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", 5222 netId, operation, prefixAddress, prefixLength)); 5223 5224 IpPrefix prefix = null; 5225 if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { 5226 try { 5227 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), 5228 prefixLength); 5229 } catch (IllegalArgumentException e) { 5230 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); 5231 return; 5232 } 5233 } 5234 5235 nai.clatd.setNat64PrefixFromDns(prefix); 5236 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5237 } 5238 5239 private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai, 5240 @Nullable final CaptivePortalData data) { 5241 nai.capportApiData = data; 5242 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo 5243 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5244 } 5245 5246 /** 5247 * Updates the inactivity state from the network requests inside the NAI. 5248 * @param nai the agent info to update 5249 * @param now the timestamp of the event causing this update 5250 * @return whether the network was inactive as a result of this update 5251 */ 5252 private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) { 5253 // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm. 5254 // 2. If the network was inactive and there are now requests, unset inactive. 5255 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 5256 // one lingered request, set inactive. 5257 nai.updateInactivityTimer(); 5258 if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) { 5259 if (DBG) log("Unsetting inactive " + nai.toShortString()); 5260 nai.unsetInactive(); 5261 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 5262 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) { 5263 if (DBG) { 5264 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 5265 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms"); 5266 } 5267 nai.setInactive(); 5268 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 5269 return true; 5270 } 5271 return false; 5272 } 5273 5274 private void handleNetworkAgentRegistered(Message msg) { 5275 final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 5276 if (!mNetworkAgentInfos.contains(nai)) { 5277 return; 5278 } 5279 5280 if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) { 5281 if (VDBG) log("NetworkAgent registered"); 5282 } else { 5283 loge("Error connecting NetworkAgent"); 5284 mNetworkAgentInfos.remove(nai); 5285 if (nai != null) { 5286 final boolean wasDefault = isDefaultNetwork(nai); 5287 synchronized (mNetworkForNetId) { 5288 mNetworkForNetId.remove(nai.network.getNetId()); 5289 } 5290 mNetIdManager.releaseNetId(nai.network.getNetId()); 5291 // Just in case. 5292 mLegacyTypeTracker.remove(nai, wasDefault); 5293 } 5294 } 5295 } 5296 5297 @VisibleForTesting 5298 protected static boolean shouldCreateNetworksImmediately() { 5299 // The feature of creating the networks immediately was slated for U, but race conditions 5300 // detected late required this was flagged off. 5301 // TODO : enable this in a Mainline update or in V, and re-enable the test for this 5302 // in NetworkAgentTest. 5303 return false; 5304 } 5305 5306 private static boolean shouldCreateNativeNetwork(@NonNull NetworkAgentInfo nai, 5307 @NonNull NetworkInfo.State state) { 5308 if (nai.isCreated()) return false; 5309 if (state == NetworkInfo.State.CONNECTED) return true; 5310 if (state != NetworkInfo.State.CONNECTING) { 5311 // TODO: throw if no WTFs are observed in the field. 5312 if (shouldCreateNetworksImmediately()) { 5313 Log.wtf(TAG, "Uncreated network in invalid state: " + state); 5314 } 5315 return false; 5316 } 5317 return nai.isVPN() || shouldCreateNetworksImmediately(); 5318 } 5319 5320 private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 5321 return nai.isCreated() && !nai.isDestroyed(); 5322 } 5323 5324 @VisibleForTesting 5325 boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) { 5326 // T+ devices should use unregisterAfterReplacement. 5327 if (mDeps.isAtLeastT()) return false; 5328 5329 // If the network never roamed, return false. The check below is not sufficient if time 5330 // since boot is less than blockTimeOut, though that's extremely unlikely to happen. 5331 if (nai.lastRoamTime == 0) return false; 5332 5333 final long blockTimeOut = Long.valueOf(mResources.get().getInteger( 5334 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis)); 5335 if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS 5336 && blockTimeOut >= 0) { 5337 final long currentTimeMs = SystemClock.elapsedRealtime(); 5338 long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime; 5339 if (timeSinceLastRoam <= blockTimeOut) { 5340 log ("blocked because only " + timeSinceLastRoam + "ms after roam"); 5341 return true; 5342 } 5343 } 5344 return false; 5345 } 5346 5347 private void handleNetworkAgentDisconnected(Message msg) { 5348 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 5349 disconnectAndDestroyNetwork(nai); 5350 } 5351 5352 // Destroys a network, remove references to it from the internal state managed by 5353 // ConnectivityService, free its interfaces and clean up. 5354 // Must be called on the Handler thread. 5355 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 5356 ensureRunningOnConnectivityServiceThread(); 5357 5358 if (!mNetworkAgentInfos.contains(nai)) return; 5359 5360 if (DBG) { 5361 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests()); 5362 } 5363 // Clear all notifications of this network. 5364 mNotifier.clearNotification(nai.network.getNetId()); 5365 // A network agent has disconnected. 5366 // TODO - if we move the logic to the network agent (have them disconnect 5367 // because they lost all their requests or because their score isn't good) 5368 // then they would disconnect organically, report their new state and then 5369 // disconnect the channel. 5370 if (nai.networkInfo.isConnected() || nai.networkInfo.isSuspended()) { 5371 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 5372 null, null); 5373 } 5374 final boolean wasDefault = isDefaultNetwork(nai); 5375 if (wasDefault) { 5376 mDefaultInetConditionPublished = 0; 5377 } 5378 if (mTrackMultiNetworkActivities) { 5379 // If trackMultiNetworkActivities is disabled, ActivityTracker removes idleTimer when 5380 // the network becomes no longer the default network. 5381 mNetworkActivityTracker.removeDataActivityTracking(nai); 5382 } 5383 notifyIfacesChangedForNetworkStats(); 5384 // If this was a local network forwarded to some upstream, or if some local network was 5385 // forwarded to this nai, then disable forwarding rules now. 5386 maybeDisableForwardRulesForDisconnectingNai(nai, true /* sendCallbacks */); 5387 // If this is a local network with an upstream selector, remove the associated network 5388 // request. 5389 if (nai.isLocalNetwork()) { 5390 final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector(); 5391 if (null != selector) { 5392 handleRemoveNetworkRequest(mNetworkRequests.get(selector)); 5393 } 5394 } 5395 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 5396 // by other networks that are already connected. Perhaps that can be done by 5397 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 5398 // of rematchAllNetworksAndRequests 5399 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 5400 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK); 5401 5402 mQosCallbackTracker.handleNetworkReleased(nai.network); 5403 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 5404 // Disable wakeup packet monitoring for each interface. 5405 wakeupModifyInterface(iface, nai, false); 5406 } 5407 nai.networkMonitor().notifyNetworkDisconnected(); 5408 mNetworkAgentInfos.remove(nai); 5409 nai.clatd.update(); 5410 synchronized (mNetworkForNetId) { 5411 // Remove the NetworkAgent, but don't mark the netId as 5412 // available until we've told netd to delete it below. 5413 mNetworkForNetId.remove(nai.network.getNetId()); 5414 } 5415 propagateUnderlyingNetworkCapabilities(nai.network); 5416 // Update allowed network lists in netd. This should be called after removing nai 5417 // from mNetworkAgentInfos. 5418 updateProfileAllowedNetworks(); 5419 // Remove all previously satisfied requests. 5420 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5421 final NetworkRequest request = nai.requestAt(i); 5422 final NetworkRequestInfo nri = mNetworkRequests.get(request); 5423 final NetworkAgentInfo currentNetwork = nri.getSatisfier(); 5424 if (currentNetwork != null 5425 && currentNetwork.network.getNetId() == nai.network.getNetId()) { 5426 // uid rules for this network will be removed in destroyNativeNetwork(nai). 5427 // TODO : setting the satisfier is in fact the job of the rematch. Teach the 5428 // rematch not to keep disconnected agents instead of setting it here ; this 5429 // will also allow removing updating the offers below. 5430 nri.setSatisfier(null, null); 5431 for (final NetworkOfferInfo noi : mNetworkOffers) { 5432 informOffer(nri, noi.offer, mNetworkRanker); 5433 } 5434 5435 if (mDefaultRequest == nri) { 5436 mNetworkActivityTracker.updateDefaultNetwork(null /* newNetwork */, nai); 5437 maybeDestroyPendingSockets(null /* newNetwork */, nai); 5438 ensureNetworkTransitionWakelock(nai.toShortString()); 5439 } 5440 } 5441 } 5442 nai.clearInactivityState(); 5443 // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after. 5444 // Currently, deleting it breaks tests that check for the default network disconnecting. 5445 // Find out why, fix the rematch code, and delete this. 5446 mLegacyTypeTracker.remove(nai, wasDefault); 5447 rematchAllNetworksAndRequests(); 5448 mLingerMonitor.noteDisconnect(nai); 5449 5450 if (null == getDefaultNetwork() && nai.linkProperties.getHttpProxy() != null) { 5451 // The obvious place to do this would be in makeDefault(), however makeDefault() is 5452 // not called by the rematch in this case. This is because the code above unset 5453 // this network from the default request's satisfier, and that is what the rematch 5454 // is using as its source data to know what the old satisfier was. So as far as the 5455 // rematch above is concerned, the old default network was null. 5456 // Therefore if there is no new default, the default network was null and is still 5457 // null, thus there was no change so makeDefault() is not called. So if the old 5458 // network had a proxy and there is no new default, the proxy tracker should be told 5459 // that there is no longer a default proxy. 5460 // Strictly speaking this is not essential because having a proxy setting when 5461 // there is no network is harmless, but it's still counter-intuitive so reset to null. 5462 mProxyTracker.setDefaultProxy(null); 5463 } 5464 5465 // Immediate teardown. 5466 if (nai.teardownDelayMs == 0) { 5467 destroyNetwork(nai); 5468 return; 5469 } 5470 5471 // Delayed teardown. 5472 if (nai.isCreated()) { 5473 try { 5474 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM); 5475 } catch (RemoteException e) { 5476 Log.d(TAG, "Error marking network restricted during teardown: ", e); 5477 } 5478 } 5479 mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs); 5480 } 5481 5482 private void destroyNetwork(NetworkAgentInfo nai) { 5483 if (shouldDestroyNativeNetwork(nai)) { 5484 // Tell netd to clean up the configuration for this network 5485 // (routing rules, DNS, etc). 5486 // This may be slow as it requires a lot of netd shelling out to ip and 5487 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 5488 // after we've rematched networks with requests (which might change the default 5489 // network or service a new request from an app), so network traffic isn't interrupted 5490 // for an unnecessarily long time. 5491 destroyNativeNetwork(nai); 5492 } 5493 if (!nai.isCreated() && !mDeps.isAtLeastT()) { 5494 // Backwards compatibility: send onNetworkDestroyed even if network was never created. 5495 // This can never run if the code above runs because shouldDestroyNativeNetwork is 5496 // false if the network was never created. 5497 // TODO: delete when S is no longer supported. 5498 nai.onNetworkDestroyed(); 5499 } 5500 mNetIdManager.releaseNetId(nai.network.getNetId()); 5501 } 5502 5503 private void maybeDisableForwardRulesForDisconnectingNai( 5504 @NonNull final NetworkAgentInfo disconnecting, final boolean sendCallbacks) { 5505 // Step 1 : maybe this network was the upstream for one or more local networks. 5506 for (final NetworkAgentInfo local : mNetworkAgentInfos) { 5507 if (!local.isLocalNetwork()) continue; 5508 final NetworkRequest selector = local.localNetworkConfig.getUpstreamSelector(); 5509 if (null == selector) continue; 5510 final NetworkRequestInfo nri = mNetworkRequests.get(selector); 5511 // null == nri can happen while disconnecting a network, because destroyNetwork() is 5512 // called after removing all associated NRIs from mNetworkRequests. 5513 if (null == nri) continue; 5514 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5515 if (disconnecting != satisfier) continue; 5516 removeLocalNetworkUpstream(local, disconnecting); 5517 // Set the satisfier to null immediately so that the LOCAL_NETWORK_CHANGED callback 5518 // correctly contains null as an upstream. 5519 if (sendCallbacks) { 5520 nri.setSatisfier(null, null); 5521 notifyNetworkCallbacks(local, 5522 ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 5523 } 5524 } 5525 5526 // Step 2 : maybe this is a local network that had an upstream. 5527 if (!disconnecting.isLocalNetwork()) return; 5528 final NetworkRequest selector = disconnecting.localNetworkConfig.getUpstreamSelector(); 5529 if (null == selector) return; 5530 final NetworkRequestInfo nri = mNetworkRequests.get(selector); 5531 // As above null == nri can happen while disconnecting a network, because destroyNetwork() 5532 // is called after removing all associated NRIs from mNetworkRequests. 5533 if (null == nri) return; 5534 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5535 if (null == satisfier) return; 5536 removeLocalNetworkUpstream(disconnecting, satisfier); 5537 } 5538 5539 private void removeLocalNetworkUpstream(@NonNull final NetworkAgentInfo localAgent, 5540 @NonNull final NetworkAgentInfo upstream) { 5541 try { 5542 final String localNetworkInterfaceName = localAgent.linkProperties.getInterfaceName(); 5543 final String upstreamNetworkInterfaceName = upstream.linkProperties.getInterfaceName(); 5544 mRoutingCoordinatorService.removeInterfaceForward( 5545 localNetworkInterfaceName, 5546 upstreamNetworkInterfaceName); 5547 disableMulticastRouting(localNetworkInterfaceName, upstreamNetworkInterfaceName); 5548 } catch (RemoteException e) { 5549 loge("Couldn't remove interface forward for " 5550 + localAgent.linkProperties.getInterfaceName() + " to " 5551 + upstream.linkProperties.getInterfaceName() + " while disconnecting"); 5552 } 5553 } 5554 5555 private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) { 5556 try { 5557 // This should never fail. Specifying an already in use NetID will cause failure. 5558 final NativeNetworkConfig config; 5559 if (nai.isVPN()) { 5560 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) { 5561 Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString()); 5562 return false; 5563 } 5564 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL, 5565 INetd.PERMISSION_NONE, 5566 !nai.networkAgentConfig.allowBypass /* secure */, 5567 getVpnType(nai), nai.networkAgentConfig.excludeLocalRouteVpn); 5568 } else { 5569 config = new NativeNetworkConfig(nai.network.getNetId(), 5570 nai.isLocalNetwork() ? NativeNetworkType.PHYSICAL_LOCAL 5571 : NativeNetworkType.PHYSICAL, 5572 getNetworkPermission(nai.networkCapabilities), 5573 false /* secure */, 5574 VpnManager.TYPE_VPN_NONE, 5575 false /* excludeLocalRoutes */); 5576 } 5577 mNetd.networkCreate(config); 5578 mDnsResolver.createNetworkCache(nai.network.getNetId()); 5579 mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), 5580 nai.networkCapabilities); 5581 return true; 5582 } catch (RemoteException | ServiceSpecificException e) { 5583 loge("Error creating network " + nai.toShortString() + ": " + e.getMessage()); 5584 return false; 5585 } 5586 } 5587 5588 private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 5589 if (mDscpPolicyTracker != null) { 5590 mDscpPolicyTracker.removeAllDscpPolicies(nai, false); 5591 } 5592 // Remove any forwarding rules to and from the interface for this network, since 5593 // the interface is going to go away. Don't send the callbacks however ; if the network 5594 // was is being disconnected the callbacks have already been sent, and if it is being 5595 // destroyed pending replacement they will be sent when it is disconnected. 5596 maybeDisableForwardRulesForDisconnectingNai(nai, false /* sendCallbacks */); 5597 updateIngressToVpnAddressFiltering(null, nai.linkProperties, nai); 5598 try { 5599 mNetd.networkDestroy(nai.network.getNetId()); 5600 } catch (RemoteException | ServiceSpecificException e) { 5601 loge("Exception destroying network(networkDestroy): " + e); 5602 } 5603 try { 5604 mDnsResolver.destroyNetworkCache(nai.network.getNetId()); 5605 } catch (RemoteException | ServiceSpecificException e) { 5606 loge("Exception destroying network: " + e); 5607 } 5608 // TODO: defer calling this until the network is removed from mNetworkAgentInfos. 5609 // Otherwise, a private DNS configuration update for a destroyed network, or one that never 5610 // gets created, could add data to DnsManager data structures that will never get deleted. 5611 mDnsManager.removeNetwork(nai.network); 5612 5613 // clean up tc police filters on interface. 5614 if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) { 5615 mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName()); 5616 } 5617 5618 nai.setDestroyed(); 5619 nai.onNetworkDestroyed(); 5620 } 5621 5622 // If this method proves to be too slow then we can maintain a separate 5623 // pendingIntent => NetworkRequestInfo map. 5624 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. 5625 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 5626 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 5627 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 5628 if (existingPendingIntent != null && 5629 mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) { 5630 return entry.getValue(); 5631 } 5632 } 5633 return null; 5634 } 5635 5636 private void checkNrisConsistency(final NetworkRequestInfo nri) { 5637 if (mDeps.isAtLeastT()) { 5638 for (final NetworkRequestInfo n : mNetworkRequests.values()) { 5639 if (n.mBinder != null && n.mBinder == nri.mBinder) { 5640 // Temporary help to debug b/194394697 ; TODO : remove this function when the 5641 // bug is fixed. 5642 dumpAllRequestInfoLogsToLogcat(); 5643 throw new IllegalStateException("This NRI is already registered. New : " + nri 5644 + ", existing : " + n); 5645 } 5646 } 5647 } 5648 } 5649 5650 private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid, 5651 @NonNull final NetworkCapabilities caps) { 5652 if (mCarrierPrivilegeAuthenticator != null) { 5653 return mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities( 5654 callingUid, caps); 5655 } 5656 return false; 5657 } 5658 5659 private int getSubscriptionIdFromNetworkCaps(@NonNull final NetworkCapabilities caps) { 5660 if (mCarrierPrivilegeAuthenticator != null) { 5661 return mCarrierPrivilegeAuthenticator.getSubIdFromNetworkCapabilities(caps); 5662 } 5663 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 5664 } 5665 5666 private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) { 5667 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 5668 // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests. 5669 ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent"); 5670 final NetworkRequestInfo existingRequest = 5671 findExistingNetworkRequestInfo(nri.mPendingIntent); 5672 if (existingRequest != null) { // remove the existing request. 5673 if (DBG) { 5674 log("Replacing " + existingRequest.mRequests.get(0) + " with " 5675 + nri.mRequests.get(0) + " because their intents matched."); 5676 } 5677 handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(), 5678 /* callOnUnavailable */ false); 5679 } 5680 handleRegisterNetworkRequest(nri); 5681 } 5682 5683 private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5684 handleRegisterNetworkRequests(Collections.singleton(nri)); 5685 } 5686 5687 private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 5688 ensureRunningOnConnectivityServiceThread(); 5689 for (final NetworkRequestInfo nri : nris) { 5690 mNetworkRequestInfoLogs.log("REGISTER " + nri); 5691 checkNrisConsistency(nri); 5692 for (final NetworkRequest req : nri.mRequests) { 5693 mNetworkRequests.put(req, nri); 5694 // TODO: Consider update signal strength for other types. 5695 if (req.isListen()) { 5696 for (final NetworkAgentInfo network : mNetworkAgentInfos) { 5697 if (req.networkCapabilities.hasSignalStrength() 5698 && network.satisfiesImmutableCapabilitiesOf(req)) { 5699 updateSignalStrengthThresholds(network, "REGISTER", req); 5700 } 5701 } 5702 } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) { 5703 mNetworkRequestStateStatsMetrics.onNetworkRequestReceived(req); 5704 } 5705 } 5706 5707 // If this NRI has a satisfier already, it is replacing an older request that 5708 // has been removed. Track it. 5709 final NetworkRequest activeRequest = nri.getActiveRequest(); 5710 if (null != activeRequest) { 5711 // If there is an active request, then for sure there is a satisfier. 5712 nri.getSatisfier().addRequest(activeRequest); 5713 } 5714 5715 if (shouldTrackUidsForBlockedStatusCallbacks() 5716 && isAppRequest(nri) 5717 && !nri.mUidTrackedForBlockedStatus) { 5718 Log.wtf(TAG, "Registered nri is not tracked for sending blocked status: " + nri); 5719 } 5720 } 5721 5722 if (mFlags.noRematchAllRequestsOnRegister()) { 5723 rematchNetworksAndRequests(nris); 5724 } else { 5725 rematchAllNetworksAndRequests(); 5726 } 5727 5728 // Requests that have not been matched to a network will not have been sent to the 5729 // providers, because the old satisfier and the new satisfier are the same (null in this 5730 // case). Send these requests to the providers. 5731 for (final NetworkRequestInfo nri : nris) { 5732 for (final NetworkOfferInfo noi : mNetworkOffers) { 5733 informOffer(nri, noi.offer, mNetworkRanker); 5734 } 5735 } 5736 } 5737 5738 private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent, 5739 final int callingUid) { 5740 final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 5741 if (nri != null) { 5742 // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests. 5743 ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent"); 5744 handleReleaseNetworkRequest( 5745 nri.mRequests.get(0), 5746 callingUid, 5747 /* callOnUnavailable */ false); 5748 } 5749 } 5750 5751 // Determines whether the network is the best (or could become the best, if it validated), for 5752 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 5753 // on the value of reason: 5754 // 5755 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 5756 // then it should be torn down. 5757 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 5758 // then it should be lingered. 5759 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 5760 ensureRunningOnConnectivityServiceThread(); 5761 5762 if (!nai.everConnected() || nai.isVPN() || nai.isInactive() 5763 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) { 5764 return false; 5765 } 5766 5767 final int numRequests; 5768 switch (reason) { 5769 case TEARDOWN: 5770 numRequests = nai.numRequestNetworkRequests(); 5771 break; 5772 case LINGER: 5773 numRequests = nai.numForegroundNetworkRequests(); 5774 break; 5775 default: 5776 Log.wtf(TAG, "Invalid reason. Cannot happen."); 5777 return true; 5778 } 5779 5780 if (numRequests > 0) return false; 5781 5782 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5783 if (reason == UnneededFor.LINGER 5784 && !nri.isMultilayerRequest() 5785 && nri.mRequests.get(0).isBackgroundRequest()) { 5786 // Background requests don't affect lingering. 5787 continue; 5788 } 5789 5790 if (isNetworkPotentialSatisfier(nai, nri)) { 5791 return false; 5792 } 5793 } 5794 return true; 5795 } 5796 5797 private boolean isNetworkPotentialSatisfier( 5798 @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) { 5799 // While destroyed network sometimes satisfy requests (including occasionally newly 5800 // satisfying requests), *potential* satisfiers are networks that might beat a current 5801 // champion if they validate. As such, a destroyed network is never a potential satisfier, 5802 // because it's never a good idea to keep a destroyed network in case it validates. 5803 // For example, declaring it a potential satisfier would keep an unvalidated destroyed 5804 // candidate after it's been replaced by another unvalidated network. 5805 if (candidate.isDestroyed()) return false; 5806 // Listen requests won't keep up a network satisfying it. If this is not a multilayer 5807 // request, return immediately. For multilayer requests, check to see if any of the 5808 // multilayer requests may have a potential satisfier. 5809 if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen() 5810 || nri.mRequests.get(0).isListenForBest())) { 5811 return false; 5812 } 5813 for (final NetworkRequest req : nri.mRequests) { 5814 // This multilayer listen request is satisfied therefore no further requests need to be 5815 // evaluated deeming this network not a potential satisfier. 5816 if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) { 5817 return false; 5818 } 5819 // As non-multilayer listen requests have already returned, the below would only happen 5820 // for a multilayer request therefore continue to the next request if available. 5821 if (req.isListen() || req.isListenForBest()) { 5822 continue; 5823 } 5824 // If there is hope for this network might validate and subsequently become the best 5825 // network for that request, then it is needed. Note that this network can't already 5826 // be the best for this request, or it would be the current satisfier, and therefore 5827 // there would be no need to call this method to find out if it is a *potential* 5828 // satisfier ("unneeded", the only caller, only calls this if this network currently 5829 // satisfies no request). 5830 if (candidate.satisfies(req)) { 5831 // As soon as a network is found that satisfies a request, return. Specifically for 5832 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request 5833 // is important so as to not evaluate lower priority requests further in 5834 // nri.mRequests. 5835 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest()) 5836 ? nri.getSatisfier() : null; 5837 // Note that this catches two important cases: 5838 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 5839 // is currently satisfying the request. This is desirable when 5840 // cellular ends up validating but WiFi does not. 5841 // 2. Unvalidated WiFi will not be reaped when validated cellular 5842 // is currently satisfying the request. This is desirable when 5843 // WiFi ends up validating and out scoring cellular. 5844 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable()); 5845 } 5846 } 5847 5848 return false; 5849 } 5850 5851 private NetworkRequestInfo getNriForAppRequest( 5852 NetworkRequest request, int callingUid, String requestedOperation) { 5853 // Looking up the app passed param request in mRequests isn't possible since it may return 5854 // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to 5855 // do the lookup since that will also find per-app default managed requests. 5856 // Additionally, this lookup needs to be relatively fast (hence the lookup optimization) 5857 // to avoid potential race conditions when validating a package->uid mapping when sending 5858 // the callback on the very low-chance that an application shuts down prior to the callback 5859 // being sent. 5860 final NetworkRequestInfo nri = mNetworkRequests.get(request) != null 5861 ? mNetworkRequests.get(request) : getNriForAppRequest(request); 5862 5863 if (nri != null) { 5864 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 5865 log(String.format("UID %d attempted to %s for unowned request %s", 5866 callingUid, requestedOperation, nri)); 5867 return null; 5868 } 5869 } 5870 5871 return nri; 5872 } 5873 5874 private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri, 5875 final String callingMethod) { 5876 if (nri.isMultilayerRequest()) { 5877 throw new IllegalStateException( 5878 callingMethod + " does not support multilayer requests."); 5879 } 5880 } 5881 5882 private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5883 ensureRunningOnConnectivityServiceThread(); 5884 // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a 5885 // single NetworkRequest and thus does not apply to multilayer requests. 5886 ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest"); 5887 if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { 5888 return; 5889 } 5890 if (nri.isBeingSatisfied()) { 5891 return; 5892 } 5893 if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) { 5894 log("releasing " + nri.mRequests.get(0) + " (timeout)"); 5895 } 5896 handleRemoveNetworkRequest(nri); 5897 callCallbackForRequest( 5898 nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 5899 } 5900 5901 private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request, 5902 final int callingUid, 5903 final boolean callOnUnavailable) { 5904 final NetworkRequestInfo nri = 5905 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 5906 if (nri == null) { 5907 return; 5908 } 5909 if (VDBG || (DBG && request.isRequest())) { 5910 log("releasing " + request + " (release request)"); 5911 } 5912 handleRemoveNetworkRequest(nri); 5913 if (callOnUnavailable) { 5914 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 5915 } 5916 } 5917 5918 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5919 handleRemoveNetworkRequest(nri, true /* untrackUids */); 5920 } 5921 5922 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri, 5923 final boolean untrackUids) { 5924 ensureRunningOnConnectivityServiceThread(); 5925 for (final NetworkRequest req : nri.mRequests) { 5926 if (null == mNetworkRequests.remove(req)) { 5927 logw("Attempted removal of untracked request " + req + " for nri " + nri); 5928 continue; 5929 } 5930 if (req.isListen()) { 5931 removeListenRequestFromNetworks(req); 5932 } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) { 5933 mNetworkRequestStateStatsMetrics.onNetworkRequestRemoved(req); 5934 } 5935 } 5936 nri.unlinkDeathRecipient(); 5937 if (mDefaultNetworkRequests.remove(nri)) { 5938 // If this request was one of the defaults, then the UID rules need to be updated 5939 // WARNING : if the app(s) for which this network request is the default are doing 5940 // traffic, this will kill their connected sockets, even if an equivalent request 5941 // is going to be reinstated right away ; unconnected traffic will go on the default 5942 // until the new default is set, which will happen very soon. 5943 // TODO : The only way out of this is to diff old defaults and new defaults, and only 5944 // remove ranges for those requests that won't have a replacement 5945 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5946 if (null != satisfier) { 5947 try { 5948 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 5949 satisfier.network.getNetId(), 5950 toUidRangeStableParcels(nri.getUids()), 5951 nri.getPreferenceOrderForNetd())); 5952 } catch (RemoteException e) { 5953 loge("Exception setting network preference default network", e); 5954 } 5955 } 5956 } 5957 5958 if (untrackUids) { 5959 maybeUntrackUidAndClearBlockedReasons(nri); 5960 } 5961 mNetworkRequestInfoLogs.log("RELEASE " + nri); 5962 checkNrisConsistency(nri); 5963 5964 if (null != nri.getActiveRequest()) { 5965 if (!nri.getActiveRequest().isListen()) { 5966 removeSatisfiedNetworkRequestFromNetwork(nri); 5967 } 5968 } 5969 5970 // For all outstanding offers, cancel any of the layers of this NRI that used to be 5971 // needed for this offer. 5972 for (final NetworkOfferInfo noi : mNetworkOffers) { 5973 for (final NetworkRequest req : nri.mRequests) { 5974 if (req.isRequest() && noi.offer.neededFor(req)) { 5975 noi.offer.onNetworkUnneeded(req); 5976 } 5977 } 5978 } 5979 } 5980 5981 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 5982 handleRemoveNetworkRequests(nris, true /* untrackUids */); 5983 } 5984 5985 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris, 5986 final boolean untrackUids) { 5987 for (final NetworkRequestInfo nri : nris) { 5988 if (mDefaultRequest == nri) { 5989 // Make sure we never remove the default request. 5990 continue; 5991 } 5992 handleRemoveNetworkRequest(nri, untrackUids); 5993 } 5994 } 5995 5996 private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) { 5997 // listens don't have a singular affected Network. Check all networks to see 5998 // if this listen request applies and remove it. 5999 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 6000 nai.removeRequest(req.requestId); 6001 if (req.networkCapabilities.hasSignalStrength() 6002 && nai.satisfiesImmutableCapabilitiesOf(req)) { 6003 updateSignalStrengthThresholds(nai, "RELEASE", req); 6004 } 6005 } 6006 } 6007 6008 /** 6009 * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and 6010 * manage the necessary upkeep (linger, teardown networks, etc.) when doing so. 6011 * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo 6012 */ 6013 private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) { 6014 boolean wasKept = false; 6015 final NetworkAgentInfo nai = nri.getSatisfier(); 6016 if (nai != null) { 6017 final int requestLegacyType = nri.getActiveRequest().legacyType; 6018 final boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 6019 nai.removeRequest(nri.getActiveRequest().requestId); 6020 if (VDBG || DDBG) { 6021 log(" Removing from current network " + nai.toShortString() 6022 + ", leaving " + nai.numNetworkRequests() + " requests."); 6023 } 6024 // If there are still lingered requests on this network, don't tear it down, 6025 // but resume lingering instead. 6026 final long now = SystemClock.elapsedRealtime(); 6027 if (updateInactivityState(nai, now)) { 6028 notifyNetworkLosing(nai, now); 6029 } 6030 if (unneeded(nai, UnneededFor.TEARDOWN)) { 6031 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting"); 6032 teardownUnneededNetwork(nai); 6033 } else { 6034 wasKept = true; 6035 } 6036 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 6037 // Went from foreground to background. 6038 updateCapabilitiesForNetwork(nai); 6039 } 6040 6041 // Maintain the illusion. When this request arrived, we might have pretended 6042 // that a network connected to serve it, even though the network was already 6043 // connected. Now that this request has gone away, we might have to pretend 6044 // that the network disconnected. LegacyTypeTracker will generate that 6045 // phantom disconnect for this type. 6046 if (requestLegacyType != TYPE_NONE) { 6047 boolean doRemove = true; 6048 if (wasKept) { 6049 // check if any of the remaining requests for this network are for the 6050 // same legacy type - if so, don't remove the nai 6051 for (int i = 0; i < nai.numNetworkRequests(); i++) { 6052 NetworkRequest otherRequest = nai.requestAt(i); 6053 if (otherRequest.legacyType == requestLegacyType 6054 && otherRequest.isRequest()) { 6055 if (DBG) log(" still have other legacy request - leaving"); 6056 doRemove = false; 6057 } 6058 } 6059 } 6060 6061 if (doRemove) { 6062 mLegacyTypeTracker.remove(requestLegacyType, nai, false); 6063 } 6064 } 6065 } 6066 } 6067 6068 private RequestInfoPerUidCounter getRequestCounter(NetworkRequestInfo nri) { 6069 return hasAnyPermissionOf(mContext, 6070 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) 6071 ? mSystemNetworkRequestCounter : mNetworkRequestCounter; 6072 } 6073 6074 @Override 6075 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 6076 enforceNetworkStackSettingsOrSetup(); 6077 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 6078 encodeBool(accept), encodeBool(always), network)); 6079 } 6080 6081 @Override 6082 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { 6083 enforceNetworkStackSettingsOrSetup(); 6084 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY, 6085 encodeBool(accept), encodeBool(always), network)); 6086 } 6087 6088 @Override 6089 public void setAvoidUnvalidated(Network network) { 6090 enforceNetworkStackSettingsOrSetup(); 6091 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 6092 } 6093 6094 @Override 6095 public void setTestAllowBadWifiUntil(long timeMs) { 6096 enforceSettingsPermission(); 6097 if (!Build.isDebuggable()) { 6098 throw new IllegalStateException("Does not support in non-debuggable build"); 6099 } 6100 6101 if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) { 6102 throw new IllegalArgumentException("It should not exceed " 6103 + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now"); 6104 } 6105 6106 mHandler.sendMessage( 6107 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs)); 6108 } 6109 6110 @Override 6111 public void setTestLowTcpPollingTimerForKeepalive(long timeMs) { 6112 enforceSettingsPermission(); 6113 6114 if (timeMs > System.currentTimeMillis() + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS) { 6115 throw new IllegalArgumentException("Argument should not exceed " 6116 + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS + "ms from now"); 6117 } 6118 6119 mHandler.sendMessage( 6120 mHandler.obtainMessage(EVENT_SET_LOW_TCP_POLLING_UNTIL, timeMs)); 6121 } 6122 6123 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 6124 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 6125 " accept=" + accept + " always=" + always); 6126 6127 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6128 if (nai == null) { 6129 // Nothing to do. 6130 return; 6131 } 6132 6133 if (nai.everValidated()) { 6134 // The network validated while the dialog box was up. Take no action. 6135 return; 6136 } 6137 6138 if (!nai.networkAgentConfig.explicitlySelected) { 6139 Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 6140 } 6141 6142 if (accept != nai.networkAgentConfig.acceptUnvalidated) { 6143 nai.networkAgentConfig.acceptUnvalidated = accept; 6144 // If network becomes partial connectivity and user already accepted to use this 6145 // network, we should respect the user's option and don't need to popup the 6146 // PARTIAL_CONNECTIVITY notification to user again. 6147 nai.networkAgentConfig.acceptPartialConnectivity = accept; 6148 nai.updateScoreForNetworkAgentUpdate(); 6149 rematchAllNetworksAndRequests(); 6150 } 6151 6152 if (always) { 6153 nai.onSaveAcceptUnvalidated(accept); 6154 } 6155 6156 if (!accept) { 6157 // Tell the NetworkAgent to not automatically reconnect to the network. 6158 nai.onPreventAutomaticReconnect(); 6159 // Teardown the network. 6160 teardownUnneededNetwork(nai); 6161 } 6162 6163 } 6164 6165 private void handleSetAcceptPartialConnectivity(Network network, boolean accept, 6166 boolean always) { 6167 if (DBG) { 6168 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept 6169 + " always=" + always); 6170 } 6171 6172 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6173 if (nai == null) { 6174 // Nothing to do. 6175 return; 6176 } 6177 6178 if (nai.isValidated()) { 6179 // The network validated while the dialog box was up. Take no action. 6180 return; 6181 } 6182 6183 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) { 6184 nai.networkAgentConfig.acceptPartialConnectivity = accept; 6185 } 6186 6187 // TODO: Use the current design or save the user choice into IpMemoryStore. 6188 if (always) { 6189 nai.onSaveAcceptUnvalidated(accept); 6190 } 6191 6192 if (!accept) { 6193 // Tell the NetworkAgent to not automatically reconnect to the network. 6194 nai.onPreventAutomaticReconnect(); 6195 // Tear down the network. 6196 teardownUnneededNetwork(nai); 6197 } else { 6198 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely 6199 // result in a partial connectivity result which will be processed by 6200 // maybeHandleNetworkMonitorMessage. 6201 // 6202 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored 6203 // per network. Therefore, NetworkMonitor may still do https probe. 6204 nai.networkMonitor().setAcceptPartialConnectivity(); 6205 } 6206 } 6207 6208 private void handleSetAvoidUnvalidated(Network network) { 6209 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6210 if (nai == null || nai.isValidated()) { 6211 // Nothing to do. The network either disconnected or revalidated. 6212 return; 6213 } 6214 if (0L == nai.getAvoidUnvalidated()) { 6215 nai.setAvoidUnvalidated(); 6216 nai.updateScoreForNetworkAgentUpdate(); 6217 rematchAllNetworksAndRequests(); 6218 } 6219 } 6220 6221 /** Schedule evaluation timeout */ 6222 @VisibleForTesting 6223 public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) { 6224 mDeps.scheduleEvaluationTimeout(mHandler, network, delayMs); 6225 } 6226 6227 @Override 6228 public void startCaptivePortalApp(Network network) { 6229 enforceNetworkStackOrSettingsPermission(); 6230 mHandler.post(() -> { 6231 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6232 if (nai == null) return; 6233 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 6234 nai.networkMonitor().launchCaptivePortalApp(); 6235 }); 6236 } 6237 6238 /** 6239 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this 6240 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. 6241 * @param network Network on which the captive portal was detected. 6242 * @param appExtras Bundle to use as intent extras for the captive portal application. 6243 * Must be treated as opaque to avoid preventing the captive portal app to 6244 * update its arguments. 6245 */ 6246 @Override 6247 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { 6248 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 6249 "ConnectivityService"); 6250 6251 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); 6252 appIntent.putExtras(appExtras); 6253 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, 6254 new CaptivePortal(new CaptivePortalImpl(network).asBinder())); 6255 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); 6256 6257 final long token = Binder.clearCallingIdentity(); 6258 try { 6259 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT); 6260 } finally { 6261 Binder.restoreCallingIdentity(token); 6262 } 6263 } 6264 6265 private class CaptivePortalImpl extends ICaptivePortal.Stub { 6266 private final Network mNetwork; 6267 6268 private CaptivePortalImpl(Network network) { 6269 mNetwork = network; 6270 } 6271 6272 @Override 6273 public void appResponse(final int response) { 6274 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { 6275 enforceSettingsPermission(); 6276 } else if (response == CaptivePortal.APP_RETURN_UNWANTED) { 6277 mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork)); 6278 // Since the network will be disconnected, skip notifying NetworkMonitor 6279 return; 6280 } 6281 6282 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 6283 if (nm == null) return; 6284 nm.notifyCaptivePortalAppFinished(response); 6285 } 6286 6287 @Override 6288 public void appRequest(final int request) { 6289 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 6290 if (nm == null) return; 6291 6292 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) { 6293 // This enforceNetworkStackPermission() should be adopted to check 6294 // the required permission but this may be break OEM captive portal 6295 // apps. Simply ignore the request if the caller does not have 6296 // permission. 6297 if (!hasNetworkStackPermission()) { 6298 Log.e(TAG, "Calling appRequest() without proper permission. Skip"); 6299 return; 6300 } 6301 6302 nm.forceReevaluation(mDeps.getCallingUid()); 6303 } 6304 } 6305 6306 @Nullable 6307 private NetworkMonitorManager getNetworkMonitorManager(final Network network) { 6308 // getNetworkAgentInfoForNetwork is thread-safe 6309 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6310 if (nai == null) return null; 6311 6312 // nai.networkMonitor() is thread-safe 6313 return nai.networkMonitor(); 6314 } 6315 } 6316 6317 public boolean avoidBadWifi() { 6318 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 6319 } 6320 6321 private boolean activelyPreferBadWifi() { 6322 return mMultinetworkPolicyTracker.getActivelyPreferBadWifi(); 6323 } 6324 6325 /** 6326 * Return whether the device should maintain continuous, working connectivity by switching away 6327 * from WiFi networks having no connectivity. 6328 * @see MultinetworkPolicyTracker#getAvoidBadWifi() 6329 */ 6330 public boolean shouldAvoidBadWifi() { 6331 if (!hasNetworkStackPermission()) { 6332 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); 6333 } 6334 return avoidBadWifi(); 6335 } 6336 6337 private void updateAvoidBadWifi() { 6338 ensureRunningOnConnectivityServiceThread(); 6339 // Agent info scores and offer scores depend on whether cells yields to bad wifi. 6340 final boolean avoidBadWifi = avoidBadWifi(); 6341 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 6342 nai.updateScoreForNetworkAgentUpdate(); 6343 if (avoidBadWifi) { 6344 // If the device is now avoiding bad wifi, remove notifications that might have 6345 // been put up when the device didn't. 6346 mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET); 6347 } 6348 } 6349 // UpdateOfferScore will update mNetworkOffers inline, so make a copy first. 6350 final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers); 6351 for (final NetworkOfferInfo noi : offersToUpdate) { 6352 updateOfferScore(noi.offer); 6353 } 6354 mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi())); 6355 rematchAllNetworksAndRequests(); 6356 } 6357 6358 // TODO: Evaluate whether this is of interest to other consumers of 6359 // MultinetworkPolicyTracker and worth moving out of here. 6360 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 6361 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 6362 if (!configRestrict) { 6363 pw.println("Bad Wi-Fi avoidance: unrestricted"); 6364 return; 6365 } 6366 6367 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 6368 pw.increaseIndent(); 6369 pw.println("Config restrict: " + configRestrict); 6370 pw.println("Actively prefer bad wifi: " + activelyPreferBadWifi()); 6371 6372 final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 6373 String description; 6374 // Can't use a switch statement because strings are legal case labels, but null is not. 6375 if ("0".equals(settingValue)) { 6376 description = "get stuck"; 6377 } else if (settingValue == null) { 6378 description = "prompt"; 6379 } else if ("1".equals(settingValue)) { 6380 description = "avoid"; 6381 } else { 6382 description = settingValue + " (?)"; 6383 } 6384 pw.println("Avoid bad wifi setting: " + description); 6385 6386 final Boolean configValue = BinderUtils.withCleanCallingIdentity( 6387 () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi()); 6388 if (null == configValue) { 6389 description = "unset"; 6390 } else if (configValue) { 6391 description = "force true"; 6392 } else { 6393 description = "force false"; 6394 } 6395 pw.println("Actively prefer bad wifi conf: " + description); 6396 pw.println(); 6397 pw.println("Network overrides:"); 6398 pw.increaseIndent(); 6399 for (NetworkAgentInfo nai : networksSortedById()) { 6400 if (0L != nai.getAvoidUnvalidated()) { 6401 pw.println(nai.toShortString()); 6402 } 6403 } 6404 pw.decreaseIndent(); 6405 pw.decreaseIndent(); 6406 } 6407 6408 // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to 6409 // unify the method. 6410 private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) { 6411 final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS); 6412 final ComponentName settingsComponent = settingsIntent.resolveActivity(pm); 6413 return settingsComponent != null 6414 ? settingsComponent.getPackageName() : "com.android.settings"; 6415 } 6416 6417 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) { 6418 final String action; 6419 final boolean highPriority; 6420 switch (type) { 6421 case NO_INTERNET: 6422 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 6423 // High priority because it is only displayed for explicitly selected networks. 6424 highPriority = true; 6425 break; 6426 case PRIVATE_DNS_BROKEN: 6427 action = Settings.ACTION_WIRELESS_SETTINGS; 6428 // High priority because we should let user know why there is no internet. 6429 highPriority = true; 6430 break; 6431 case LOST_INTERNET: 6432 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 6433 // High priority because it could help the user avoid unexpected data usage. 6434 highPriority = true; 6435 break; 6436 case PARTIAL_CONNECTIVITY: 6437 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY; 6438 // Don't bother the user with a high-priority notification if the network was not 6439 // explicitly selected by the user. 6440 highPriority = nai.networkAgentConfig.explicitlySelected; 6441 break; 6442 default: 6443 Log.wtf(TAG, "Unknown notification type " + type); 6444 return; 6445 } 6446 6447 Intent intent = new Intent(action); 6448 if (type != NotificationType.PRIVATE_DNS_BROKEN) { 6449 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network); 6450 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 6451 // Some OEMs have their own Settings package. Thus, need to get the current using 6452 // Settings package name instead of just use default name "com.android.settings". 6453 final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager()); 6454 intent.setClassName(settingsPkgName, 6455 settingsPkgName + ".wifi.WifiNoInternetDialog"); 6456 } 6457 6458 PendingIntent pendingIntent = PendingIntent.getActivity( 6459 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 6460 0 /* requestCode */, 6461 intent, 6462 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 6463 6464 mNotifier.showNotification( 6465 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority); 6466 } 6467 6468 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) { 6469 // Don't prompt if the network is validated, and don't prompt on captive portals 6470 // because we're already prompting the user to sign in. 6471 if (nai.everValidated() || nai.everCaptivePortalDetected()) { 6472 return false; 6473 } 6474 6475 // If a network has partial connectivity, always prompt unless the user has already accepted 6476 // partial connectivity and selected don't ask again. This ensures that if the device 6477 // automatically connects to a network that has partial Internet access, the user will 6478 // always be able to use it, either because they've already chosen "don't ask again" or 6479 // because we have prompted them. 6480 if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) { 6481 return true; 6482 } 6483 6484 // If a network has no Internet access, only prompt if the network was explicitly selected 6485 // and if the user has not already told us to use the network regardless of whether it 6486 // validated or not. 6487 if (nai.networkAgentConfig.explicitlySelected 6488 && !nai.networkAgentConfig.acceptUnvalidated) { 6489 return true; 6490 } 6491 6492 return false; 6493 } 6494 6495 private void handleInitialEvaluationTimeout(@NonNull final Network network) { 6496 if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network); 6497 6498 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6499 if (null == nai) return; 6500 6501 if (nai.setEvaluated()) { 6502 // If setEvaluated() returned true, the network never had any form of connectivity. 6503 // This may have an impact on request matching if bad WiFi avoidance is off and the 6504 // network was found not to have Internet access. 6505 nai.updateScoreForNetworkAgentUpdate(); 6506 rematchAllNetworksAndRequests(); 6507 6508 // Also, if this is WiFi and it should be preferred actively, now is the time to 6509 // prompt the user that they walked past and connected to a bad WiFi. 6510 if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI) 6511 && !avoidBadWifi() 6512 && activelyPreferBadWifi()) { 6513 // The notification will be removed if the network validates or disconnects. 6514 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 6515 return; 6516 } 6517 } 6518 6519 if (!shouldPromptUnvalidated(nai)) return; 6520 6521 // Stop automatically reconnecting to this network in the future. Automatically connecting 6522 // to a network that provides no or limited connectivity is not useful, because the user 6523 // cannot use that network except through the notification shown by this method, and the 6524 // notification is only shown if the network is explicitly selected by the user. 6525 nai.onPreventAutomaticReconnect(); 6526 6527 if (nai.partialConnectivity()) { 6528 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); 6529 } else { 6530 showNetworkNotification(nai, NotificationType.NO_INTERNET); 6531 } 6532 } 6533 6534 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 6535 NetworkCapabilities nc = nai.networkCapabilities; 6536 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc); 6537 6538 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 6539 return; 6540 } 6541 6542 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 6543 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 6544 } 6545 } 6546 6547 @Override 6548 public int getMultipathPreference(Network network) { 6549 enforceAccessPermission(); 6550 6551 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6552 if (nai != null && nai.networkCapabilities 6553 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 6554 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 6555 } 6556 6557 final NetworkPolicyManager netPolicyManager = 6558 mContext.getSystemService(NetworkPolicyManager.class); 6559 6560 final long token = Binder.clearCallingIdentity(); 6561 final int networkPreference; 6562 try { 6563 networkPreference = netPolicyManager.getMultipathPreference(network); 6564 } finally { 6565 Binder.restoreCallingIdentity(token); 6566 } 6567 if (networkPreference != 0) { 6568 return networkPreference; 6569 } 6570 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 6571 } 6572 6573 @Override 6574 public NetworkRequest getDefaultRequest() { 6575 return mDefaultRequest.mRequests.get(0); 6576 } 6577 6578 private class InternalHandler extends Handler { 6579 public InternalHandler(Looper looper) { 6580 super(looper); 6581 } 6582 6583 @Override 6584 public void handleMessage(Message msg) { 6585 switch (msg.what) { 6586 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 6587 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 6588 handleReleaseNetworkTransitionWakelock(msg.what); 6589 break; 6590 } 6591 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 6592 mProxyTracker.loadDeprecatedGlobalHttpProxy(); 6593 break; 6594 } 6595 case EVENT_PAC_PROXY_HAS_CHANGED: { 6596 final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj; 6597 handlePacProxyServiceStarted(arg.first, arg.second); 6598 break; 6599 } 6600 case EVENT_REGISTER_NETWORK_PROVIDER: { 6601 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); 6602 break; 6603 } 6604 case EVENT_UNREGISTER_NETWORK_PROVIDER: { 6605 handleUnregisterNetworkProvider((Messenger) msg.obj); 6606 break; 6607 } 6608 case EVENT_REGISTER_NETWORK_OFFER: { 6609 handleRegisterNetworkOffer((NetworkOffer) msg.obj); 6610 break; 6611 } 6612 case EVENT_UNREGISTER_NETWORK_OFFER: { 6613 final NetworkOfferInfo offer = 6614 findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj); 6615 if (null != offer) { 6616 handleUnregisterNetworkOffer(offer); 6617 } 6618 break; 6619 } 6620 case EVENT_REGISTER_NETWORK_AGENT: { 6621 final Pair<NetworkAgentInfo, INetworkMonitor> arg = 6622 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; 6623 handleRegisterNetworkAgent(arg.first, arg.second); 6624 break; 6625 } 6626 case EVENT_REGISTER_NETWORK_REQUEST: 6627 case EVENT_REGISTER_NETWORK_LISTENER: { 6628 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 6629 break; 6630 } 6631 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 6632 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 6633 handleRegisterNetworkRequestWithIntent(msg); 6634 break; 6635 } 6636 case EVENT_TIMEOUT_NETWORK_REQUEST: { 6637 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 6638 handleTimedOutNetworkRequest(nri); 6639 break; 6640 } 6641 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 6642 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 6643 break; 6644 } 6645 case EVENT_RELEASE_NETWORK_REQUEST: { 6646 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1, 6647 /* callOnUnavailable */ false); 6648 break; 6649 } 6650 case EVENT_SET_ACCEPT_UNVALIDATED: { 6651 Network network = (Network) msg.obj; 6652 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 6653 break; 6654 } 6655 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: { 6656 Network network = (Network) msg.obj; 6657 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1), 6658 toBool(msg.arg2)); 6659 break; 6660 } 6661 case EVENT_SET_AVOID_UNVALIDATED: { 6662 handleSetAvoidUnvalidated((Network) msg.obj); 6663 break; 6664 } 6665 case EVENT_INITIAL_EVALUATION_TIMEOUT: { 6666 handleInitialEvaluationTimeout((Network) msg.obj); 6667 break; 6668 } 6669 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { 6670 handleConfigureAlwaysOnNetworks(); 6671 break; 6672 } 6673 // Sent by AutomaticOnOffKeepaliveTracker to process an app request on the 6674 // handler thread. 6675 case AutomaticOnOffKeepaliveTracker.CMD_REQUEST_START_KEEPALIVE: { 6676 mKeepaliveTracker.handleStartKeepalive(msg); 6677 break; 6678 } 6679 case AutomaticOnOffKeepaliveTracker.CMD_MONITOR_AUTOMATIC_KEEPALIVE: { 6680 final AutomaticOnOffKeepalive ki = 6681 mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj); 6682 if (null == ki) return; // The callback was unregistered before the alarm fired 6683 6684 final Network underpinnedNetwork = ki.getUnderpinnedNetwork(); 6685 final Network network = ki.getNetwork(); 6686 boolean networkFound = false; 6687 boolean underpinnedNetworkFound = false; 6688 for (NetworkAgentInfo n : mNetworkAgentInfos) { 6689 if (n.network.equals(network)) networkFound = true; 6690 if (n.everConnected() && n.network.equals(underpinnedNetwork)) { 6691 underpinnedNetworkFound = true; 6692 } 6693 } 6694 6695 // If the network no longer exists, then the keepalive should have been 6696 // cleaned up already. There is no point trying to resume keepalives. 6697 if (!networkFound) return; 6698 6699 if (underpinnedNetworkFound) { 6700 mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki, 6701 underpinnedNetwork.netId); 6702 } else { 6703 // If no underpinned network, then make sure the keepalive is running. 6704 mKeepaliveTracker.handleMaybeResumeKeepalive(ki); 6705 } 6706 break; 6707 } 6708 // Sent by KeepaliveTracker to process an app request on the state machine thread. 6709 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: { 6710 final AutomaticOnOffKeepalive ki = mKeepaliveTracker.getKeepaliveForBinder( 6711 (IBinder) msg.obj); 6712 if (ki == null) { 6713 Log.e(TAG, "Attempt to stop an already stopped keepalive"); 6714 return; 6715 } 6716 final int reason = msg.arg2; 6717 mKeepaliveTracker.handleStopKeepalive(ki, reason); 6718 break; 6719 } 6720 case EVENT_REPORT_NETWORK_CONNECTIVITY: { 6721 handleReportNetworkConnectivity((NetworkAgentInfo) msg.obj, msg.arg1, 6722 toBool(msg.arg2)); 6723 break; 6724 } 6725 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 6726 handlePrivateDnsSettingsChanged(); 6727 break; 6728 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 6729 handlePrivateDnsValidationUpdate( 6730 (PrivateDnsValidationUpdate) msg.obj); 6731 break; 6732 case EVENT_BLOCKED_REASONS_CHANGED: 6733 handleBlockedReasonsChanged((List) msg.obj); 6734 break; 6735 case EVENT_SET_REQUIRE_VPN_FOR_UIDS: 6736 handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); 6737 break; 6738 case EVENT_SET_OEM_NETWORK_PREFERENCE: { 6739 final Pair<OemNetworkPreferences, IOnCompleteListener> arg = 6740 (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj; 6741 handleSetOemNetworkPreference(arg.first, arg.second); 6742 break; 6743 } 6744 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: { 6745 final Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener> arg = 6746 (Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener>) msg.obj; 6747 handleSetProfileNetworkPreference(arg.first, arg.second); 6748 break; 6749 } 6750 case EVENT_REPORT_NETWORK_ACTIVITY: 6751 final NetworkActivityParams arg = (NetworkActivityParams) msg.obj; 6752 handleReportNetworkActivity(arg); 6753 break; 6754 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED: 6755 handleMobileDataPreferredUidsChanged(); 6756 break; 6757 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL: 6758 final long timeMs = ((Long) msg.obj).longValue(); 6759 mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs); 6760 break; 6761 case EVENT_INGRESS_RATE_LIMIT_CHANGED: 6762 handleIngressRateLimitChanged(); 6763 break; 6764 case EVENT_USER_DOES_NOT_WANT: 6765 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 6766 if (nai == null) break; 6767 nai.onPreventAutomaticReconnect(); 6768 nai.disconnect(); 6769 break; 6770 case EVENT_SET_VPN_NETWORK_PREFERENCE: 6771 handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj); 6772 break; 6773 case EVENT_SET_LOW_TCP_POLLING_UNTIL: { 6774 final long time = ((Long) msg.obj).longValue(); 6775 mKeepaliveTracker.handleSetTestLowTcpPollingTimer(time); 6776 break; 6777 } 6778 case EVENT_UID_FROZEN_STATE_CHANGED: 6779 UidFrozenStateChangedArgs args = (UidFrozenStateChangedArgs) msg.obj; 6780 handleFrozenUids(args.mUids, args.mFrozenStates); 6781 break; 6782 case EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS: 6783 handleUpdateFirewallDestroySocketReasons((List) msg.obj); 6784 break; 6785 case EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS: 6786 handleClearFirewallDestroySocketReasons(msg.arg1); 6787 break; 6788 } 6789 } 6790 } 6791 6792 @Override 6793 @Deprecated 6794 public int getLastTetherError(String iface) { 6795 enforceAccessPermission(); 6796 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6797 Context.TETHERING_SERVICE); 6798 return tm.getLastTetherError(iface); 6799 } 6800 6801 @Override 6802 @Deprecated 6803 public String[] getTetherableIfaces() { 6804 enforceAccessPermission(); 6805 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6806 Context.TETHERING_SERVICE); 6807 return tm.getTetherableIfaces(); 6808 } 6809 6810 @Override 6811 @Deprecated 6812 public String[] getTetheredIfaces() { 6813 enforceAccessPermission(); 6814 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6815 Context.TETHERING_SERVICE); 6816 return tm.getTetheredIfaces(); 6817 } 6818 6819 6820 @Override 6821 @Deprecated 6822 public String[] getTetheringErroredIfaces() { 6823 enforceAccessPermission(); 6824 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6825 Context.TETHERING_SERVICE); 6826 6827 return tm.getTetheringErroredIfaces(); 6828 } 6829 6830 @Override 6831 @Deprecated 6832 public String[] getTetherableUsbRegexs() { 6833 enforceAccessPermission(); 6834 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6835 Context.TETHERING_SERVICE); 6836 6837 return tm.getTetherableUsbRegexs(); 6838 } 6839 6840 @Override 6841 @Deprecated 6842 public String[] getTetherableWifiRegexs() { 6843 enforceAccessPermission(); 6844 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 6845 Context.TETHERING_SERVICE); 6846 return tm.getTetherableWifiRegexs(); 6847 } 6848 6849 // Called when we lose the default network and have no replacement yet. 6850 // This will automatically be cleared after X seconds or a new default network 6851 // becomes CONNECTED, whichever happens first. The timer is started by the 6852 // first caller and not restarted by subsequent callers. 6853 private void ensureNetworkTransitionWakelock(String forWhom) { 6854 synchronized (this) { 6855 if (mNetTransitionWakeLock.isHeld()) { 6856 return; 6857 } 6858 mNetTransitionWakeLock.acquire(); 6859 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 6860 mTotalWakelockAcquisitions++; 6861 } 6862 mWakelockLogs.log("ACQUIRE for " + forWhom); 6863 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 6864 final int lockTimeout = mResources.get().getInteger( 6865 R.integer.config_networkTransitionTimeout); 6866 mHandler.sendMessageDelayed(msg, lockTimeout); 6867 } 6868 6869 // Called when we gain a new default network to release the network transition wakelock in a 6870 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 6871 // message is cancelled. 6872 private void scheduleReleaseNetworkTransitionWakelock() { 6873 synchronized (this) { 6874 if (!mNetTransitionWakeLock.isHeld()) { 6875 return; // expiry message released the lock first. 6876 } 6877 } 6878 // Cancel self timeout on wakelock hold. 6879 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 6880 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 6881 mHandler.sendMessageDelayed(msg, 1000); 6882 } 6883 6884 // Called when either message of ensureNetworkTransitionWakelock or 6885 // scheduleReleaseNetworkTransitionWakelock is processed. 6886 private void handleReleaseNetworkTransitionWakelock(int eventId) { 6887 String event = eventName(eventId); 6888 synchronized (this) { 6889 if (!mNetTransitionWakeLock.isHeld()) { 6890 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 6891 Log.w(TAG, "expected Net Transition WakeLock to be held"); 6892 return; 6893 } 6894 mNetTransitionWakeLock.release(); 6895 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 6896 mTotalWakelockDurationMs += lockDuration; 6897 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 6898 mTotalWakelockReleases++; 6899 } 6900 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 6901 } 6902 6903 // 100 percent is full good, 0 is full bad. 6904 @Override 6905 public void reportInetCondition(int networkType, int percentage) { 6906 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 6907 if (nai == null) return; 6908 reportNetworkConnectivity(nai.network, percentage > 50); 6909 } 6910 6911 @Override 6912 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 6913 enforceAccessPermission(); 6914 enforceInternetPermission(); 6915 final int uid = mDeps.getCallingUid(); 6916 final int connectivityInfo = encodeBool(hasConnectivity); 6917 6918 final NetworkAgentInfo nai; 6919 if (network == null) { 6920 nai = getDefaultNetwork(); 6921 } else { 6922 nai = getNetworkAgentInfoForNetwork(network); 6923 } 6924 6925 mHandler.sendMessage( 6926 mHandler.obtainMessage( 6927 EVENT_REPORT_NETWORK_CONNECTIVITY, uid, connectivityInfo, nai)); 6928 } 6929 6930 private void handleReportNetworkConnectivity( 6931 @Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) { 6932 if (nai == null 6933 || nai != getNetworkAgentInfoForNetwork(nai.network) 6934 || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 6935 return; 6936 } 6937 // Revalidate if the app report does not match our current validated state. 6938 if (hasConnectivity == nai.isValidated()) { 6939 mConnectivityDiagnosticsHandler.sendMessage( 6940 mConnectivityDiagnosticsHandler.obtainMessage( 6941 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 6942 new ReportedNetworkConnectivityInfo( 6943 hasConnectivity, false /* isNetworkRevalidating */, uid, nai))); 6944 return; 6945 } 6946 if (DBG) { 6947 int netid = nai.network.getNetId(); 6948 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 6949 } 6950 // Validating a network that has not yet connected could result in a call to 6951 // rematchNetworkAndRequests() which is not meant to work on such networks. 6952 if (!nai.everConnected()) { 6953 return; 6954 } 6955 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 6956 if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) { 6957 return; 6958 } 6959 6960 // Send CONNECTIVITY_REPORTED event before re-validating the Network to force an ordering of 6961 // ConnDiags events. This ensures that #onNetworkConnectivityReported() will be called 6962 // before #onConnectivityReportAvailable(), which is called once Network evaluation is 6963 // completed. 6964 mConnectivityDiagnosticsHandler.sendMessage( 6965 mConnectivityDiagnosticsHandler.obtainMessage( 6966 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 6967 new ReportedNetworkConnectivityInfo( 6968 hasConnectivity, true /* isNetworkRevalidating */, uid, nai))); 6969 nai.networkMonitor().forceReevaluation(uid); 6970 } 6971 6972 // TODO: call into netd. 6973 private boolean queryUserAccess(int uid, Network network) { 6974 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6975 if (nai == null) return false; 6976 6977 // Any UID can use its default network. 6978 if (nai == getDefaultNetworkForUid(uid)) return true; 6979 6980 // Privileged apps can use any network. 6981 if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) { 6982 return true; 6983 } 6984 6985 // An unprivileged UID can use a VPN iff the VPN applies to it. 6986 if (nai.isVPN()) { 6987 return nai.networkCapabilities.appliesToUid(uid); 6988 } 6989 6990 // An unprivileged UID can bypass the VPN that applies to it only if it can protect its 6991 // sockets, i.e., if it is the owner. 6992 final NetworkAgentInfo vpn = getVpnForUid(uid); 6993 if (vpn != null && !vpn.networkAgentConfig.allowBypass 6994 && uid != vpn.networkCapabilities.getOwnerUid()) { 6995 return false; 6996 } 6997 6998 // The UID's permission must be at least sufficient for the network. Since the restricted 6999 // permission was already checked above, that just leaves background networks. 7000 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { 7001 return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid); 7002 } 7003 7004 // Unrestricted network. Anyone gets to use it. 7005 return true; 7006 } 7007 7008 /** 7009 * Returns information about the proxy a certain network is using. If given a null network, it 7010 * it will return the proxy for the bound network for the caller app or the default proxy if 7011 * none. 7012 * 7013 * @param network the network we want to get the proxy information for. 7014 * @return Proxy information if a network has a proxy configured, or otherwise null. 7015 */ 7016 @Override 7017 public ProxyInfo getProxyForNetwork(Network network) { 7018 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy(); 7019 if (globalProxy != null) return globalProxy; 7020 if (network == null) { 7021 // Get the network associated with the calling UID. 7022 final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(), 7023 true); 7024 if (activeNetwork == null) { 7025 return null; 7026 } 7027 return getLinkPropertiesProxyInfo(activeNetwork); 7028 } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) { 7029 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 7030 // caller may not have. 7031 return getLinkPropertiesProxyInfo(network); 7032 } 7033 // No proxy info available if the calling UID does not have network access. 7034 return null; 7035 } 7036 7037 7038 private ProxyInfo getLinkPropertiesProxyInfo(Network network) { 7039 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 7040 if (nai == null) return null; 7041 synchronized (nai) { 7042 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy(); 7043 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy); 7044 } 7045 } 7046 7047 @Override 7048 public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) { 7049 enforceNetworkStackPermission(mContext); 7050 mProxyTracker.setGlobalProxy(proxyProperties); 7051 } 7052 7053 @Override 7054 @Nullable 7055 public ProxyInfo getGlobalProxy() { 7056 return mProxyTracker.getGlobalProxy(); 7057 } 7058 7059 private void handlePacProxyServiceStarted(@Nullable Network net, @Nullable ProxyInfo proxy) { 7060 mProxyTracker.setDefaultProxy(proxy); 7061 final NetworkAgentInfo nai = getDefaultNetwork(); 7062 // TODO : this method should check that net == nai.network, unfortunately at this point 7063 // 'net' is always null in practice (see PacProxyService#sendPacBroadcast). PAC proxy 7064 // is only ever installed on the default network so in practice this is okay. 7065 if (null == nai) return; 7066 // PAC proxies only work on the default network. Therefore, only the default network 7067 // should have its link properties fixed up for PAC proxies. 7068 mProxyTracker.updateDefaultNetworkProxyPortForPAC(nai.linkProperties, nai.network); 7069 if (nai.everConnected()) { 7070 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_IP_CHANGED); 7071 } 7072 } 7073 7074 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called 7075 // when any network changes proxy. 7076 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a 7077 // multi-network world where an app might be bound to a non-default network. 7078 private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 7079 ProxyInfo newProxyInfo = newLp.getHttpProxy(); 7080 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 7081 7082 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 7083 mProxyTracker.sendProxyBroadcast(); 7084 } 7085 } 7086 7087 private static class SettingsObserver extends ContentObserver { 7088 final private HashMap<Uri, Integer> mUriEventMap; 7089 final private Context mContext; 7090 final private Handler mHandler; 7091 7092 SettingsObserver(Context context, Handler handler) { 7093 super(null); 7094 mUriEventMap = new HashMap<>(); 7095 mContext = context; 7096 mHandler = handler; 7097 } 7098 7099 void observe(Uri uri, int what) { 7100 mUriEventMap.put(uri, what); 7101 final ContentResolver resolver = mContext.getContentResolver(); 7102 resolver.registerContentObserver(uri, false, this); 7103 } 7104 7105 @Override 7106 public void onChange(boolean selfChange) { 7107 Log.wtf(TAG, "Should never be reached."); 7108 } 7109 7110 @Override 7111 public void onChange(boolean selfChange, Uri uri) { 7112 final Integer what = mUriEventMap.get(uri); 7113 if (what != null) { 7114 mHandler.obtainMessage(what).sendToTarget(); 7115 } else { 7116 loge("No matching event to send for URI=" + uri); 7117 } 7118 } 7119 } 7120 7121 private static void log(String s) { 7122 Log.d(TAG, s); 7123 } 7124 7125 private static void logw(String s) { 7126 Log.w(TAG, s); 7127 } 7128 7129 private static void logwtf(String s) { 7130 Log.wtf(TAG, s); 7131 } 7132 7133 private static void logwtf(String s, Throwable t) { 7134 Log.wtf(TAG, s, t); 7135 } 7136 7137 private static void loge(String s) { 7138 Log.e(TAG, s); 7139 } 7140 7141 private static void loge(String s, Throwable t) { 7142 Log.e(TAG, s, t); 7143 } 7144 7145 /** 7146 * Return the information of all ongoing VPNs. 7147 * 7148 * <p>This method is used to update NetworkStatsService. 7149 * 7150 * <p>Must be called on the handler thread. 7151 */ 7152 private UnderlyingNetworkInfo[] getAllVpnInfo() { 7153 ensureRunningOnConnectivityServiceThread(); 7154 if (mLockdownEnabled) { 7155 return new UnderlyingNetworkInfo[0]; 7156 } 7157 List<UnderlyingNetworkInfo> infoList = new ArrayList<>(); 7158 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 7159 UnderlyingNetworkInfo info = createVpnInfo(nai); 7160 if (info != null) { 7161 infoList.add(info); 7162 } 7163 } 7164 return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]); 7165 } 7166 7167 /** 7168 * @return VPN information for accounting, or null if we can't retrieve all required 7169 * information, e.g underlying ifaces. 7170 */ 7171 private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) { 7172 Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; 7173 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 7174 // the underlyingNetworks list. 7175 // TODO: stop using propagateUnderlyingCapabilities here, for example, by always 7176 // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array. 7177 if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) { 7178 final NetworkAgentInfo defaultNai = getDefaultNetworkForUid( 7179 nai.networkCapabilities.getOwnerUid()); 7180 if (defaultNai != null) { 7181 underlyingNetworks = new Network[] { defaultNai.network }; 7182 } 7183 } 7184 7185 if (CollectionUtils.isEmpty(underlyingNetworks)) return null; 7186 7187 List<String> interfaces = new ArrayList<>(); 7188 for (Network network : underlyingNetworks) { 7189 NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network); 7190 if (underlyingNai == null) continue; 7191 LinkProperties lp = underlyingNai.linkProperties; 7192 for (String iface : lp.getAllInterfaceNames()) { 7193 if (!TextUtils.isEmpty(iface)) { 7194 interfaces.add(iface); 7195 } 7196 } 7197 } 7198 7199 if (interfaces.isEmpty()) return null; 7200 7201 // Must be non-null or NetworkStatsService will crash. 7202 // Cannot happen in production code because Vpn only registers the NetworkAgent after the 7203 // tun or ipsec interface is created. 7204 // TODO: Remove this check. 7205 if (nai.linkProperties.getInterfaceName() == null) return null; 7206 7207 return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(), 7208 nai.linkProperties.getInterfaceName(), interfaces); 7209 } 7210 7211 // TODO This needs to be the default network that applies to the NAI. 7212 private Network[] underlyingNetworksOrDefault(final int ownerUid, 7213 Network[] underlyingNetworks) { 7214 final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid)); 7215 if (underlyingNetworks == null && defaultNetwork != null) { 7216 // null underlying networks means to track the default. 7217 underlyingNetworks = new Network[] { defaultNetwork }; 7218 } 7219 return underlyingNetworks; 7220 } 7221 7222 // Returns true iff |network| is an underlying network of |nai|. 7223 private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) { 7224 // TODO: support more than one level of underlying networks, either via a fixed-depth search 7225 // (e.g., 2 levels of underlying networks), or via loop detection, or.... 7226 if (!nai.propagateUnderlyingCapabilities()) return false; 7227 final Network[] underlying = underlyingNetworksOrDefault( 7228 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks); 7229 return CollectionUtils.contains(underlying, network); 7230 } 7231 7232 /** 7233 * Recompute the capabilities for any networks that had a specific network as underlying. 7234 * 7235 * When underlying networks change, such networks may have to update capabilities to reflect 7236 * things like the metered bit, their transports, and so on. The capabilities are calculated 7237 * immediately. This method runs on the ConnectivityService thread. 7238 */ 7239 private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) { 7240 ensureRunningOnConnectivityServiceThread(); 7241 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 7242 if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) { 7243 updateCapabilitiesForNetwork(nai); 7244 } 7245 } 7246 } 7247 7248 private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) { 7249 // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies 7250 // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when 7251 // a VPN is not up. 7252 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 7253 if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false; 7254 for (UidRange range : blockedUidRanges) { 7255 if (range.contains(uid)) return true; 7256 } 7257 return false; 7258 } 7259 7260 @Override 7261 public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 7262 enforceNetworkStackOrSettingsPermission(); 7263 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS, 7264 encodeBool(requireVpn), 0 /* arg2 */, ranges)); 7265 } 7266 7267 private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 7268 if (DBG) { 7269 Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: " 7270 + Arrays.toString(ranges)); 7271 } 7272 // Cannot use a Set since the list of UID ranges might contain duplicates. 7273 final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges); 7274 for (int i = 0; i < ranges.length; i++) { 7275 if (requireVpn) { 7276 newVpnBlockedUidRanges.add(ranges[i]); 7277 } else { 7278 newVpnBlockedUidRanges.remove(ranges[i]); 7279 } 7280 } 7281 7282 try { 7283 mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges)); 7284 } catch (RemoteException | ServiceSpecificException e) { 7285 Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", " 7286 + Arrays.toString(ranges) + "): netd command failed: " + e); 7287 } 7288 7289 if (mDeps.isAtLeastT()) { 7290 mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges); 7291 } 7292 7293 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 7294 final boolean curMetered = nai.networkCapabilities.isMetered(); 7295 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, 7296 mVpnBlockedUidRanges, newVpnBlockedUidRanges); 7297 } 7298 7299 mVpnBlockedUidRanges = newVpnBlockedUidRanges; 7300 } 7301 7302 @Override 7303 public void setLegacyLockdownVpnEnabled(boolean enabled) { 7304 enforceNetworkStackOrSettingsPermission(); 7305 mHandler.post(() -> mLockdownEnabled = enabled); 7306 } 7307 7308 private boolean isLegacyLockdownNai(NetworkAgentInfo nai) { 7309 return mLockdownEnabled 7310 && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY 7311 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID); 7312 } 7313 7314 private NetworkAgentInfo getLegacyLockdownNai() { 7315 if (!mLockdownEnabled) { 7316 return null; 7317 } 7318 // The legacy lockdown VPN always only applies to userId 0. 7319 final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID); 7320 if (nai == null || !isLegacyLockdownNai(nai)) return null; 7321 7322 // The legacy lockdown VPN must always have exactly one underlying network. 7323 // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in 7324 // a local variable. There is no need to make a copy because its contents cannot change. 7325 final Network[] underlying = nai.declaredUnderlyingNetworks; 7326 if (underlying == null || underlying.length != 1) { 7327 return null; 7328 } 7329 7330 // The legacy lockdown VPN always uses the default network. 7331 // If the VPN's underlying network is no longer the current default network, it means that 7332 // the default network has just switched, and the VPN is about to disconnect. 7333 // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten 7334 // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED. 7335 final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 7336 if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) { 7337 return null; 7338 } 7339 7340 return nai; 7341 }; 7342 7343 // TODO: move all callers to filterForLegacyLockdown and delete this method. 7344 // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of 7345 // just a DetailedState object. 7346 private DetailedState getLegacyLockdownState(DetailedState origState) { 7347 if (origState != DetailedState.CONNECTED) { 7348 return origState; 7349 } 7350 return (mLockdownEnabled && getLegacyLockdownNai() == null) 7351 ? DetailedState.CONNECTING 7352 : DetailedState.CONNECTED; 7353 } 7354 7355 private void filterForLegacyLockdown(NetworkInfo ni) { 7356 if (!mLockdownEnabled || !ni.isConnected()) return; 7357 // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the 7358 // state of its VPN. This is to ensure that when an underlying network connects, apps will 7359 // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN 7360 // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying 7361 // network, this time with a state of CONNECTED. 7362 // 7363 // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access 7364 // to the internal state of the Vpn object, always replace the state with CONNECTING. This 7365 // is not too far off the truth, since an always-on VPN, when not connected, is always 7366 // trying to reconnect. 7367 if (getLegacyLockdownNai() == null) { 7368 ni.setDetailedState(DetailedState.CONNECTING, "", null); 7369 } 7370 } 7371 7372 @Override 7373 public void setProvisioningNotificationVisible(boolean visible, int networkType, 7374 String action) { 7375 enforceSettingsPermission(); 7376 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 7377 return; 7378 } 7379 final long ident = Binder.clearCallingIdentity(); 7380 try { 7381 // Concatenate the range of types onto the range of NetIDs. 7382 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 7383 mNotifier.setProvNotificationVisible(visible, id, action); 7384 } finally { 7385 Binder.restoreCallingIdentity(ident); 7386 } 7387 } 7388 7389 @Override 7390 public void setAirplaneMode(boolean enable) { 7391 enforceAirplaneModePermission(); 7392 final long ident = Binder.clearCallingIdentity(); 7393 try { 7394 final ContentResolver cr = mContext.getContentResolver(); 7395 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 7396 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 7397 intent.putExtra("state", enable); 7398 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 7399 } finally { 7400 Binder.restoreCallingIdentity(ident); 7401 } 7402 } 7403 7404 private void onUserAdded(@NonNull final UserHandle user) { 7405 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 7406 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7407 } 7408 updateProfileAllowedNetworks(); 7409 } 7410 7411 private void onUserRemoved(@NonNull final UserHandle user) { 7412 // If there was a network preference for this user, remove it. 7413 handleSetProfileNetworkPreference( 7414 List.of(new ProfileNetworkPreferenceInfo(user, null, true, 7415 false /* blockingNonEnterprise */)), 7416 null /* listener */); 7417 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 7418 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7419 } 7420 } 7421 7422 private void onPackageChanged(@NonNull final String packageName) { 7423 // This is necessary in case a package is added or removed, but also when it's replaced to 7424 // run as a new UID by its manifest rules. Also, if a separate package shares the same UID 7425 // as one in the preferences, then it should follow the same routing as that other package, 7426 // which means updating the rules is never to be needed in this case (whether it joins or 7427 // leaves a UID with a preference). 7428 if (isMappedInOemNetworkPreference(packageName)) { 7429 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7430 } 7431 7432 // Invalidates cache entry when the package is updated. 7433 synchronized (mSelfCertifiedCapabilityCache) { 7434 mSelfCertifiedCapabilityCache.remove(packageName); 7435 } 7436 } 7437 7438 private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 7439 @Override 7440 public void onReceive(Context context, Intent intent) { 7441 ensureRunningOnConnectivityServiceThread(); 7442 final String action = intent.getAction(); 7443 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 7444 7445 // User should be filled for below intents, check the existence. 7446 if (user == null) { 7447 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER"); 7448 return; 7449 } 7450 7451 if (Intent.ACTION_USER_ADDED.equals(action)) { 7452 onUserAdded(user); 7453 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 7454 onUserRemoved(user); 7455 } else { 7456 Log.wtf(TAG, "received unexpected intent: " + action); 7457 } 7458 } 7459 }; 7460 7461 private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { 7462 @Override 7463 public void onReceive(Context context, Intent intent) { 7464 ensureRunningOnConnectivityServiceThread(); 7465 switch (intent.getAction()) { 7466 case Intent.ACTION_PACKAGE_ADDED: 7467 case Intent.ACTION_PACKAGE_REMOVED: 7468 case Intent.ACTION_PACKAGE_REPLACED: 7469 onPackageChanged(intent.getData().getSchemeSpecificPart()); 7470 break; 7471 default: 7472 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 7473 } 7474 } 7475 }; 7476 7477 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 7478 private final BroadcastReceiver mDataSaverReceiver = new BroadcastReceiver() { 7479 @Override 7480 public void onReceive(Context context, Intent intent) { 7481 if (mDeps.isAtLeastV()) { 7482 throw new IllegalStateException( 7483 "data saver status should be updated from platform"); 7484 } 7485 ensureRunningOnConnectivityServiceThread(); 7486 switch (intent.getAction()) { 7487 case ACTION_RESTRICT_BACKGROUND_CHANGED: 7488 // If the uid is present in the deny list, the API will consistently 7489 // return ENABLED. To retrieve the global switch status, the system 7490 // uid is chosen because it will never be included in the deny list. 7491 final int dataSaverForSystemUid = 7492 mPolicyManager.getRestrictBackgroundStatus(Process.SYSTEM_UID); 7493 final boolean isDataSaverEnabled = (dataSaverForSystemUid 7494 != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED); 7495 mBpfNetMaps.setDataSaverEnabled(isDataSaverEnabled); 7496 break; 7497 default: 7498 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 7499 } 7500 } 7501 }; 7502 7503 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); 7504 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); 7505 7506 private static class NetworkProviderInfo { 7507 public final String name; 7508 public final Messenger messenger; 7509 private final IBinder.DeathRecipient mDeathRecipient; 7510 public final int providerId; 7511 7512 NetworkProviderInfo(String name, Messenger messenger, int providerId, 7513 @NonNull IBinder.DeathRecipient deathRecipient) { 7514 this.name = name; 7515 this.messenger = messenger; 7516 this.providerId = providerId; 7517 mDeathRecipient = deathRecipient; 7518 7519 if (mDeathRecipient == null) { 7520 throw new AssertionError("Must pass a deathRecipient"); 7521 } 7522 } 7523 7524 void connect(Context context, Handler handler) { 7525 try { 7526 messenger.getBinder().linkToDeath(mDeathRecipient, 0); 7527 } catch (RemoteException e) { 7528 mDeathRecipient.binderDied(); 7529 } 7530 } 7531 } 7532 7533 private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) { 7534 for (int i = 0; i < requests.size(); i++) { 7535 ensureNetworkRequestHasType(requests.get(i)); 7536 } 7537 } 7538 7539 private void ensureNetworkRequestHasType(NetworkRequest request) { 7540 if (request.type == NetworkRequest.Type.NONE) { 7541 throw new IllegalArgumentException( 7542 "All NetworkRequests in ConnectivityService must have a type"); 7543 } 7544 } 7545 7546 /** 7547 * Tracks info about the requester. 7548 * Also used to notice when the calling process dies so as to self-expire 7549 */ 7550 @VisibleForTesting 7551 protected class NetworkRequestInfo implements IBinder.DeathRecipient { 7552 // The requests to be satisfied in priority order. Non-multilayer requests will only have a 7553 // single NetworkRequest in mRequests. 7554 final List<NetworkRequest> mRequests; 7555 7556 // mSatisfier and mActiveRequest rely on one another therefore set them together. 7557 void setSatisfier( 7558 @Nullable final NetworkAgentInfo satisfier, 7559 @Nullable final NetworkRequest activeRequest) { 7560 mSatisfier = satisfier; 7561 mActiveRequest = activeRequest; 7562 } 7563 7564 // The network currently satisfying this NRI. Only one request in an NRI can have a 7565 // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier. 7566 @Nullable 7567 private NetworkAgentInfo mSatisfier; 7568 NetworkAgentInfo getSatisfier() { 7569 return mSatisfier; 7570 } 7571 7572 // The request in mRequests assigned to a network agent. This is null if none of the 7573 // requests in mRequests can be satisfied. This member has the constraint of only being 7574 // accessible on the handler thread. 7575 @Nullable 7576 private NetworkRequest mActiveRequest; 7577 NetworkRequest getActiveRequest() { 7578 return mActiveRequest; 7579 } 7580 7581 final PendingIntent mPendingIntent; 7582 boolean mPendingIntentSent; 7583 @Nullable 7584 final Messenger mMessenger; 7585 7586 // Information about the caller that caused this object to be created. 7587 @Nullable 7588 private final IBinder mBinder; 7589 final int mPid; 7590 final int mUid; 7591 final @NetworkCallback.Flag int mCallbackFlags; 7592 @Nullable 7593 final String mCallingAttributionTag; 7594 7595 // Counter keeping track of this NRI. 7596 final RequestInfoPerUidCounter mPerUidCounter; 7597 7598 // Effective UID of this request. This is different from mUid when a privileged process 7599 // files a request on behalf of another UID. This UID is used to determine blocked status, 7600 // UID matching, and so on. mUid above is used for permission checks and to enforce the 7601 // maximum limit of registered callbacks per UID. 7602 final int mAsUid; 7603 7604 // Flag to indicate that uid of this nri is tracked for sending blocked status callbacks. 7605 // It is always true on V+ if mMessenger != null. As such, it's not strictly necessary. 7606 // it's used only as a safeguard to avoid double counting or leaking. 7607 boolean mUidTrackedForBlockedStatus; 7608 7609 // Preference order of this request. 7610 final int mPreferenceOrder; 7611 7612 // In order to preserve the mapping of NetworkRequest-to-callback when apps register 7613 // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be 7614 // maintained for keying off of. This is only a concern when the original nri 7615 // mNetworkRequests changes which happens currently for apps that register callbacks to 7616 // track the default network. In those cases, the nri is updated to have mNetworkRequests 7617 // that match the per-app default nri that currently tracks the calling app's uid so that 7618 // callbacks are fired at the appropriate time. When the callbacks fire, 7619 // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When 7620 // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue. 7621 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 7622 @NonNull 7623 private final NetworkRequest mNetworkRequestForCallback; 7624 NetworkRequest getNetworkRequestForCallback() { 7625 return mNetworkRequestForCallback; 7626 } 7627 7628 /** 7629 * Get the list of UIDs this nri applies to. 7630 */ 7631 @NonNull 7632 Set<UidRange> getUids() { 7633 // networkCapabilities.getUids() returns a defensive copy. 7634 // multilayer requests will all have the same uids so return the first one. 7635 final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges(); 7636 return (null == uids) ? new ArraySet<>() : uids; 7637 } 7638 7639 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, 7640 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) { 7641 this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag, 7642 PREFERENCE_ORDER_INVALID); 7643 } 7644 7645 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 7646 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, 7647 @Nullable String callingAttributionTag, final int preferenceOrder) { 7648 ensureAllNetworkRequestsHaveType(r); 7649 mRequests = initializeRequests(r); 7650 mNetworkRequestForCallback = requestForCallback; 7651 mPendingIntent = pi; 7652 mMessenger = null; 7653 mBinder = null; 7654 mPid = getCallingPid(); 7655 mUid = mDeps.getCallingUid(); 7656 mAsUid = asUid; 7657 mPerUidCounter = getRequestCounter(this); 7658 /** 7659 * Location sensitive data not included in pending intent. Only included in 7660 * {@link NetworkCallback}. 7661 */ 7662 mCallbackFlags = NetworkCallback.FLAG_NONE; 7663 mCallingAttributionTag = callingAttributionTag; 7664 mPreferenceOrder = preferenceOrder; 7665 } 7666 7667 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, 7668 @Nullable final IBinder binder, 7669 @NetworkCallback.Flag int callbackFlags, 7670 @Nullable String callingAttributionTag) { 7671 this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags, 7672 callingAttributionTag); 7673 } 7674 7675 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 7676 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, 7677 @Nullable final IBinder binder, 7678 @NetworkCallback.Flag int callbackFlags, 7679 @Nullable String callingAttributionTag) { 7680 super(); 7681 ensureAllNetworkRequestsHaveType(r); 7682 mRequests = initializeRequests(r); 7683 mNetworkRequestForCallback = requestForCallback; 7684 mMessenger = m; 7685 mBinder = binder; 7686 mPid = getCallingPid(); 7687 mUid = mDeps.getCallingUid(); 7688 mAsUid = asUid; 7689 mPendingIntent = null; 7690 mPerUidCounter = getRequestCounter(this); 7691 mCallbackFlags = callbackFlags; 7692 mCallingAttributionTag = callingAttributionTag; 7693 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 7694 linkDeathRecipient(); 7695 } 7696 7697 NetworkRequestInfo(@NonNull final NetworkRequestInfo nri, 7698 @NonNull final List<NetworkRequest> r) { 7699 super(); 7700 ensureAllNetworkRequestsHaveType(r); 7701 mRequests = initializeRequests(r); 7702 mNetworkRequestForCallback = nri.getNetworkRequestForCallback(); 7703 final NetworkAgentInfo satisfier = nri.getSatisfier(); 7704 if (null != satisfier) { 7705 // If the old NRI was satisfied by an NAI, then it may have had an active request. 7706 // The active request is necessary to figure out what callbacks to send, in 7707 // particular when a network updates its capabilities. 7708 // As this code creates a new NRI with a new set of requests, figure out which of 7709 // the list of requests should be the active request. It is always the first 7710 // request of the list that can be satisfied by the satisfier since the order of 7711 // requests is a priority order. 7712 // Note even in the presence of a satisfier there may not be an active request, 7713 // when the satisfier is the no-service network. 7714 NetworkRequest activeRequest = null; 7715 for (final NetworkRequest candidate : r) { 7716 if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) { 7717 activeRequest = candidate; 7718 break; 7719 } 7720 } 7721 setSatisfier(satisfier, activeRequest); 7722 } 7723 mMessenger = nri.mMessenger; 7724 mBinder = nri.mBinder; 7725 mPid = nri.mPid; 7726 mUid = nri.mUid; 7727 mAsUid = nri.mAsUid; 7728 mPendingIntent = nri.mPendingIntent; 7729 mPerUidCounter = nri.mPerUidCounter; 7730 mCallbackFlags = nri.mCallbackFlags; 7731 mCallingAttributionTag = nri.mCallingAttributionTag; 7732 mUidTrackedForBlockedStatus = nri.mUidTrackedForBlockedStatus; 7733 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 7734 linkDeathRecipient(); 7735 } 7736 7737 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) { 7738 this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID); 7739 } 7740 7741 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 7742 final int preferenceOrder) { 7743 this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */, 7744 preferenceOrder); 7745 } 7746 7747 // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer 7748 // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning 7749 // false. 7750 boolean isBeingSatisfied() { 7751 return (null != mSatisfier && null != mActiveRequest); 7752 } 7753 7754 boolean isMultilayerRequest() { 7755 return mRequests.size() > 1; 7756 } 7757 7758 private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) { 7759 // Creating a defensive copy to prevent the sender from modifying the list being 7760 // reflected in the return value of this method. 7761 final List<NetworkRequest> tempRequests = new ArrayList<>(r); 7762 return Collections.unmodifiableList(tempRequests); 7763 } 7764 7765 void linkDeathRecipient() { 7766 if (null != mBinder) { 7767 try { 7768 mBinder.linkToDeath(this, 0); 7769 } catch (RemoteException e) { 7770 binderDied(); 7771 } 7772 } 7773 } 7774 7775 void unlinkDeathRecipient() { 7776 if (null != mBinder) { 7777 try { 7778 mBinder.unlinkToDeath(this, 0); 7779 } catch (NoSuchElementException e) { 7780 // Temporary workaround for b/194394697 pending analysis of additional logs 7781 Log.wtf(TAG, "unlinkToDeath for already unlinked NRI " + this); 7782 } 7783 } 7784 } 7785 7786 boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) { 7787 // Compare two preference orders. 7788 return mPreferenceOrder < target.mPreferenceOrder; 7789 } 7790 7791 int getPreferenceOrderForNetd() { 7792 if (mPreferenceOrder >= PREFERENCE_ORDER_NONE 7793 && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) { 7794 return mPreferenceOrder; 7795 } 7796 return PREFERENCE_ORDER_NONE; 7797 } 7798 7799 @Override 7800 public void binderDied() { 7801 // As an immutable collection, mRequests cannot change by the time the 7802 // lambda is evaluated on the handler thread so calling .get() from a binder thread 7803 // is acceptable. Use handleReleaseNetworkRequest and not directly 7804 // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case 7805 // the app already unregistered the request. 7806 mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0), 7807 mUid, false /* callOnUnavailable */)); 7808 } 7809 7810 @Override 7811 public String toString() { 7812 final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid; 7813 return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: " 7814 + (mActiveRequest == null ? null : mActiveRequest.requestId) 7815 + " callbackRequest: " 7816 + mNetworkRequestForCallback.requestId 7817 + " " + mRequests 7818 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent) 7819 + " callback flags: " + mCallbackFlags 7820 + " order: " + mPreferenceOrder 7821 + " isUidTracked: " + mUidTrackedForBlockedStatus; 7822 } 7823 } 7824 7825 // Keep backward compatibility since the ServiceSpecificException is used by 7826 // the API surface, see {@link ConnectivityManager#convertServiceException}. 7827 public static class RequestInfoPerUidCounter extends PerUidCounter { 7828 RequestInfoPerUidCounter(int maxCountPerUid) { 7829 super(maxCountPerUid); 7830 } 7831 7832 @Override 7833 public synchronized void incrementCountOrThrow(int uid) { 7834 try { 7835 super.incrementCountOrThrow(uid); 7836 } catch (IllegalStateException e) { 7837 throw new ServiceSpecificException( 7838 ConnectivityManager.Errors.TOO_MANY_REQUESTS, 7839 "Uid " + uid + " exceeded its allotted requests limit"); 7840 } 7841 } 7842 7843 @Override 7844 public synchronized void decrementCountOrThrow(int uid) { 7845 throw new UnsupportedOperationException("Use decrementCount instead."); 7846 } 7847 7848 public synchronized void decrementCount(int uid) { 7849 try { 7850 super.decrementCountOrThrow(uid); 7851 } catch (IllegalStateException e) { 7852 logwtf("Exception when decrement per uid request count: ", e); 7853 } 7854 } 7855 } 7856 7857 // This checks that the passed capabilities either do not request a 7858 // specific SSID/SignalStrength, or the calling app has permission to do so. 7859 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 7860 int callerPid, int callerUid, String callerPackageName) { 7861 if (null != nc.getSsid() && !hasSettingsPermission(callerPid, callerUid)) { 7862 throw new SecurityException("Insufficient permissions to request a specific SSID"); 7863 } 7864 7865 if (nc.hasSignalStrength() 7866 && !hasNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { 7867 throw new SecurityException( 7868 "Insufficient permissions to request a specific signal strength"); 7869 } 7870 mAppOpsManager.checkPackage(callerUid, callerPackageName); 7871 } 7872 7873 private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { 7874 final SortedSet<Integer> thresholds = new TreeSet<>(); 7875 synchronized (nai) { 7876 // mNetworkRequests may contain the same value multiple times in case of 7877 // multilayer requests. It won't matter in this case because the thresholds 7878 // will then be the same and be deduplicated as they enter the `thresholds` set. 7879 // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like. 7880 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 7881 for (final NetworkRequest req : nri.mRequests) { 7882 if (req.networkCapabilities.hasSignalStrength() 7883 && nai.satisfiesImmutableCapabilitiesOf(req)) { 7884 thresholds.add(req.networkCapabilities.getSignalStrength()); 7885 } 7886 } 7887 } 7888 } 7889 return CollectionUtils.toIntArray(new ArrayList<>(thresholds)); 7890 } 7891 7892 private void updateSignalStrengthThresholds( 7893 NetworkAgentInfo nai, String reason, NetworkRequest request) { 7894 final int[] thresholdsArray = getSignalStrengthThresholds(nai); 7895 7896 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 7897 String detail; 7898 if (request != null && request.networkCapabilities.hasSignalStrength()) { 7899 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 7900 } else { 7901 detail = reason; 7902 } 7903 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 7904 detail, Arrays.toString(thresholdsArray), nai.toShortString())); 7905 } 7906 7907 nai.onSignalStrengthThresholdsUpdated(thresholdsArray); 7908 } 7909 7910 private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 7911 if (nc == null) { 7912 return; 7913 } 7914 NetworkSpecifier ns = nc.getNetworkSpecifier(); 7915 if (ns == null) { 7916 return; 7917 } 7918 if (ns instanceof MatchAllNetworkSpecifier) { 7919 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); 7920 } 7921 } 7922 7923 private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) { 7924 ensureValidNetworkSpecifier(nc); 7925 if (nc.isPrivateDnsBroken()) { 7926 throw new IllegalArgumentException("Can't request broken private DNS"); 7927 } 7928 if (nc.hasAllowedUids()) { 7929 throw new IllegalArgumentException("Can't request access UIDs"); 7930 } 7931 } 7932 7933 private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) { 7934 ensureListenableCapabilities(nc); 7935 final String badCapability = nc.describeFirstNonRequestableCapability(); 7936 if (badCapability != null) { 7937 throw new IllegalArgumentException("Cannot request network with " + badCapability); 7938 } 7939 } 7940 7941 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 7942 @TargetApi(Build.VERSION_CODES.S) 7943 private boolean isTargetSdkAtleast(int version, int callingUid, 7944 @NonNull String callingPackageName) { 7945 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 7946 final PackageManager pm = 7947 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 7948 try { 7949 final int callingVersion = pm.getTargetSdkVersion(callingPackageName); 7950 if (callingVersion < version) return false; 7951 } catch (PackageManager.NameNotFoundException e) { } 7952 return true; 7953 } 7954 7955 @Override 7956 public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities, 7957 int reqTypeInt, Messenger messenger, int timeoutMs, final IBinder binder, 7958 int legacyType, int callbackFlags, @NonNull String callingPackageName, 7959 @Nullable String callingAttributionTag) { 7960 if (legacyType != TYPE_NONE && !hasNetworkStackPermission()) { 7961 if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(), 7962 callingPackageName)) { 7963 throw new SecurityException("Insufficient permissions to specify legacy type"); 7964 } 7965 } 7966 final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities; 7967 final int callingUid = mDeps.getCallingUid(); 7968 // Privileged callers can track the default network of another UID by passing in a UID. 7969 if (asUid != Process.INVALID_UID) { 7970 enforceSettingsPermission(); 7971 } else { 7972 asUid = callingUid; 7973 } 7974 final NetworkRequest.Type reqType; 7975 try { 7976 reqType = NetworkRequest.Type.values()[reqTypeInt]; 7977 } catch (ArrayIndexOutOfBoundsException e) { 7978 throw new IllegalArgumentException("Unsupported request type " + reqTypeInt); 7979 } 7980 switch (reqType) { 7981 case TRACK_DEFAULT: 7982 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities} 7983 // is unused and will be replaced by ones appropriate for the UID (usually, the 7984 // calling app). This allows callers to keep track of the default network. 7985 networkCapabilities = copyDefaultNetworkCapabilitiesForUid( 7986 defaultNc, asUid, callingUid, callingPackageName); 7987 enforceAccessPermission(); 7988 break; 7989 case TRACK_SYSTEM_DEFAULT: 7990 enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission(); 7991 networkCapabilities = new NetworkCapabilities(defaultNc); 7992 break; 7993 case BACKGROUND_REQUEST: 7994 enforceNetworkStackOrSettingsPermission(); 7995 // Fall-through since other checks are the same with normal requests. 7996 case REQUEST: 7997 networkCapabilities = new NetworkCapabilities(networkCapabilities); 7998 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 7999 callingAttributionTag, callingUid); 8000 // TODO: this is incorrect. We mark the request as metered or not depending on 8001 // the state of the app when the request is filed, but we never change the 8002 // request if the app changes network state. http://b/29964605 8003 enforceMeteredApnPolicy(networkCapabilities); 8004 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid); 8005 break; 8006 case LISTEN_FOR_BEST: 8007 enforceAccessPermission(); 8008 networkCapabilities = new NetworkCapabilities(networkCapabilities); 8009 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid); 8010 break; 8011 default: 8012 throw new IllegalArgumentException("Unsupported request type " + reqType); 8013 } 8014 ensureRequestableCapabilities(networkCapabilities); 8015 ensureSufficientPermissionsForRequest(networkCapabilities, 8016 Binder.getCallingPid(), callingUid, callingPackageName); 8017 8018 // Enforce FOREGROUND if the caller does not have permission to use background network. 8019 if (reqType == LISTEN_FOR_BEST) { 8020 restrictBackgroundRequestForCaller(networkCapabilities); 8021 } 8022 8023 // Set the UID range for this request to the single UID of the requester, unless the 8024 // requester has the permission to specify other UIDs. 8025 // This will overwrite any allowed UIDs in the requested capabilities. Though there 8026 // are no visible methods to set the UIDs, an app could use reflection to try and get 8027 // networks for other apps so it's essential that the UIDs are overwritten. 8028 // Also set the requester UID and package name in the request. 8029 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 8030 callingUid, callingPackageName); 8031 8032 if (timeoutMs < 0) { 8033 throw new IllegalArgumentException("Bad timeout specified"); 8034 } 8035 8036 // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were 8037 // copied from the default request above. (This is necessary to ensure, for example, that 8038 // the callback does not leak sensitive information to unprivileged apps.) Check that the 8039 // changes don't alter request matching. 8040 if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT && 8041 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) { 8042 throw new IllegalStateException( 8043 "TRACK_SYSTEM_DEFAULT capabilities don't match default request: " 8044 + networkCapabilities + " vs. " + defaultNc); 8045 } 8046 8047 final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 8048 nextNetworkRequestId(), reqType); 8049 final NetworkRequestInfo nri = getNriToRegister( 8050 asUid, networkRequest, messenger, binder, callbackFlags, 8051 callingAttributionTag); 8052 if (DBG) log("requestNetwork for " + nri); 8053 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST, nri); 8054 if (timeoutMs > 0) { 8055 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 8056 nri), timeoutMs); 8057 } 8058 return networkRequest; 8059 } 8060 8061 /** 8062 * Return the nri to be used when registering a network request. Specifically, this is used with 8063 * requests registered to track the default request. If there is currently a per-app default 8064 * tracking the app requestor, then we need to create a version of this nri that mirrors that of 8065 * the tracking per-app default so that callbacks are sent to the app requestor appropriately. 8066 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 8067 * when a privileged caller is tracking the default network for another uid. 8068 * @param nr the network request for the nri. 8069 * @param msgr the messenger for the nri. 8070 * @param binder the binder for the nri. 8071 * @param callingAttributionTag the calling attribution tag for the nri. 8072 * @return the nri to register. 8073 */ 8074 private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, 8075 @Nullable final Messenger msgr, @Nullable final IBinder binder, 8076 @NetworkCallback.Flag int callbackFlags, 8077 @Nullable String callingAttributionTag) { 8078 final List<NetworkRequest> requests; 8079 if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) { 8080 requests = copyDefaultNetworkRequestsForUid( 8081 asUid, nr.getRequestorUid(), nr.getRequestorPackageName()); 8082 } else { 8083 requests = Collections.singletonList(nr); 8084 } 8085 return new NetworkRequestInfo( 8086 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag); 8087 } 8088 8089 private boolean shouldCheckCapabilitiesDeclaration( 8090 @NonNull final NetworkCapabilities networkCapabilities, final int callingUid, 8091 @NonNull final String callingPackageName) { 8092 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 8093 // Only run the check if the change is enabled. 8094 if (!mDeps.isChangeEnabled( 8095 ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION, 8096 callingPackageName, user)) { 8097 return false; 8098 } 8099 8100 return networkCapabilities.hasCapability( 8101 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 8102 || networkCapabilities.hasCapability( 8103 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY); 8104 } 8105 8106 private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName, 8107 @NonNull final NetworkCapabilities networkCapabilities, int callingUid) { 8108 // This check is added to fix the linter error for "current min is 30", which is not going 8109 // to happen because Connectivity service always run in S+. 8110 if (!mDeps.isAtLeastS()) { 8111 Log.wtf(TAG, "Connectivity service should always run in at least SDK S"); 8112 return; 8113 } 8114 ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities; 8115 final long ident = Binder.clearCallingIdentity(); 8116 try { 8117 synchronized (mSelfCertifiedCapabilityCache) { 8118 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get( 8119 callerPackageName); 8120 if (applicationNetworkCapabilities == null) { 8121 final PackageManager packageManager = 8122 mContext.createContextAsUser(UserHandle.getUserHandleForUid( 8123 callingUid), 0 /* flags */).getPackageManager(); 8124 final PackageManager.Property networkSliceProperty = packageManager.getProperty( 8125 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 8126 callerPackageName 8127 ); 8128 final XmlResourceParser parser = packageManager 8129 .getResourcesForApplication(callerPackageName) 8130 .getXml(networkSliceProperty.getResourceId()); 8131 applicationNetworkCapabilities = 8132 ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser); 8133 mSelfCertifiedCapabilityCache.put(callerPackageName, 8134 applicationNetworkCapabilities); 8135 } 8136 8137 } 8138 } catch (PackageManager.NameNotFoundException ne) { 8139 throw new SecurityException( 8140 "Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES 8141 + " property"); 8142 } catch (XmlPullParserException | IOException | InvalidTagException e) { 8143 throw new SecurityException(e.getMessage()); 8144 } finally { 8145 Binder.restoreCallingIdentity(ident); 8146 } 8147 8148 applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared( 8149 networkCapabilities); 8150 } 8151 8152 private boolean canRequestRestrictedNetworkDueToCarrierPrivileges( 8153 NetworkCapabilities networkCapabilities, int callingUid) { 8154 if (mRequestRestrictedWifiEnabled) { 8155 // For U+ devices, callers with carrier privilege could request restricted networks 8156 // with CBS capabilities, or any restricted WiFi networks. 8157 return ((networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS) 8158 || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) 8159 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)); 8160 } else { 8161 // For T+ devices, callers with carrier privilege could request with CBS 8162 // capabilities. 8163 return (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS) 8164 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)); 8165 } 8166 } 8167 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, 8168 String callingPackageName, String callingAttributionTag, final int callingUid) { 8169 if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid, 8170 callingPackageName)) { 8171 enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities, 8172 callingUid); 8173 } 8174 if (!networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 8175 if (!canRequestRestrictedNetworkDueToCarrierPrivileges( 8176 networkCapabilities, callingUid)) { 8177 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 8178 } 8179 } else { 8180 enforceChangePermission(callingPackageName, callingAttributionTag); 8181 } 8182 } 8183 8184 @Override 8185 public boolean requestBandwidthUpdate(Network network) { 8186 enforceAccessPermission(); 8187 NetworkAgentInfo nai = null; 8188 if (network == null) { 8189 return false; 8190 } 8191 synchronized (mNetworkForNetId) { 8192 nai = mNetworkForNetId.get(network.getNetId()); 8193 } 8194 if (nai != null) { 8195 nai.onBandwidthUpdateRequested(); 8196 synchronized (mBandwidthRequests) { 8197 final int uid = mDeps.getCallingUid(); 8198 Integer uidReqs = mBandwidthRequests.get(uid); 8199 if (uidReqs == null) { 8200 uidReqs = 0; 8201 } 8202 mBandwidthRequests.put(uid, ++uidReqs); 8203 } 8204 return true; 8205 } 8206 return false; 8207 } 8208 8209 private boolean isSystem(int uid) { 8210 return uid < Process.FIRST_APPLICATION_UID; 8211 } 8212 8213 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 8214 final int uid = mDeps.getCallingUid(); 8215 if (isSystem(uid)) { 8216 // Exemption for system uid. 8217 return; 8218 } 8219 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 8220 // Policy already enforced. 8221 return; 8222 } 8223 if (mDeps.isAtLeastV()) { 8224 if (mBpfNetMaps.isUidRestrictedOnMeteredNetworks(uid)) { 8225 // If UID is restricted, don't allow them to bring up metered APNs. 8226 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 8227 } 8228 return; 8229 } 8230 final long ident = Binder.clearCallingIdentity(); 8231 try { 8232 if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) { 8233 // If UID is restricted, don't allow them to bring up metered APNs. 8234 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 8235 } 8236 } finally { 8237 Binder.restoreCallingIdentity(ident); 8238 } 8239 } 8240 8241 @Override 8242 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 8243 PendingIntent operation, @NonNull String callingPackageName, 8244 @Nullable String callingAttributionTag) { 8245 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8246 final int callingUid = mDeps.getCallingUid(); 8247 networkCapabilities = new NetworkCapabilities(networkCapabilities); 8248 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 8249 callingAttributionTag, callingUid); 8250 enforceMeteredApnPolicy(networkCapabilities); 8251 ensureRequestableCapabilities(networkCapabilities); 8252 ensureSufficientPermissionsForRequest(networkCapabilities, 8253 Binder.getCallingPid(), callingUid, callingPackageName); 8254 restrictRequestNetworkCapabilitiesForCaller( 8255 networkCapabilities, callingUid, callingPackageName); 8256 8257 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 8258 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 8259 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 8260 callingAttributionTag); 8261 if (DBG) log("pendingRequest for " + nri); 8262 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, nri); 8263 return networkRequest; 8264 } 8265 8266 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 8267 mHandler.sendMessageDelayed( 8268 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 8269 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 8270 } 8271 8272 @Override 8273 public void releasePendingNetworkRequest(PendingIntent operation) { 8274 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8275 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 8276 mDeps.getCallingUid(), 0, operation)); 8277 } 8278 8279 // In order to implement the compatibility measure for pre-M apps that call 8280 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 8281 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 8282 // This ensures it has permission to do so. 8283 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 8284 if (nc == null) { 8285 return false; 8286 } 8287 int[] transportTypes = nc.getTransportTypes(); 8288 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 8289 return false; 8290 } 8291 try { 8292 mContext.enforceCallingOrSelfPermission( 8293 android.Manifest.permission.ACCESS_WIFI_STATE, 8294 "ConnectivityService"); 8295 } catch (SecurityException e) { 8296 return false; 8297 } 8298 return true; 8299 } 8300 8301 private boolean isAppRequest(NetworkRequestInfo nri) { 8302 return nri.mMessenger != null || nri.mPendingIntent != null; 8303 } 8304 8305 private void trackUidAndMaybePostCurrentBlockedReason(final NetworkRequestInfo nri) { 8306 if (!isAppRequest(nri)) { 8307 Log.wtf(TAG, "trackUidAndMaybePostCurrentBlockedReason is called for non app" 8308 + "request: " + nri); 8309 return; 8310 } 8311 nri.mPerUidCounter.incrementCountOrThrow(nri.mUid); 8312 8313 // If nri.mMessenger is null, this nri does not have NetworkCallback so ConnectivityService 8314 // does not need to send onBlockedStatusChanged callback for this uid and does not need to 8315 // track the uid in mBlockedStatusTrackingUids 8316 if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) { 8317 return; 8318 } 8319 if (nri.mUidTrackedForBlockedStatus) { 8320 Log.wtf(TAG, "Nri is already tracked for sending blocked status: " + nri); 8321 return; 8322 } 8323 nri.mUidTrackedForBlockedStatus = true; 8324 synchronized (mBlockedStatusTrackingUids) { 8325 final int uid = nri.mAsUid; 8326 final int count = mBlockedStatusTrackingUids.get(uid, 0); 8327 if (count == 0) { 8328 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 8329 List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))))); 8330 } 8331 mBlockedStatusTrackingUids.put(uid, count + 1); 8332 } 8333 } 8334 8335 private void trackUidAndRegisterNetworkRequest(final int event, NetworkRequestInfo nri) { 8336 // Post the update of the UID's blocked reasons before posting the message that registers 8337 // the callback. This is necessary because if the callback immediately matches a request, 8338 // the onBlockedStatusChanged must be called with the correct blocked reasons. 8339 // Also, once trackUidAndMaybePostCurrentBlockedReason is called, the register network 8340 // request event must be posted, because otherwise the counter for uid will never be 8341 // decremented. 8342 trackUidAndMaybePostCurrentBlockedReason(nri); 8343 mHandler.sendMessage(mHandler.obtainMessage(event, nri)); 8344 } 8345 8346 private void maybeUntrackUidAndClearBlockedReasons(final NetworkRequestInfo nri) { 8347 if (!isAppRequest(nri)) { 8348 // Not an app request. 8349 return; 8350 } 8351 nri.mPerUidCounter.decrementCount(nri.mUid); 8352 8353 if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) { 8354 return; 8355 } 8356 if (!nri.mUidTrackedForBlockedStatus) { 8357 Log.wtf(TAG, "Nri is not tracked for sending blocked status: " + nri); 8358 return; 8359 } 8360 nri.mUidTrackedForBlockedStatus = false; 8361 synchronized (mBlockedStatusTrackingUids) { 8362 final int count = mBlockedStatusTrackingUids.get(nri.mAsUid); 8363 if (count > 1) { 8364 mBlockedStatusTrackingUids.put(nri.mAsUid, count - 1); 8365 } else { 8366 mBlockedStatusTrackingUids.delete(nri.mAsUid); 8367 mUidBlockedReasons.delete(nri.mAsUid); 8368 } 8369 } 8370 } 8371 8372 @Override 8373 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 8374 Messenger messenger, IBinder binder, 8375 @NetworkCallback.Flag int callbackFlags, 8376 @NonNull String callingPackageName, @NonNull String callingAttributionTag) { 8377 final int callingUid = mDeps.getCallingUid(); 8378 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 8379 enforceAccessPermission(); 8380 } 8381 8382 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 8383 ensureSufficientPermissionsForRequest(networkCapabilities, 8384 Binder.getCallingPid(), callingUid, callingPackageName); 8385 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 8386 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 8387 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 8388 // onLost and onAvailable callbacks when networks move in and out of the background. 8389 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 8390 // can't request networks. 8391 restrictBackgroundRequestForCaller(nc); 8392 ensureListenableCapabilities(nc); 8393 8394 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 8395 NetworkRequest.Type.LISTEN); 8396 NetworkRequestInfo nri = 8397 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags, 8398 callingAttributionTag); 8399 if (VDBG) log("listenForNetwork for " + nri); 8400 8401 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER, nri); 8402 return networkRequest; 8403 } 8404 8405 @Override 8406 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 8407 PendingIntent operation, @NonNull String callingPackageName, 8408 @Nullable String callingAttributionTag) { 8409 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8410 final int callingUid = mDeps.getCallingUid(); 8411 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 8412 enforceAccessPermission(); 8413 } 8414 ensureListenableCapabilities(networkCapabilities); 8415 ensureSufficientPermissionsForRequest(networkCapabilities, 8416 Binder.getCallingPid(), callingUid, callingPackageName); 8417 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 8418 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 8419 8420 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 8421 NetworkRequest.Type.LISTEN); 8422 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 8423 callingAttributionTag); 8424 if (VDBG) log("pendingListenForNetwork for " + nri); 8425 8426 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri); 8427 } 8428 8429 /** Returns the next Network provider ID. */ 8430 public final int nextNetworkProviderId() { 8431 return mNextNetworkProviderId.getAndIncrement(); 8432 } 8433 8434 @Override 8435 public void releaseNetworkRequest(NetworkRequest networkRequest) { 8436 ensureNetworkRequestHasType(networkRequest); 8437 mHandler.sendMessage(mHandler.obtainMessage( 8438 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest)); 8439 } 8440 8441 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { 8442 if (mNetworkProviderInfos.containsKey(npi.messenger)) { 8443 // Avoid creating duplicates. even if an app makes a direct AIDL call. 8444 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, 8445 // as that will throw if a duplicate provider is registered. 8446 loge("Attempt to register existing NetworkProviderInfo " 8447 + mNetworkProviderInfos.get(npi.messenger).name); 8448 return; 8449 } 8450 8451 if (DBG) log("Got NetworkProvider Messenger for " + npi.name); 8452 mNetworkProviderInfos.put(npi.messenger, npi); 8453 npi.connect(mContext, mTrackerHandler); 8454 } 8455 8456 @Override 8457 public int registerNetworkProvider(Messenger messenger, String name) { 8458 enforceNetworkFactoryOrSettingsPermission(); 8459 Objects.requireNonNull(messenger, "messenger must be non-null"); 8460 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, 8461 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); 8462 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); 8463 return npi.providerId; 8464 } 8465 8466 @Override 8467 public void unregisterNetworkProvider(Messenger messenger) { 8468 enforceNetworkFactoryOrSettingsPermission(); 8469 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); 8470 } 8471 8472 @Override 8473 public void offerNetwork(final int providerId, 8474 @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, 8475 @NonNull final INetworkOfferCallback callback) { 8476 Objects.requireNonNull(score); 8477 Objects.requireNonNull(caps); 8478 Objects.requireNonNull(callback); 8479 final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 8480 final NetworkOffer offer = new NetworkOffer( 8481 FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi), 8482 caps, callback, providerId); 8483 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer)); 8484 } 8485 8486 private void updateOfferScore(final NetworkOffer offer) { 8487 final boolean yieldToBadWiFi = 8488 offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 8489 final NetworkOffer newOffer = new NetworkOffer( 8490 offer.score.withYieldToBadWiFi(yieldToBadWiFi), 8491 offer.caps, offer.callback, offer.providerId); 8492 if (offer.equals(newOffer)) return; 8493 handleRegisterNetworkOffer(newOffer); 8494 } 8495 8496 @Override 8497 public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { 8498 Objects.requireNonNull(callback); 8499 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback)); 8500 } 8501 8502 private void handleUnregisterNetworkProvider(Messenger messenger) { 8503 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); 8504 if (npi == null) { 8505 loge("Failed to find Messenger in unregisterNetworkProvider"); 8506 return; 8507 } 8508 // Unregister all the offers from this provider 8509 final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>(); 8510 for (final NetworkOfferInfo noi : mNetworkOffers) { 8511 if (noi.offer.providerId == npi.providerId) { 8512 // Can't call handleUnregisterNetworkOffer here because iteration is in progress 8513 toRemove.add(noi); 8514 } 8515 } 8516 for (final NetworkOfferInfo noi : toRemove) { 8517 handleUnregisterNetworkOffer(noi); 8518 } 8519 if (DBG) log("unregisterNetworkProvider for " + npi.name); 8520 } 8521 8522 @Override 8523 public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) { 8524 if (request.hasTransport(TRANSPORT_TEST)) { 8525 enforceNetworkFactoryOrTestNetworksPermission(); 8526 } else { 8527 enforceNetworkFactoryPermission(); 8528 } 8529 final NetworkRequestInfo nri = mNetworkRequests.get(request); 8530 if (nri != null) { 8531 // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests. 8532 ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable"); 8533 mHandler.post(() -> handleReleaseNetworkRequest( 8534 nri.mRequests.get(0), mDeps.getCallingUid(), true)); 8535 } 8536 } 8537 8538 // NOTE: Accessed on multiple threads, must be synchronized on itself. 8539 @GuardedBy("mNetworkForNetId") 8540 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); 8541 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 8542 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so 8543 // there may not be a strict 1:1 correlation between the two. 8544 private final NetIdManager mNetIdManager; 8545 8546 // Tracks all NetworkAgents that are currently registered. 8547 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 8548 private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>(); 8549 8550 // UID ranges for users that are currently blocked by VPNs. 8551 // This array is accessed and iterated on multiple threads without holding locks, so its 8552 // contents must never be mutated. When the ranges change, the array is replaced with a new one 8553 // (on the handler thread). 8554 private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>(); 8555 8556 // Must only be accessed on the handler thread 8557 @NonNull 8558 private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>(); 8559 8560 @GuardedBy("mBlockedAppUids") 8561 private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 8562 8563 // Current OEM network preferences. This object must only be written to on the handler thread. 8564 // Since it is immutable and always non-null, other threads may read it if they only care 8565 // about seeing a consistent object but not that it is current. 8566 @NonNull 8567 private OemNetworkPreferences mOemNetworkPreferences = 8568 new OemNetworkPreferences.Builder().build(); 8569 // Current per-profile network preferences. This object follows the same threading rules as 8570 // the OEM network preferences above. 8571 @NonNull 8572 private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> 8573 mProfileNetworkPreferences = new NetworkPreferenceList<>(); 8574 8575 // Current VPN network preferences. This object follows the same threading rules as the OEM 8576 // network preferences above. 8577 @NonNull 8578 private NetworkPreferenceList<String, VpnNetworkPreferenceInfo> 8579 mVpnNetworkPreferences = new NetworkPreferenceList<>(); 8580 8581 // A set of UIDs that should use mobile data preferentially if available. This object follows 8582 // the same threading rules as the OEM network preferences above. 8583 @NonNull 8584 private Set<Integer> mMobileDataPreferredUids = new ArraySet<>(); 8585 8586 // OemNetworkPreferences activity String log entries. 8587 private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20; 8588 @NonNull 8589 private final LocalLog mOemNetworkPreferencesLogs = 8590 new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS); 8591 8592 /** 8593 * Determine whether a given package has a mapping in the current OemNetworkPreferences. 8594 * @param packageName the package name to check existence of a mapping for. 8595 * @return true if a mapping exists, false otherwise 8596 */ 8597 private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) { 8598 return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName); 8599 } 8600 8601 // The always-on request for an Internet-capable network that apps without a specific default 8602 // fall back to. 8603 @VisibleForTesting 8604 @NonNull 8605 final NetworkRequestInfo mDefaultRequest; 8606 // Collection of NetworkRequestInfo's used for default networks. 8607 @VisibleForTesting 8608 @NonNull 8609 final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>(); 8610 8611 private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) { 8612 return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri); 8613 } 8614 8615 /** 8616 * Return the default network request currently tracking the given uid. 8617 * @param uid the uid to check. 8618 * @return the NetworkRequestInfo tracking the given uid. 8619 */ 8620 @NonNull 8621 private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) { 8622 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 8623 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 8624 // Checking the first request is sufficient as only multilayer requests will have more 8625 // than one request and for multilayer, all requests will track the same uids. 8626 if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) { 8627 // Find out the highest priority request. 8628 if (nri.hasHigherOrderThan(highestPriorityNri)) { 8629 highestPriorityNri = nri; 8630 } 8631 } 8632 } 8633 return highestPriorityNri; 8634 } 8635 8636 /** 8637 * Get a copy of the network requests of the default request that is currently tracking the 8638 * given uid. 8639 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 8640 * when a privileged caller is tracking the default network for another uid. 8641 * @param requestorUid the uid to check the default for. 8642 * @param requestorPackageName the requestor's package name. 8643 * @return a copy of the default's NetworkRequest that is tracking the given uid. 8644 */ 8645 @NonNull 8646 private List<NetworkRequest> copyDefaultNetworkRequestsForUid( 8647 final int asUid, final int requestorUid, @NonNull final String requestorPackageName) { 8648 return copyNetworkRequestsForUid( 8649 getDefaultRequestTrackingUid(asUid).mRequests, 8650 asUid, requestorUid, requestorPackageName); 8651 } 8652 8653 /** 8654 * Copy the given nri's NetworkRequest collection. 8655 * @param requestsToCopy the NetworkRequest collection to be copied. 8656 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 8657 * when a privileged caller is tracking the default network for another uid. 8658 * @param requestorUid the uid to set on the copied collection. 8659 * @param requestorPackageName the package name to set on the copied collection. 8660 * @return the copied NetworkRequest collection. 8661 */ 8662 @NonNull 8663 private List<NetworkRequest> copyNetworkRequestsForUid( 8664 @NonNull final List<NetworkRequest> requestsToCopy, final int asUid, 8665 final int requestorUid, @NonNull final String requestorPackageName) { 8666 final List<NetworkRequest> requests = new ArrayList<>(); 8667 for (final NetworkRequest nr : requestsToCopy) { 8668 requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid( 8669 nr.networkCapabilities, asUid, requestorUid, requestorPackageName), 8670 nr.legacyType, nextNetworkRequestId(), nr.type)); 8671 } 8672 return requests; 8673 } 8674 8675 @NonNull 8676 private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid( 8677 @NonNull final NetworkCapabilities netCapToCopy, final int asUid, 8678 final int requestorUid, @NonNull final String requestorPackageName) { 8679 // These capabilities are for a TRACK_DEFAULT callback, so: 8680 // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between 8681 // mDefaultRequest and a per-UID default request. 8682 // TODO: stop depending on the fact that these two unrelated things happen to be the same 8683 // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will 8684 // not do this in the case of a privileged application. 8685 final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy); 8686 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 8687 netCap.setSingleUid(asUid); 8688 restrictRequestUidsForCallerAndSetRequestorInfo( 8689 netCap, requestorUid, requestorPackageName); 8690 return netCap; 8691 } 8692 8693 /** 8694 * Get the nri that is currently being tracked for callbacks by per-app defaults. 8695 * @param nr the network request to check for equality against. 8696 * @return the nri if one exists, null otherwise. 8697 */ 8698 @Nullable 8699 private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) { 8700 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 8701 if (nri.getNetworkRequestForCallback().equals(nr)) { 8702 return nri; 8703 } 8704 } 8705 return null; 8706 } 8707 8708 /** 8709 * Check if an nri is currently being managed by per-app default networking. 8710 * @param nri the nri to check. 8711 * @return true if this nri is currently being managed by per-app default networking. 8712 */ 8713 private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) { 8714 // nri.mRequests.get(0) is only different from the original request filed in 8715 // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default 8716 // functionality therefore if these two don't match, it means this particular nri is 8717 // currently being managed by a per-app default. 8718 return nri.getNetworkRequestForCallback() != nri.mRequests.get(0); 8719 } 8720 8721 /** 8722 * Determine if an nri is a managed default request that disallows default networking. 8723 * @param nri the request to evaluate 8724 * @return true if device-default networking is disallowed 8725 */ 8726 private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) { 8727 // Check if this nri is a managed default that supports the default network at its 8728 // lowest priority request. 8729 final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0); 8730 final NetworkCapabilities lowestPriorityNetCap = 8731 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities; 8732 return isPerAppDefaultRequest(nri) 8733 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities( 8734 lowestPriorityNetCap)); 8735 } 8736 8737 // Request used to optionally keep mobile data active even when higher 8738 // priority networks like Wi-Fi are active. 8739 private final NetworkRequest mDefaultMobileDataRequest; 8740 8741 // Request used to optionally keep wifi data active even when higher 8742 // priority networks like ethernet are active. 8743 private final NetworkRequest mDefaultWifiRequest; 8744 8745 // Request used to optionally keep vehicle internal network always active 8746 private final NetworkRequest mDefaultVehicleRequest; 8747 8748 // Sentinel NAI used to direct apps with default networks that should have no connectivity to a 8749 // network with no service. This NAI should never be matched against, nor should any public API 8750 // ever return the associated network. For this reason, this NAI is not in the list of available 8751 // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device 8752 // default requests that don't support using the device default network which will ultimately 8753 // allow ConnectivityService to use this no-service network when calling makeDefaultForApps(). 8754 @VisibleForTesting 8755 final NetworkAgentInfo mNoServiceNetwork; 8756 8757 // The NetworkAgentInfo currently satisfying the default request, if any. 8758 private NetworkAgentInfo getDefaultNetwork() { 8759 return mDefaultRequest.mSatisfier; 8760 } 8761 8762 private NetworkAgentInfo getDefaultNetworkForUid(final int uid) { 8763 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 8764 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 8765 // Currently, all network requests will have the same uids therefore checking the first 8766 // one is sufficient. If/when uids are tracked at the nri level, this can change. 8767 final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges(); 8768 if (null == uids) { 8769 continue; 8770 } 8771 for (final UidRange range : uids) { 8772 if (range.contains(uid)) { 8773 if (nri.hasHigherOrderThan(highestPriorityNri)) { 8774 highestPriorityNri = nri; 8775 } 8776 } 8777 } 8778 } 8779 if (!highestPriorityNri.isBeingSatisfied()) return null; 8780 return highestPriorityNri.getSatisfier(); 8781 } 8782 8783 @Nullable 8784 private Network getNetwork(@Nullable NetworkAgentInfo nai) { 8785 return nai != null ? nai.network : null; 8786 } 8787 8788 private void ensureRunningOnConnectivityServiceThread() { 8789 if (mHandler.getLooper().getThread() != Thread.currentThread()) { 8790 throw new IllegalStateException( 8791 "Not running on ConnectivityService thread: " 8792 + Thread.currentThread().getName()); 8793 } 8794 } 8795 8796 @VisibleForTesting 8797 protected boolean isDefaultNetwork(NetworkAgentInfo nai) { 8798 return nai == getDefaultNetwork(); 8799 } 8800 8801 /** 8802 * Returns whether local agents are supported on this device. 8803 * 8804 * Local agents are supported from U on TVs, and from V on all devices. 8805 */ 8806 @VisibleForTesting 8807 public boolean areLocalAgentsSupported() { 8808 final PackageManager pm = mContext.getPackageManager(); 8809 // Local agents are supported starting on U on TVs and on V on everything else. 8810 return mDeps.isAtLeastV() || (mDeps.isAtLeastU() && pm.hasSystemFeature(FEATURE_LEANBACK)); 8811 } 8812 8813 /** 8814 * Register a new agent with ConnectivityService to handle a network. 8815 * 8816 * @param na a reference for ConnectivityService to contact the agent asynchronously. 8817 * @param networkInfo the initial info associated with this network. It can be updated later : 8818 * see {@link #updateNetworkInfo}. 8819 * @param linkProperties the initial link properties of this network. They can be updated 8820 * later : see {@link #updateLinkProperties}. 8821 * @param networkCapabilities the initial capabilites of this network. They can be updated 8822 * later : see {@link #updateCapabilities}. 8823 * @param initialScore the initial score of the network. See {@link NetworkAgentInfo#getScore}. 8824 * @param localNetworkConfig config about this local network, or null if not a local network 8825 * @param networkAgentConfig metadata about the network. This is never updated. 8826 * @param providerId the ID of the provider owning this NetworkAgent. 8827 * @return the network created for this agent. 8828 */ 8829 public Network registerNetworkAgent(INetworkAgent na, 8830 NetworkInfo networkInfo, 8831 LinkProperties linkProperties, 8832 NetworkCapabilities networkCapabilities, 8833 @NonNull NetworkScore initialScore, 8834 @Nullable LocalNetworkConfig localNetworkConfig, 8835 NetworkAgentConfig networkAgentConfig, 8836 int providerId) { 8837 Objects.requireNonNull(networkInfo, "networkInfo must not be null"); 8838 Objects.requireNonNull(linkProperties, "linkProperties must not be null"); 8839 Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); 8840 Objects.requireNonNull(initialScore, "initialScore must not be null"); 8841 Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); 8842 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 8843 enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS); 8844 } else { 8845 enforceNetworkFactoryPermission(); 8846 } 8847 final boolean hasLocalCap = 8848 networkCapabilities.hasCapability(NET_CAPABILITY_LOCAL_NETWORK); 8849 if (hasLocalCap && !areLocalAgentsSupported()) { 8850 // Before U, netd doesn't support PHYSICAL_LOCAL networks so this can't work. 8851 throw new IllegalArgumentException("Local agents are not supported in this version"); 8852 } 8853 final boolean hasLocalNetworkConfig = null != localNetworkConfig; 8854 if (hasLocalCap != hasLocalNetworkConfig) { 8855 throw new IllegalArgumentException(null != localNetworkConfig 8856 ? "Only local network agents can have a LocalNetworkConfig" 8857 : "Local network agents must have a LocalNetworkConfig" 8858 ); 8859 } 8860 8861 final int uid = mDeps.getCallingUid(); 8862 final long token = Binder.clearCallingIdentity(); 8863 try { 8864 return registerNetworkAgentInternal(na, networkInfo, linkProperties, 8865 networkCapabilities, initialScore, networkAgentConfig, localNetworkConfig, 8866 providerId, uid); 8867 } finally { 8868 Binder.restoreCallingIdentity(token); 8869 } 8870 } 8871 8872 private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, 8873 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 8874 NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, 8875 @Nullable LocalNetworkConfig localNetworkConfig, int providerId, 8876 int uid) { 8877 8878 // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them 8879 // and mutate them at any time. 8880 final NetworkInfo niCopy = new NetworkInfo(networkInfo); 8881 final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities); 8882 final LinkProperties lpCopy = new LinkProperties(linkProperties); 8883 // No need to copy |localNetworkConfiguration| as it is immutable. 8884 8885 // At this point the capabilities/properties are untrusted and unverified, e.g. checks that 8886 // the capabilities' access UIDs comply with security limitations. They will be sanitized 8887 // as the NAI registration finishes, in handleRegisterNetworkAgent(). This is 8888 // because some of the checks must happen on the handler thread. 8889 final NetworkAgentInfo nai = new NetworkAgentInfo(na, 8890 new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy, 8891 localNetworkConfig, currentScore, mContext, mTrackerHandler, 8892 new NetworkAgentConfig(networkAgentConfig), this, mNetd, mDnsResolver, providerId, 8893 uid, mLingerDelayMs, mQosCallbackTracker, mDeps); 8894 8895 final String extraInfo = niCopy.getExtraInfo(); 8896 final String name = TextUtils.isEmpty(extraInfo) 8897 ? nai.networkCapabilities.getSsid() : extraInfo; 8898 if (DBG) log("registerNetworkAgent " + nai); 8899 mDeps.getNetworkStack().makeNetworkMonitor( 8900 nai.network, name, new NetworkMonitorCallbacks(nai)); 8901 // NetworkAgentInfo registration will finish when the NetworkMonitor is created. 8902 // If the network disconnects or sends any other event before that, messages are deferred by 8903 // NetworkAgent until nai.connect(), which will be called when finalizing the 8904 // registration. 8905 return nai.network; 8906 } 8907 8908 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { 8909 if (VDBG) log("Network Monitor created for " + nai); 8910 // Store a copy of the declared capabilities. 8911 nai.setDeclaredCapabilities(nai.networkCapabilities); 8912 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said. 8913 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, 8914 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator))); 8915 processLinkPropertiesFromAgent(nai, nai.linkProperties); 8916 8917 nai.onNetworkMonitorCreated(networkMonitor); 8918 8919 mNetworkAgentInfos.add(nai); 8920 synchronized (mNetworkForNetId) { 8921 mNetworkForNetId.put(nai.network.getNetId(), nai); 8922 } 8923 8924 try { 8925 networkMonitor.start(); 8926 } catch (RemoteException e) { 8927 e.rethrowAsRuntimeException(); 8928 } 8929 8930 if (nai.isLocalNetwork()) { 8931 handleUpdateLocalNetworkConfig(nai, null /* oldConfig */, nai.localNetworkConfig); 8932 } 8933 nai.notifyRegistered(); 8934 NetworkInfo networkInfo = nai.networkInfo; 8935 updateNetworkInfo(nai, networkInfo); 8936 updateVpnUids(nai, null, nai.networkCapabilities); 8937 } 8938 8939 private class NetworkOfferInfo implements IBinder.DeathRecipient { 8940 @NonNull public final NetworkOffer offer; 8941 8942 NetworkOfferInfo(@NonNull final NetworkOffer offer) { 8943 this.offer = offer; 8944 } 8945 8946 @Override 8947 public void binderDied() { 8948 mHandler.post(() -> handleUnregisterNetworkOffer(this)); 8949 } 8950 } 8951 8952 private boolean isNetworkProviderWithIdRegistered(final int providerId) { 8953 for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 8954 if (npi.providerId == providerId) return true; 8955 } 8956 return false; 8957 } 8958 8959 /** 8960 * Register or update a network offer. 8961 * @param newOffer The new offer. If the callback member is the same as an existing 8962 * offer, it is an update of that offer. 8963 */ 8964 // TODO : rename this to handleRegisterOrUpdateNetworkOffer 8965 private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) { 8966 ensureRunningOnConnectivityServiceThread(); 8967 if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) { 8968 // This may actually happen if a provider updates its score or registers and then 8969 // immediately unregisters. The offer would still be in the handler queue, but the 8970 // provider would have been removed. 8971 if (DBG) log("Received offer from an unregistered provider"); 8972 return; 8973 } 8974 final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback); 8975 if (null != existingOffer) { 8976 handleUnregisterNetworkOffer(existingOffer); 8977 newOffer.migrateFrom(existingOffer.offer); 8978 if (DBG) { 8979 // handleUnregisterNetworkOffer has already logged the old offer 8980 log("update offer from providerId " + newOffer.providerId + " new : " + newOffer); 8981 } 8982 } else { 8983 if (DBG) { 8984 log("register offer from providerId " + newOffer.providerId + " : " + newOffer); 8985 } 8986 } 8987 final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer); 8988 try { 8989 noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */); 8990 } catch (RemoteException e) { 8991 noi.binderDied(); 8992 return; 8993 } 8994 mNetworkOffers.add(noi); 8995 issueNetworkNeeds(noi); 8996 } 8997 8998 private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) { 8999 ensureRunningOnConnectivityServiceThread(); 9000 if (DBG) { 9001 log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer); 9002 } 9003 9004 // If the provider removes the offer and dies immediately afterwards this 9005 // function may be called twice in a row, but the array will no longer contain 9006 // the offer. 9007 if (!mNetworkOffers.remove(noi)) return; 9008 noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */); 9009 } 9010 9011 @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback( 9012 @NonNull final INetworkOfferCallback callback) { 9013 ensureRunningOnConnectivityServiceThread(); 9014 for (final NetworkOfferInfo noi : mNetworkOffers) { 9015 if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi; 9016 } 9017 return null; 9018 } 9019 9020 /** 9021 * Called when receiving LinkProperties directly from a NetworkAgent. 9022 * Stores into |nai| any data coming from the agent that might also be written to the network's 9023 * LinkProperties by ConnectivityService itself. This ensures that the data provided by the 9024 * agent is not lost when updateLinkProperties is called. 9025 * This method should never alter the agent's LinkProperties, only store data in |nai|. 9026 */ 9027 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { 9028 lp.ensureDirectlyConnectedRoutes(); 9029 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix()); 9030 nai.networkAgentPortalData = lp.getCaptivePortalData(); 9031 } 9032 9033 private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, 9034 @Nullable LinkProperties oldLp) { 9035 int netId = networkAgent.network.getNetId(); 9036 9037 // The NetworkAgent does not know whether clatd is running on its network or not, or whether 9038 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure 9039 // the LinkProperties for the network are accurate. 9040 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 9041 9042 updateInterfaces(newLp, oldLp, netId, networkAgent); 9043 9044 // update filtering rules, need to happen after the interface update so netd knows about the 9045 // new interface (the interface name -> index map becomes initialized) 9046 updateVpnFiltering(newLp, oldLp, networkAgent); 9047 9048 updateIngressToVpnAddressFiltering(newLp, oldLp, networkAgent); 9049 9050 updateMtu(newLp, oldLp); 9051 // TODO - figure out what to do for clat 9052 // for (LinkProperties lp : newLp.getStackedLinks()) { 9053 // updateMtu(lp, null); 9054 // } 9055 if (isDefaultNetwork(networkAgent)) { 9056 mProxyTracker.updateDefaultNetworkProxyPortForPAC(newLp, null); 9057 updateTcpBufferSizes(newLp.getTcpBufferSizes()); 9058 } 9059 9060 updateRoutes(newLp, oldLp, netId); 9061 updateDnses(newLp, oldLp, netId); 9062 // Make sure LinkProperties represents the latest private DNS status. 9063 // This does not need to be done before updateDnses because the 9064 // LinkProperties are not the source of the private DNS configuration. 9065 // updateDnses will fetch the private DNS configuration from DnsManager. 9066 mDnsManager.updatePrivateDnsStatus(netId, newLp); 9067 9068 if (isDefaultNetwork(networkAgent)) { 9069 mProxyTracker.setDefaultProxy(newLp.getHttpProxy()); 9070 } else if (networkAgent.everConnected()) { 9071 updateProxy(newLp, oldLp); 9072 } 9073 9074 updateWakeOnLan(newLp); 9075 9076 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo. 9077 // It is not always contained in the LinkProperties sent from NetworkAgents, and if it 9078 // does, it needs to be merged here. 9079 newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData, 9080 networkAgent.capportApiData)); 9081 9082 // TODO - move this check to cover the whole function 9083 if (!Objects.equals(newLp, oldLp)) { 9084 synchronized (networkAgent) { 9085 networkAgent.linkProperties = newLp; 9086 } 9087 // Start or stop DNS64 detection and 464xlat according to network state. 9088 networkAgent.clatd.update(); 9089 // Notify NSS when relevant events happened. Currently, NSS only cares about 9090 // interface changed to update clat interfaces accounting. 9091 final boolean interfacesChanged = oldLp == null 9092 || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames()); 9093 if (interfacesChanged) { 9094 notifyIfacesChangedForNetworkStats(); 9095 } 9096 networkAgent.networkMonitor().notifyLinkPropertiesChanged( 9097 new LinkProperties(newLp, true /* parcelSensitiveFields */)); 9098 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 9099 } 9100 9101 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 9102 } 9103 9104 private void applyInitialLinkProperties(@NonNull NetworkAgentInfo nai) { 9105 updateLinkProperties(nai, new LinkProperties(nai.linkProperties), null); 9106 } 9107 9108 /** 9109 * @param naData captive portal data from NetworkAgent 9110 * @param apiData captive portal data from capport API 9111 */ 9112 @Nullable 9113 private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData, 9114 CaptivePortalData apiData) { 9115 if (naData == null || apiData == null) { 9116 return naData == null ? apiData : naData; 9117 } 9118 final CaptivePortalData.Builder captivePortalBuilder = 9119 new CaptivePortalData.Builder(naData); 9120 9121 if (apiData.isCaptive()) { 9122 captivePortalBuilder.setCaptive(true); 9123 } 9124 if (apiData.isSessionExtendable()) { 9125 captivePortalBuilder.setSessionExtendable(true); 9126 } 9127 if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) { 9128 // Expiry time, bytes remaining, refresh time all need to come from the same source, 9129 // otherwise data would be inconsistent. Prefer the capport API info if present, 9130 // as it can generally be refreshed more often. 9131 captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis()); 9132 captivePortalBuilder.setBytesRemaining(apiData.getByteLimit()); 9133 captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis()); 9134 } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) { 9135 // No source has time / bytes remaining information: surface the newest refresh time 9136 // for other fields 9137 captivePortalBuilder.setRefreshTime( 9138 Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis())); 9139 } 9140 9141 // Prioritize the user portal URL from the network agent if the source is authenticated. 9142 if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource() 9143 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 9144 captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(), 9145 apiData.getUserPortalUrlSource()); 9146 } 9147 // Prioritize the venue information URL from the network agent if the source is 9148 // authenticated. 9149 if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource() 9150 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 9151 captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(), 9152 apiData.getVenueInfoUrlSource()); 9153 } 9154 return captivePortalBuilder.build(); 9155 } 9156 9157 @VisibleForTesting 9158 static String makeNflogPrefix(String iface, long networkHandle) { 9159 // This needs to be kept in sync and backwards compatible with the decoding logic in 9160 // NetdEventListenerService, which is non-mainline code. 9161 return SdkLevel.isAtLeastU() ? (networkHandle + ":" + iface) : ("iface:" + iface); 9162 } 9163 9164 private static boolean isWakeupMarkingSupported(NetworkCapabilities capabilities) { 9165 if (capabilities.hasTransport(TRANSPORT_WIFI)) { 9166 return true; 9167 } 9168 if (SdkLevel.isAtLeastU() && capabilities.hasTransport(TRANSPORT_CELLULAR)) { 9169 return true; 9170 } 9171 return false; 9172 } 9173 9174 private void wakeupModifyInterface(String iface, NetworkAgentInfo nai, boolean add) { 9175 // Marks are only available on WiFi interfaces. Checking for 9176 // marks on unsupported interfaces is harmless. 9177 if (!isWakeupMarkingSupported(nai.networkCapabilities)) { 9178 return; 9179 } 9180 9181 // Mask/mark of zero will not detect anything interesting. 9182 // Don't install rules unless both values are nonzero. 9183 if (mWakeUpMark == 0 || mWakeUpMask == 0) { 9184 return; 9185 } 9186 9187 final String prefix = makeNflogPrefix(iface, nai.network.getNetworkHandle()); 9188 try { 9189 if (add) { 9190 mNetd.wakeupAddInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 9191 } else { 9192 mNetd.wakeupDelInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 9193 } 9194 } catch (Exception e) { 9195 loge("Exception modifying wakeup packet monitoring: " + e); 9196 } 9197 } 9198 9199 private void updateInterfaces(final @NonNull LinkProperties newLp, 9200 final @Nullable LinkProperties oldLp, final int netId, 9201 final @NonNull NetworkAgentInfo nai) { 9202 final CompareResult<String> interfaceDiff = new CompareResult<>( 9203 oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames()); 9204 if (!interfaceDiff.added.isEmpty()) { 9205 for (final String iface : interfaceDiff.added) { 9206 try { 9207 if (DBG) log("Adding iface " + iface + " to network " + netId); 9208 mRoutingCoordinatorService.addInterfaceToNetwork(netId, iface); 9209 wakeupModifyInterface(iface, nai, true); 9210 mDeps.reportNetworkInterfaceForTransports(mContext, iface, 9211 nai.networkCapabilities.getTransportTypes()); 9212 } catch (Exception e) { 9213 logw("Exception adding interface: " + e); 9214 } 9215 } 9216 } 9217 for (final String iface : interfaceDiff.removed) { 9218 try { 9219 if (DBG) log("Removing iface " + iface + " from network " + netId); 9220 wakeupModifyInterface(iface, nai, false); 9221 mRoutingCoordinatorService.removeInterfaceFromNetwork(netId, iface); 9222 } catch (Exception e) { 9223 loge("Exception removing interface: " + e); 9224 } 9225 } 9226 } 9227 9228 /** 9229 * Have netd update routes from oldLp to newLp. 9230 * @return true if routes changed between oldLp and newLp 9231 */ 9232 private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 9233 int netId) { 9234 // compare the route diff to determine which routes have been updated 9235 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff = 9236 new CompareOrUpdateResult<>( 9237 oldLp != null ? oldLp.getAllRoutes() : null, 9238 newLp.getAllRoutes(), 9239 (r) -> r.getRouteKey()); 9240 9241 // add routes before removing old in case it helps with continuous connectivity 9242 9243 // do this twice, adding non-next-hop routes first, then routes they are dependent on 9244 for (RouteInfo route : routeDiff.added) { 9245 if (route.hasGateway()) continue; 9246 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 9247 try { 9248 mRoutingCoordinatorService.addRoute(netId, route); 9249 } catch (Exception e) { 9250 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 9251 loge("Exception in addRoute for non-gateway: " + e); 9252 } 9253 } 9254 } 9255 for (RouteInfo route : routeDiff.added) { 9256 if (!route.hasGateway()) continue; 9257 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 9258 try { 9259 mRoutingCoordinatorService.addRoute(netId, route); 9260 } catch (Exception e) { 9261 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 9262 loge("Exception in addRoute for gateway: " + e); 9263 } 9264 } 9265 } 9266 9267 for (RouteInfo route : routeDiff.removed) { 9268 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); 9269 try { 9270 mRoutingCoordinatorService.removeRoute(netId, route); 9271 } catch (Exception e) { 9272 loge("Exception in removeRoute: " + e); 9273 } 9274 } 9275 9276 for (RouteInfo route : routeDiff.updated) { 9277 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId); 9278 try { 9279 mRoutingCoordinatorService.updateRoute(netId, route); 9280 } catch (Exception e) { 9281 loge("Exception in updateRoute: " + e); 9282 } 9283 } 9284 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty() 9285 || !routeDiff.updated.isEmpty(); 9286 } 9287 9288 private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 9289 int netId) { 9290 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 9291 return; // no updating necessary 9292 } 9293 9294 if (DBG) { 9295 final Collection<InetAddress> dnses = newLp.getDnsServers(); 9296 log("Setting DNS servers for network " + netId + " to " + dnses); 9297 } 9298 try { 9299 mDnsManager.noteDnsServersForNetwork(netId, newLp); 9300 mDnsManager.flushVmDnsCache(); 9301 } catch (Exception e) { 9302 loge("Exception in setDnsConfigurationForNetwork: " + e); 9303 } 9304 } 9305 9306 private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 9307 @NonNull NetworkAgentInfo nai) { 9308 final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp); 9309 final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp); 9310 final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface); 9311 final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface); 9312 9313 if (!wasFiltering && !needsFiltering) { 9314 // Nothing to do. 9315 return; 9316 } 9317 9318 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) { 9319 // Nothing changed. 9320 return; 9321 } 9322 9323 final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges(); 9324 if (ranges == null || ranges.isEmpty()) { 9325 return; 9326 } 9327 9328 final int vpnAppUid = nai.networkCapabilities.getOwnerUid(); 9329 // TODO: this create a window of opportunity for apps to receive traffic between the time 9330 // when the old rules are removed and the time when new rules are added. To fix this, 9331 // make eBPF support two allowlisted interfaces so here new rules can be added before the 9332 // old rules are being removed. 9333 if (wasFiltering) { 9334 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid); 9335 } 9336 if (needsFiltering) { 9337 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid); 9338 } 9339 } 9340 9341 /** 9342 * Returns ingress discard rules to drop packets to VPN addresses ingressing via non-VPN 9343 * interfaces. 9344 * Ingress discard rule is added to the address iff 9345 * 1. The address is not a link local address 9346 * 2. The address is used by a single VPN interface and not used by any other 9347 * interfaces even non-VPN ones 9348 * This method can be called during network disconnects, when nai has already been removed from 9349 * mNetworkAgentInfos. 9350 * 9351 * @param nai This method generates rules assuming lp of this nai is the lp at the second 9352 * argument. 9353 * @param lp This method generates rules assuming lp of nai at the first argument is this lp. 9354 * Caller passes old lp to generate old rules and new lp to generate new rules. 9355 * @return ingress discard rules. Set of pairs of addresses and interface names 9356 */ 9357 private Set<Pair<InetAddress, String>> generateIngressDiscardRules( 9358 @NonNull final NetworkAgentInfo nai, @Nullable final LinkProperties lp) { 9359 Set<NetworkAgentInfo> nais = new ArraySet<>(mNetworkAgentInfos); 9360 nais.add(nai); 9361 // Determine how many networks each IP address is currently configured on. 9362 // Ingress rules are added only for IP addresses that are configured on single interface. 9363 final Map<InetAddress, Integer> addressOwnerCounts = new ArrayMap<>(); 9364 for (final NetworkAgentInfo agent : nais) { 9365 if (agent.isDestroyed()) { 9366 continue; 9367 } 9368 final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties; 9369 if (agentLp == null) { 9370 continue; 9371 } 9372 for (final InetAddress addr: agentLp.getAllAddresses()) { 9373 addressOwnerCounts.put(addr, addressOwnerCounts.getOrDefault(addr, 0) + 1); 9374 } 9375 } 9376 9377 // Iterates all networks instead of only generating rule for nai that was passed in since 9378 // lp of the nai change could cause/resolve address collision and result in affecting rule 9379 // for different network. 9380 final Set<Pair<InetAddress, String>> ingressDiscardRules = new ArraySet<>(); 9381 for (final NetworkAgentInfo agent : nais) { 9382 if (!agent.isVPN() || agent.isDestroyed()) { 9383 continue; 9384 } 9385 final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties; 9386 if (agentLp == null || agentLp.getInterfaceName() == null) { 9387 continue; 9388 } 9389 9390 for (final InetAddress addr: agentLp.getAllAddresses()) { 9391 if (addressOwnerCounts.get(addr) == 1 && !addr.isLinkLocalAddress()) { 9392 ingressDiscardRules.add(new Pair<>(addr, agentLp.getInterfaceName())); 9393 } 9394 } 9395 } 9396 return ingressDiscardRules; 9397 } 9398 9399 private void updateIngressToVpnAddressFiltering(@Nullable LinkProperties newLp, 9400 @Nullable LinkProperties oldLp, @NonNull NetworkAgentInfo nai) { 9401 // Having isAtleastT to avoid NewApi linter error (b/303382209) 9402 if (!mIngressToVpnAddressFiltering || !mDeps.isAtLeastT()) { 9403 return; 9404 } 9405 final CompareOrUpdateResult<InetAddress, Pair<InetAddress, String>> ruleDiff = 9406 new CompareOrUpdateResult<>( 9407 generateIngressDiscardRules(nai, oldLp), 9408 generateIngressDiscardRules(nai, newLp), 9409 (rule) -> rule.first); 9410 for (Pair<InetAddress, String> rule: ruleDiff.removed) { 9411 mBpfNetMaps.removeIngressDiscardRule(rule.first); 9412 } 9413 for (Pair<InetAddress, String> rule: ruleDiff.added) { 9414 mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second); 9415 } 9416 // setIngressDiscardRule overrides the existing rule 9417 for (Pair<InetAddress, String> rule: ruleDiff.updated) { 9418 mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second); 9419 } 9420 } 9421 9422 private void updateWakeOnLan(@NonNull LinkProperties lp) { 9423 if (mWolSupportedInterfaces == null) { 9424 mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray( 9425 R.array.config_wakeonlan_supported_interfaces)); 9426 } 9427 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName())); 9428 } 9429 9430 private int getNetworkPermission(NetworkCapabilities nc) { 9431 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 9432 return INetd.PERMISSION_SYSTEM; 9433 } 9434 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 9435 return INetd.PERMISSION_NETWORK; 9436 } 9437 return INetd.PERMISSION_NONE; 9438 } 9439 9440 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai, 9441 @NonNull final NetworkCapabilities newNc) { 9442 final int oldPermission = getNetworkPermission(nai.networkCapabilities); 9443 final int newPermission = getNetworkPermission(newNc); 9444 if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) { 9445 try { 9446 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission); 9447 } catch (RemoteException | ServiceSpecificException e) { 9448 loge("Exception in networkSetPermissionForNetwork: " + e); 9449 } 9450 } 9451 } 9452 9453 /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */ 9454 @VisibleForTesting 9455 void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, 9456 @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { 9457 underlyingNetworks = underlyingNetworksOrDefault( 9458 agentCaps.getOwnerUid(), underlyingNetworks); 9459 long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes()); 9460 int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 9461 int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 9462 // metered if any underlying is metered, or originally declared metered by the agent. 9463 boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 9464 boolean roaming = false; // roaming if any underlying is roaming 9465 boolean congested = false; // congested if any underlying is congested 9466 boolean suspended = true; // suspended if all underlying are suspended 9467 9468 boolean hadUnderlyingNetworks = false; 9469 ArrayList<Network> newUnderlyingNetworks = null; 9470 if (null != underlyingNetworks) { 9471 newUnderlyingNetworks = new ArrayList<>(); 9472 for (Network underlyingNetwork : underlyingNetworks) { 9473 final NetworkAgentInfo underlying = 9474 getNetworkAgentInfoForNetwork(underlyingNetwork); 9475 if (underlying == null) continue; 9476 9477 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; 9478 hadUnderlyingNetworks = true; 9479 for (int underlyingType : underlyingCaps.getTransportTypes()) { 9480 transportTypes |= 1L << underlyingType; 9481 } 9482 9483 // Merge capabilities of this underlying network. For bandwidth, assume the 9484 // worst case. 9485 downKbps = NetworkCapabilities.minBandwidth(downKbps, 9486 underlyingCaps.getLinkDownstreamBandwidthKbps()); 9487 upKbps = NetworkCapabilities.minBandwidth(upKbps, 9488 underlyingCaps.getLinkUpstreamBandwidthKbps()); 9489 // If this underlying network is metered, the VPN is metered (it may cost money 9490 // to send packets on this network). 9491 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 9492 // If this underlying network is roaming, the VPN is roaming (the billing structure 9493 // is different than the usual, local one). 9494 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); 9495 // If this underlying network is congested, the VPN is congested (the current 9496 // condition of the network affects the performance of this network). 9497 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 9498 // If this network is not suspended, the VPN is not suspended (the VPN 9499 // is able to transfer some data). 9500 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 9501 newUnderlyingNetworks.add(underlyingNetwork); 9502 } 9503 } 9504 if (!hadUnderlyingNetworks) { 9505 // No idea what the underlying networks are; assume reasonable defaults 9506 metered = true; 9507 roaming = false; 9508 congested = false; 9509 suspended = false; 9510 } 9511 9512 newNc.setTransportTypes(BitUtils.unpackBits(transportTypes)); 9513 newNc.setLinkDownstreamBandwidthKbps(downKbps); 9514 newNc.setLinkUpstreamBandwidthKbps(upKbps); 9515 newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered); 9516 newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); 9517 newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); 9518 newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); 9519 newNc.setUnderlyingNetworks(newUnderlyingNetworks); 9520 } 9521 9522 /** 9523 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 9524 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 9525 * and foreground status). 9526 */ 9527 @NonNull 9528 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 9529 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 9530 // Don't complain for VPNs since they're not driven by requests and there is no risk of 9531 // causing a connect/teardown loop. 9532 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to 9533 // avoid connect/teardown loops. 9534 if (nai.everConnected() 9535 && !nai.isVPN() 9536 && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 9537 // TODO: consider not complaining when a network agent degrades its capabilities if this 9538 // does not cause any request (that is not a listen) currently matching that agent to 9539 // stop being matched by the updated agent. 9540 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 9541 if (!TextUtils.isEmpty(diff)) { 9542 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 9543 } 9544 } 9545 9546 // Don't modify caller's NetworkCapabilities. 9547 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 9548 if (nai.isValidated()) { 9549 newNc.addCapability(NET_CAPABILITY_VALIDATED); 9550 } else { 9551 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 9552 } 9553 if (nai.captivePortalDetected()) { 9554 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 9555 } else { 9556 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 9557 } 9558 if (nai.isBackgroundNetwork()) { 9559 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 9560 } else { 9561 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 9562 } 9563 if (nai.partialConnectivity()) { 9564 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 9565 } else { 9566 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 9567 } 9568 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken()); 9569 9570 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING 9571 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) { 9572 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9573 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING); 9574 } 9575 9576 if (nai.propagateUnderlyingCapabilities()) { 9577 applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, 9578 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator), 9579 newNc); 9580 } 9581 9582 return newNc; 9583 } 9584 9585 private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, 9586 NetworkCapabilities prevNc, NetworkCapabilities newNc) { 9587 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 9588 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 9589 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 9590 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 9591 if (prevSuspended != suspended) { 9592 // TODO (b/73132094) : remove this call once the few users of onSuspended and 9593 // onResumed have been removed. 9594 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED 9595 : ConnectivityManager.CALLBACK_RESUMED); 9596 } 9597 if (prevSuspended != suspended || prevRoaming != roaming) { 9598 // updateNetworkInfo will mix in the suspended info from the capabilities and 9599 // take appropriate action for the network having possibly changed state. 9600 updateNetworkInfo(nai, nai.networkInfo); 9601 } 9602 } 9603 9604 private void handleUidCarrierPrivilegesLost(int uid, int subId) { 9605 if (!mRequestRestrictedWifiEnabled) { 9606 return; 9607 } 9608 ensureRunningOnConnectivityServiceThread(); 9609 // A NetworkRequest needs to be revoked when all the conditions are met 9610 // 1. It requests restricted network 9611 // 2. The requestor uid matches the uid with the callback 9612 // 3. The app doesn't have Carrier Privileges 9613 // 4. The app doesn't have permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS 9614 for (final NetworkRequest nr : mNetworkRequests.keySet()) { 9615 if (nr.isRequest() 9616 && !nr.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 9617 && nr.getRequestorUid() == uid 9618 && getSubscriptionIdFromNetworkCaps(nr.networkCapabilities) == subId 9619 && !hasConnectivityRestrictedNetworksPermission(uid, true)) { 9620 declareNetworkRequestUnfulfillable(nr); 9621 } 9622 } 9623 9624 // A NetworkAgent's allowedUids may need to be updated if the app has lost 9625 // carrier config 9626 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 9627 if (nai.networkCapabilities.getAllowedUidsNoCopy().contains(uid) 9628 && getSubscriptionIdFromNetworkCaps(nai.networkCapabilities) == subId) { 9629 final NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities); 9630 NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent( 9631 nc, 9632 uid, 9633 false /* hasAutomotiveFeature (irrelevant) */, 9634 mDeps, 9635 mCarrierPrivilegeAuthenticator); 9636 updateCapabilities(nai.getScore(), nai, nc); 9637 } 9638 } 9639 } 9640 9641 /** 9642 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 9643 * 9644 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 9645 * capabilities we manage and store in {@code nai}, such as validated status and captive 9646 * portal status) 9647 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 9648 * potentially triggers rematches. 9649 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 9650 * change.) 9651 * 9652 * @param oldScore score of the network before any of the changes that prompted us 9653 * to call this function. 9654 * @param nai the network having its capabilities updated. 9655 * @param nc the new network capabilities. 9656 */ 9657 private void updateCapabilities(final FullScore oldScore, @NonNull final NetworkAgentInfo nai, 9658 @NonNull final NetworkCapabilities nc) { 9659 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 9660 if (Objects.equals(nai.networkCapabilities, newNc)) return; 9661 final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities); 9662 if (null != differences) { 9663 Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences); 9664 } 9665 updateNetworkPermissions(nai, newNc); 9666 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc); 9667 9668 updateVpnUids(nai, prevNc, newNc); 9669 updateAllowedUids(nai, prevNc, newNc); 9670 nai.updateScoreForNetworkAgentUpdate(); 9671 9672 if (nai.getScore().equals(oldScore) && newNc.equalRequestableCapabilities(prevNc)) { 9673 // If the requestable capabilities haven't changed, and the score hasn't changed, then 9674 // the change we're processing can't affect any requests, it can only affect the listens 9675 // on this network. We might have been called by rematchNetworkAndRequests when a 9676 // network changed foreground state. 9677 processListenRequests(nai); 9678 } else { 9679 // If the requestable capabilities have changed or the score changed, we can't have been 9680 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 9681 rematchAllNetworksAndRequests(); 9682 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 9683 } 9684 updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc); 9685 9686 final boolean oldMetered = prevNc.isMetered(); 9687 final boolean newMetered = newNc.isMetered(); 9688 final boolean meteredChanged = oldMetered != newMetered; 9689 9690 if (meteredChanged) { 9691 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, 9692 mVpnBlockedUidRanges, mVpnBlockedUidRanges); 9693 } 9694 9695 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) 9696 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 9697 9698 // Report changes that are interesting for network statistics tracking. 9699 if (meteredChanged || roamingChanged) { 9700 notifyIfacesChangedForNetworkStats(); 9701 } 9702 9703 // This network might have been underlying another network. Propagate its capabilities. 9704 propagateUnderlyingNetworkCapabilities(nai.network); 9705 9706 if (meteredChanged || !newNc.equalsTransportTypes(prevNc)) { 9707 mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), newNc); 9708 } 9709 9710 maybeSendProxyBroadcast(nai, prevNc, newNc); 9711 } 9712 9713 /** Convenience method to update the capabilities for a given network. */ 9714 private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) { 9715 updateCapabilities(nai.getScore(), nai, nai.networkCapabilities); 9716 } 9717 9718 private void maybeApplyMulticastRoutingConfig(@NonNull final NetworkAgentInfo nai, 9719 final LocalNetworkConfig oldConfig, 9720 final LocalNetworkConfig newConfig) { 9721 final MulticastRoutingConfig oldUpstreamConfig = 9722 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 9723 oldConfig.getUpstreamMulticastRoutingConfig(); 9724 final MulticastRoutingConfig oldDownstreamConfig = 9725 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 9726 oldConfig.getDownstreamMulticastRoutingConfig(); 9727 final MulticastRoutingConfig newUpstreamConfig = 9728 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 9729 newConfig.getUpstreamMulticastRoutingConfig(); 9730 final MulticastRoutingConfig newDownstreamConfig = 9731 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 9732 newConfig.getDownstreamMulticastRoutingConfig(); 9733 9734 if (oldUpstreamConfig.equals(newUpstreamConfig) && 9735 oldDownstreamConfig.equals(newDownstreamConfig)) { 9736 return; 9737 } 9738 9739 final String downstreamNetworkName = nai.linkProperties.getInterfaceName(); 9740 final LocalNetworkInfo lni = localNetworkInfoForNai(nai); 9741 final Network upstreamNetwork = lni.getUpstreamNetwork(); 9742 9743 if (upstreamNetwork != null) { 9744 final String upstreamNetworkName = 9745 getLinkProperties(upstreamNetwork).getInterfaceName(); 9746 applyMulticastRoutingConfig(downstreamNetworkName, upstreamNetworkName, newConfig); 9747 } 9748 } 9749 9750 private void applyMulticastRoutingConfig(@NonNull String localNetworkInterfaceName, 9751 @NonNull String upstreamNetworkInterfaceName, 9752 @NonNull final LocalNetworkConfig config) { 9753 if (mMulticastRoutingCoordinatorService == null) { 9754 if (config.getDownstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE || 9755 config.getUpstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE) { 9756 loge("Multicast routing is not supported, failed to configure " + config 9757 + " for " + localNetworkInterfaceName + " to " 9758 + upstreamNetworkInterfaceName); 9759 } 9760 return; 9761 } 9762 9763 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName, 9764 upstreamNetworkInterfaceName, config.getUpstreamMulticastRoutingConfig()); 9765 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig 9766 (upstreamNetworkInterfaceName, localNetworkInterfaceName, 9767 config.getDownstreamMulticastRoutingConfig()); 9768 } 9769 9770 private void disableMulticastRouting(@NonNull String localNetworkInterfaceName, 9771 @NonNull String upstreamNetworkInterfaceName) { 9772 if (mMulticastRoutingCoordinatorService == null) { 9773 return; 9774 } 9775 9776 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName, 9777 upstreamNetworkInterfaceName, MulticastRoutingConfig.CONFIG_FORWARD_NONE); 9778 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig 9779 (upstreamNetworkInterfaceName, localNetworkInterfaceName, 9780 MulticastRoutingConfig.CONFIG_FORWARD_NONE); 9781 } 9782 9783 // oldConfig is null iff this is the original registration of the local network config 9784 private void handleUpdateLocalNetworkConfig(@NonNull final NetworkAgentInfo nai, 9785 @Nullable final LocalNetworkConfig oldConfig, 9786 @NonNull final LocalNetworkConfig newConfig) { 9787 if (!nai.isLocalNetwork()) { 9788 Log.wtf(TAG, "Ignoring update of a local network info on non-local network " + nai); 9789 return; 9790 } 9791 9792 if (VDBG) { 9793 Log.v(TAG, "Update local network config " + nai.network.netId + " : " + newConfig); 9794 } 9795 final LocalNetworkConfig.Builder configBuilder = new LocalNetworkConfig.Builder(); 9796 configBuilder.setUpstreamMulticastRoutingConfig( 9797 newConfig.getUpstreamMulticastRoutingConfig()); 9798 configBuilder.setDownstreamMulticastRoutingConfig( 9799 newConfig.getDownstreamMulticastRoutingConfig()); 9800 9801 final NetworkRequest oldRequest = 9802 (null == oldConfig) ? null : oldConfig.getUpstreamSelector(); 9803 final NetworkCapabilities oldCaps = 9804 (null == oldRequest) ? null : oldRequest.networkCapabilities; 9805 final NetworkRequestInfo oldNri = 9806 null == oldRequest ? null : mNetworkRequests.get(oldRequest); 9807 final NetworkAgentInfo oldSatisfier = 9808 null == oldNri ? null : oldNri.getSatisfier(); 9809 final NetworkRequest newRequest = newConfig.getUpstreamSelector(); 9810 final NetworkCapabilities newCaps = 9811 (null == newRequest) ? null : newRequest.networkCapabilities; 9812 final boolean requestUpdated = !Objects.equals(newCaps, oldCaps); 9813 if (null != oldRequest && requestUpdated) { 9814 handleRemoveNetworkRequest(mNetworkRequests.get(oldRequest)); 9815 if (null == newRequest && null != oldSatisfier) { 9816 // If there is an old satisfier, but no new request, then remove the old upstream. 9817 removeLocalNetworkUpstream(nai, oldSatisfier); 9818 nai.localNetworkConfig = configBuilder.build(); 9819 // When there is a new request, the rematch sees the new request and sends the 9820 // LOCAL_NETWORK_INFO_CHANGED callbacks accordingly. 9821 // But here there is no new request, so the rematch won't see anything. Send 9822 // callbacks to apps now to tell them about the loss of upstream. 9823 notifyNetworkCallbacks(nai, 9824 ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 9825 return; 9826 } 9827 } 9828 if (null != newRequest && requestUpdated) { 9829 // File the new request if : 9830 // - it has changed (requestUpdated), or 9831 // - it's the first time this local info (null == oldConfig) 9832 // is updated and the request has not been filed yet. 9833 // Requests for local info are always LISTEN_FOR_BEST, because they have at most one 9834 // upstream (the best) but never request it to be brought up. 9835 final NetworkRequest nr = new NetworkRequest(newCaps, ConnectivityManager.TYPE_NONE, 9836 nextNetworkRequestId(), LISTEN_FOR_BEST); 9837 configBuilder.setUpstreamSelector(nr); 9838 final NetworkRequestInfo nri = new NetworkRequestInfo( 9839 nai.creatorUid, nr, null /* messenger */, null /* binder */, 9840 0 /* callbackFlags */, null /* attributionTag */); 9841 if (null != oldSatisfier) { 9842 // Set the old satisfier in the new NRI so that the rematch will see any changes 9843 nri.setSatisfier(oldSatisfier, nr); 9844 } 9845 nai.localNetworkConfig = configBuilder.build(); 9846 // handleRegisterNetworkRequest causes a rematch. The rematch must happen after 9847 // nai.localNetworkConfig is set, since it will base its callbacks on the old 9848 // satisfier and the new request. 9849 handleRegisterNetworkRequest(nri); 9850 } else { 9851 configBuilder.setUpstreamSelector(oldRequest); 9852 nai.localNetworkConfig = configBuilder.build(); 9853 } 9854 maybeApplyMulticastRoutingConfig(nai, oldConfig, newConfig); 9855 } 9856 9857 /** 9858 * Returns the interface which requires VPN isolation (ingress interface filtering). 9859 * 9860 * Ingress interface filtering enforces that all apps under the given network can only receive 9861 * packets from the network's interface (and loopback). This is important for VPNs because 9862 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any 9863 * non-VPN interfaces. 9864 * 9865 * As a result, this method should return Non-null interface iff 9866 * 1. the network is an app VPN (not legacy VPN) 9867 * 2. the VPN does not allow bypass 9868 * 3. the VPN is fully-routed 9869 * 4. the VPN interface is non-null 9870 * 9871 * @see INetd#firewallAddUidInterfaceRules 9872 * @see INetd#firewallRemoveUidInterfaceRules 9873 */ 9874 @Nullable 9875 private String getVpnIsolationInterface(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, 9876 LinkProperties lp) { 9877 if (nc == null || lp == null) return null; 9878 if (nai.isVPN() 9879 && !nai.networkAgentConfig.allowBypass 9880 && nc.getOwnerUid() != Process.SYSTEM_UID 9881 && lp.getInterfaceName() != null 9882 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute()) 9883 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()) 9884 && !lp.hasExcludeRoute()) { 9885 return lp.getInterfaceName(); 9886 } 9887 return null; 9888 } 9889 9890 /** 9891 * Returns whether we need to set interface filtering rule or not 9892 */ 9893 private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp, 9894 String isolationIface) { 9895 // Allow rules are always needed if VPN isolation is enabled. 9896 if (isolationIface != null) return true; 9897 9898 // On T and above, allow rules are needed for all VPNs. Allow rule with null iface is a 9899 // wildcard to allow apps to receive packets on all interfaces. This is required to accept 9900 // incoming traffic in Lockdown mode by overriding the Lockdown blocking rule. 9901 return mDeps.isAtLeastT() && nai.isVPN() && lp != null && lp.getInterfaceName() != null; 9902 } 9903 9904 private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 9905 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; 9906 int index = 0; 9907 for (UidRange range : ranges) { 9908 stableRanges[index] = new UidRangeParcel(range.start, range.stop); 9909 index++; 9910 } 9911 return stableRanges; 9912 } 9913 9914 private static UidRangeParcel[] intsToUidRangeStableParcels( 9915 final @NonNull ArraySet<Integer> uids) { 9916 final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()]; 9917 int index = 0; 9918 for (int uid : uids) { 9919 stableRanges[index] = new UidRangeParcel(uid, uid); 9920 index++; 9921 } 9922 return stableRanges; 9923 } 9924 9925 private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) { 9926 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 9927 for (int i = 0; i < ranges.length; i++) { 9928 stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop); 9929 } 9930 return stableRanges; 9931 } 9932 9933 private void maybeCloseSockets(NetworkAgentInfo nai, Set<UidRange> ranges, 9934 UidRangeParcel[] uidRangeParcels, int[] exemptUids) { 9935 if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) { 9936 try { 9937 if (mDeps.isAtLeastU()) { 9938 final Set<Integer> exemptUidSet = new ArraySet<>(); 9939 for (final int uid: exemptUids) { 9940 exemptUidSet.add(uid); 9941 } 9942 mDeps.destroyLiveTcpSockets(UidRange.toIntRanges(ranges), exemptUidSet); 9943 } else { 9944 mNetd.socketDestroy(uidRangeParcels, exemptUids); 9945 } 9946 } catch (Exception e) { 9947 loge("Exception in socket destroy: ", e); 9948 } 9949 } 9950 } 9951 9952 private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) { 9953 int[] exemptUids = new int[2]; 9954 // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used 9955 // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when 9956 // starting a legacy VPN, and remove VPN_UID here. (b/176542831) 9957 exemptUids[0] = VPN_UID; 9958 exemptUids[1] = nai.networkCapabilities.getOwnerUid(); 9959 UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges); 9960 9961 // Close sockets before modifying uid ranges so that RST packets can reach to the server. 9962 maybeCloseSockets(nai, uidRanges, ranges, exemptUids); 9963 try { 9964 if (add) { 9965 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 9966 nai.network.netId, ranges, PREFERENCE_ORDER_VPN)); 9967 } else { 9968 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 9969 nai.network.netId, ranges, PREFERENCE_ORDER_VPN)); 9970 } 9971 } catch (Exception e) { 9972 loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges + 9973 " on netId " + nai.network.netId + ". " + e); 9974 } 9975 // Close sockets that established connection while requesting netd. 9976 maybeCloseSockets(nai, uidRanges, ranges, exemptUids); 9977 } 9978 9979 private boolean isProxySetOnAnyDefaultNetwork() { 9980 ensureRunningOnConnectivityServiceThread(); 9981 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 9982 final NetworkAgentInfo nai = nri.getSatisfier(); 9983 if (nai != null && nai.linkProperties.getHttpProxy() != null) { 9984 return true; 9985 } 9986 } 9987 return false; 9988 } 9989 9990 private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, 9991 NetworkCapabilities newNc) { 9992 // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that 9993 // the proxy might be changed since the default network satisfied by the apps might also 9994 // changed. 9995 // TODO: Try to track the default network that apps use and only send a proxy broadcast when 9996 // that happens to prevent false alarms. 9997 final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges(); 9998 final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges(); 9999 if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids) 10000 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) { 10001 mProxyTracker.sendProxyBroadcast(); 10002 } 10003 } 10004 10005 private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc, 10006 @Nullable NetworkCapabilities newNc) { 10007 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges(); 10008 Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges(); 10009 if (null == prevRanges) prevRanges = new ArraySet<>(); 10010 if (null == newRanges) newRanges = new ArraySet<>(); 10011 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 10012 10013 prevRanges.removeAll(newRanges); 10014 newRanges.removeAll(prevRangesCopy); 10015 10016 try { 10017 // When updating the VPN uid routing rules, add the new range first then remove the old 10018 // range. If old range were removed first, there would be a window between the old 10019 // range being removed and the new range being added, during which UIDs contained 10020 // in both ranges are not subject to any VPN routing rules. Adding new range before 10021 // removing old range works because, unlike the filtering rules below, it's possible to 10022 // add duplicate UID routing rules. 10023 // TODO: calculate the intersection of add & remove. Imagining that we are trying to 10024 // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is: 10025 // [1-5] & [1-2],[4-5] == [3] 10026 // Then we can do: 10027 // maybeCloseSockets([3]) 10028 // mNetd.networkAddUidRanges([1-2],[4-5]) 10029 // mNetd.networkRemoveUidRanges([1-5]) 10030 // maybeCloseSockets([3]) 10031 // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the 10032 // number of binder calls from 6 to 4. 10033 if (!newRanges.isEmpty()) { 10034 updateVpnUidRanges(true, nai, newRanges); 10035 } 10036 if (!prevRanges.isEmpty()) { 10037 updateVpnUidRanges(false, nai, prevRanges); 10038 } 10039 final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties); 10040 final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties); 10041 final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface); 10042 final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface); 10043 // For VPN uid interface filtering, old ranges need to be removed before new ranges can 10044 // be added, due to the range being expanded and stored as individual UIDs. For example 10045 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means 10046 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges 10047 // were added first and then newRanges got removed later, there would be only one uid 10048 // 10013 left. A consequence of removing old ranges before adding new ranges is that 10049 // there is now a window of opportunity when the UIDs are not subject to any filtering. 10050 // Note that this is in contrast with the (more robust) update of VPN routing rules 10051 // above, where the addition of new ranges happens before the removal of old ranges. 10052 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range 10053 // to be removed will never overlap with the new range to be added. 10054 if (wasFiltering && !prevRanges.isEmpty()) { 10055 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges, 10056 prevNc.getOwnerUid()); 10057 } 10058 if (shouldFilter && !newRanges.isEmpty()) { 10059 mPermissionMonitor.onVpnUidRangesAdded(newIface, newRanges, newNc.getOwnerUid()); 10060 } 10061 } catch (Exception e) { 10062 // Never crash! 10063 loge("Exception in updateVpnUids: ", e); 10064 } 10065 } 10066 10067 private void updateAllowedUids(@NonNull NetworkAgentInfo nai, 10068 @Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) { 10069 // In almost all cases both NC code for empty access UIDs. return as fast as possible. 10070 final boolean prevEmpty = null == prevNc || prevNc.getAllowedUidsNoCopy().isEmpty(); 10071 final boolean newEmpty = null == newNc || newNc.getAllowedUidsNoCopy().isEmpty(); 10072 if (prevEmpty && newEmpty) return; 10073 10074 final ArraySet<Integer> prevUids = 10075 null == prevNc ? new ArraySet<>() : prevNc.getAllowedUidsNoCopy(); 10076 final ArraySet<Integer> newUids = 10077 null == newNc ? new ArraySet<>() : newNc.getAllowedUidsNoCopy(); 10078 10079 if (prevUids.equals(newUids)) return; 10080 10081 // This implementation is very simple and vastly faster for sets of Integers than 10082 // CompareOrUpdateResult, which is tuned for sets that need to be compared based on 10083 // a key computed from the value and has storage for that. 10084 final ArraySet<Integer> toRemove = new ArraySet<>(prevUids); 10085 final ArraySet<Integer> toAdd = new ArraySet<>(newUids); 10086 toRemove.removeAll(newUids); 10087 toAdd.removeAll(prevUids); 10088 try { 10089 if (!toAdd.isEmpty()) { 10090 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 10091 nai.network.netId, 10092 intsToUidRangeStableParcels(toAdd), 10093 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT)); 10094 } 10095 if (!toRemove.isEmpty()) { 10096 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 10097 nai.network.netId, 10098 intsToUidRangeStableParcels(toRemove), 10099 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT)); 10100 } 10101 } catch (ServiceSpecificException e) { 10102 // Has the interface disappeared since the network was built ? 10103 Log.i(TAG, "Can't set access UIDs for network " + nai.network, e); 10104 } catch (RemoteException e) { 10105 // Netd died. This usually causes a runtime restart anyway. 10106 } 10107 } 10108 10109 public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai, 10110 @NonNull LinkProperties newLp) { 10111 ensureRunningOnConnectivityServiceThread(); 10112 10113 if (!mNetworkAgentInfos.contains(nai)) { 10114 // Ignore updates for disconnected networks 10115 return; 10116 } 10117 if (VDBG || DDBG) { 10118 log("Update of LinkProperties for " + nai.toShortString() 10119 + "; created=" + nai.getCreatedTime() 10120 + "; firstConnected=" + nai.getConnectedTime()); 10121 } 10122 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not 10123 // modify its oldLp parameter. 10124 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties)); 10125 } 10126 10127 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 10128 int notificationType) { 10129 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 10130 Intent intent = new Intent(); 10131 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 10132 // If apps could file multi-layer requests with PendingIntents, they'd need to know 10133 // which of the layer is satisfied alongside with some ID for the request. Hence, if 10134 // such an API is ever implemented, there is no doubt the right request to send in 10135 // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would 10136 // need to be sent as a separate extra. 10137 final NetworkRequest req = nri.isMultilayerRequest() 10138 ? nri.getActiveRequest() 10139 // Non-multilayer listen requests do not have an active request 10140 : nri.mRequests.get(0); 10141 if (req == null) { 10142 Log.wtf(TAG, "No request in NRI " + nri); 10143 } 10144 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req); 10145 nri.mPendingIntentSent = true; 10146 sendIntent(nri.mPendingIntent, intent); 10147 } 10148 // else not handled 10149 } 10150 10151 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 10152 @SuppressLint("NewApi") 10153 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 10154 mPendingIntentWakeLock.acquire(); 10155 try { 10156 if (DBG) log("Sending " + pendingIntent); 10157 final BroadcastOptions options = BroadcastOptions.makeBasic(); 10158 if (mDeps.isAtLeastT()) { 10159 // Explicitly disallow the receiver from starting activities, to prevent apps from 10160 // utilizing the PendingIntent as a backdoor to do this. 10161 options.setPendingIntentBackgroundActivityLaunchAllowed(false); 10162 } 10163 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */, 10164 null /* requiredPermission */, 10165 mDeps.isAtLeastT() ? options.toBundle() : null); 10166 } catch (PendingIntent.CanceledException e) { 10167 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 10168 mPendingIntentWakeLock.release(); 10169 releasePendingNetworkRequest(pendingIntent); 10170 } 10171 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 10172 } 10173 10174 @Override 10175 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 10176 String resultData, Bundle resultExtras) { 10177 if (DBG) log("Finished sending " + pendingIntent); 10178 mPendingIntentWakeLock.release(); 10179 // Release with a delay so the receiving client has an opportunity to put in its 10180 // own request. 10181 releasePendingNetworkRequestWithDelay(pendingIntent); 10182 } 10183 10184 @Nullable 10185 private LocalNetworkInfo localNetworkInfoForNai(@NonNull final NetworkAgentInfo nai) { 10186 if (!nai.isLocalNetwork()) return null; 10187 final Network upstream; 10188 final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector(); 10189 if (null == selector) { 10190 upstream = null; 10191 } else { 10192 final NetworkRequestInfo upstreamNri = mNetworkRequests.get(selector); 10193 final NetworkAgentInfo satisfier = upstreamNri.getSatisfier(); 10194 upstream = (null == satisfier) ? null : satisfier.network; 10195 } 10196 return new LocalNetworkInfo.Builder().setUpstreamNetwork(upstream).build(); 10197 } 10198 10199 // networkAgent is only allowed to be null if notificationType is 10200 // CALLBACK_UNAVAIL. This is because UNAVAIL is about no network being 10201 // available, while all other cases are about some particular network. 10202 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, 10203 @Nullable final NetworkAgentInfo networkAgent, final int notificationType, 10204 final int arg1) { 10205 if (nri.mMessenger == null) { 10206 // Default request has no msgr. Also prevents callbacks from being invoked for 10207 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks 10208 // are Type.LISTEN, but should not have NetworkCallbacks invoked. 10209 return; 10210 } 10211 final Bundle bundle = new Bundle(); 10212 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 10213 // TODO: check if defensive copies of data is needed. 10214 final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); 10215 putParcelable(bundle, nrForCallback); 10216 Message msg = Message.obtain(); 10217 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) { 10218 putParcelable(bundle, networkAgent.network); 10219 } 10220 final boolean includeLocationSensitiveInfo = 10221 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0; 10222 switch (notificationType) { 10223 case ConnectivityManager.CALLBACK_AVAILABLE: { 10224 final NetworkCapabilities nc = 10225 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10226 networkCapabilitiesRestrictedForCallerPermissions( 10227 networkAgent.networkCapabilities, nri.mPid, nri.mUid), 10228 includeLocationSensitiveInfo, nri.mPid, nri.mUid, 10229 nrForCallback.getRequestorPackageName(), 10230 nri.mCallingAttributionTag); 10231 putParcelable(bundle, nc); 10232 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 10233 networkAgent.linkProperties, nri.mPid, nri.mUid)); 10234 // The local network info is often null, so can't use the static putParcelable 10235 // method here. 10236 bundle.putParcelable(LocalNetworkInfo.class.getSimpleName(), 10237 localNetworkInfoForNai(networkAgent)); 10238 // For this notification, arg1 contains the blocked status. 10239 msg.arg1 = arg1; 10240 break; 10241 } 10242 case ConnectivityManager.CALLBACK_LOSING: { 10243 msg.arg1 = arg1; 10244 break; 10245 } 10246 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 10247 // networkAgent can't be null as it has been accessed a few lines above. 10248 final NetworkCapabilities netCap = 10249 networkCapabilitiesRestrictedForCallerPermissions( 10250 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 10251 putParcelable( 10252 bundle, 10253 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10254 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid, 10255 nrForCallback.getRequestorPackageName(), 10256 nri.mCallingAttributionTag)); 10257 break; 10258 } 10259 case ConnectivityManager.CALLBACK_IP_CHANGED: { 10260 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 10261 networkAgent.linkProperties, nri.mPid, nri.mUid)); 10262 break; 10263 } 10264 case ConnectivityManager.CALLBACK_BLK_CHANGED: { 10265 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1); 10266 msg.arg1 = arg1; 10267 break; 10268 } 10269 case ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED: { 10270 if (!networkAgent.isLocalNetwork()) { 10271 Log.wtf(TAG, "Callback for local info for a non-local network"); 10272 return; 10273 } 10274 putParcelable(bundle, localNetworkInfoForNai(networkAgent)); 10275 break; 10276 } 10277 } 10278 msg.what = notificationType; 10279 msg.setData(bundle); 10280 try { 10281 if (VDBG) { 10282 String notification = ConnectivityManager.getCallbackName(notificationType); 10283 log("sending notification " + notification + " for " + nrForCallback); 10284 } 10285 nri.mMessenger.send(msg); 10286 } catch (RemoteException e) { 10287 // may occur naturally in the race of binder death. 10288 loge("RemoteException caught trying to send a callback msg for " + nrForCallback); 10289 } 10290 } 10291 10292 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 10293 bundle.putParcelable(t.getClass().getSimpleName(), t); 10294 } 10295 10296 /** 10297 * Returns whether reassigning a request from an NAI to another can be done gracefully. 10298 * 10299 * When a request should be assigned to a new network, it is normally lingered to give 10300 * time for apps to gracefully migrate their connections. When both networks are on the same 10301 * radio, but that radio can't do time-sharing efficiently, this may end up being 10302 * counter-productive because any traffic on the old network may drastically reduce the 10303 * performance of the new network. 10304 * The stack supports a configuration to let modem vendors state that their radio can't 10305 * do time-sharing efficiently. If this configuration is set, the stack assumes moving 10306 * from one cell network to another can't be done gracefully. 10307 * 10308 * @param oldNai the old network serving the request 10309 * @param newNai the new network serving the request 10310 * @return whether the switch can be graceful 10311 */ 10312 private boolean canSupportGracefulNetworkSwitch(@NonNull final NetworkAgentInfo oldSatisfier, 10313 @NonNull final NetworkAgentInfo newSatisfier) { 10314 if (mCellularRadioTimesharingCapable) return true; 10315 return !oldSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 10316 || !newSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 10317 || !newSatisfier.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY); 10318 } 10319 10320 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 10321 if (nai.numRequestNetworkRequests() != 0) { 10322 for (int i = 0; i < nai.numNetworkRequests(); i++) { 10323 NetworkRequest nr = nai.requestAt(i); 10324 // Ignore listening and track default requests. 10325 if (!nr.isRequest()) continue; 10326 loge("Dead network still had at least " + nr); 10327 break; 10328 } 10329 } 10330 nai.disconnect(); 10331 } 10332 10333 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 10334 if (oldNetwork == null) { 10335 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 10336 return; 10337 } 10338 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString()); 10339 10340 // If we get here it means that the last linger timeout for this network expired. So there 10341 // must be no other active linger timers, and we must stop lingering. 10342 oldNetwork.clearInactivityState(); 10343 10344 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 10345 // Tear the network down. 10346 teardownUnneededNetwork(oldNetwork); 10347 } else { 10348 // Put the network in the background if it doesn't satisfy any foreground request. 10349 updateCapabilitiesForNetwork(oldNetwork); 10350 } 10351 } 10352 10353 private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) { 10354 boolean isDefaultChanged = false; 10355 for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) { 10356 final NetworkReassignment.RequestReassignment reassignment = 10357 changes.getReassignment(defaultRequestInfo); 10358 if (null == reassignment) { 10359 continue; 10360 } 10361 // reassignment only contains those instances where the satisfying network changed. 10362 isDefaultChanged = true; 10363 // Notify system services of the new default. 10364 makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork); 10365 } 10366 10367 if (isDefaultChanged) { 10368 // Hold a wakelock for a short time to help apps in migrating to a new default. 10369 scheduleReleaseNetworkTransitionWakelock(); 10370 } 10371 } 10372 10373 private void resetHttpProxyForNonDefaultNetwork(NetworkAgentInfo oldDefaultNetwork) { 10374 if (null == oldDefaultNetwork) return; 10375 // The network stopped being the default. If it was using a PAC proxy, then the 10376 // proxy needs to be reset, otherwise HTTP requests on this network may be sent 10377 // to the local proxy server, which would forward them over the newly default network. 10378 final ProxyInfo proxyInfo = oldDefaultNetwork.linkProperties.getHttpProxy(); 10379 if (null == proxyInfo || !proxyInfo.isPacProxy()) return; 10380 oldDefaultNetwork.linkProperties.setHttpProxy(new ProxyInfo(proxyInfo.getPacFileUrl())); 10381 notifyNetworkCallbacks(oldDefaultNetwork, CALLBACK_IP_CHANGED); 10382 } 10383 10384 private void makeDefault(@NonNull final NetworkRequestInfo nri, 10385 @Nullable final NetworkAgentInfo oldDefaultNetwork, 10386 @Nullable final NetworkAgentInfo newDefaultNetwork) { 10387 if (DBG) { 10388 log("Switching to new default network for: " + nri + " using " + newDefaultNetwork); 10389 } 10390 10391 // Fix up the NetworkCapabilities of any networks that have this network as underlying. 10392 if (newDefaultNetwork != null) { 10393 propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network); 10394 } 10395 10396 // Set an app level managed default and return since further processing only applies to the 10397 // default network. 10398 if (mDefaultRequest != nri) { 10399 makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork); 10400 return; 10401 } 10402 10403 makeDefaultNetwork(newDefaultNetwork); 10404 10405 if (oldDefaultNetwork != null) { 10406 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork); 10407 } 10408 mNetworkActivityTracker.updateDefaultNetwork(newDefaultNetwork, oldDefaultNetwork); 10409 maybeDestroyPendingSockets(newDefaultNetwork, oldDefaultNetwork); 10410 mProxyTracker.setDefaultProxy(null != newDefaultNetwork 10411 ? newDefaultNetwork.linkProperties.getHttpProxy() : null); 10412 resetHttpProxyForNonDefaultNetwork(oldDefaultNetwork); 10413 updateTcpBufferSizes(null != newDefaultNetwork 10414 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null); 10415 notifyIfacesChangedForNetworkStats(); 10416 } 10417 10418 private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri, 10419 @Nullable final NetworkAgentInfo oldDefaultNetwork, 10420 @Nullable final NetworkAgentInfo newDefaultNetwork) { 10421 try { 10422 if (VDBG) { 10423 log("Setting default network for " + nri 10424 + " using UIDs " + nri.getUids() 10425 + " with old network " + (oldDefaultNetwork != null 10426 ? oldDefaultNetwork.network().getNetId() : "null") 10427 + " and new network " + (newDefaultNetwork != null 10428 ? newDefaultNetwork.network().getNetId() : "null")); 10429 } 10430 if (nri.getUids().isEmpty()) { 10431 throw new IllegalStateException("makeDefaultForApps called without specifying" 10432 + " any applications to set as the default." + nri); 10433 } 10434 if (null != newDefaultNetwork) { 10435 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 10436 newDefaultNetwork.network.getNetId(), 10437 toUidRangeStableParcels(nri.getUids()), 10438 nri.getPreferenceOrderForNetd())); 10439 } 10440 if (null != oldDefaultNetwork) { 10441 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 10442 oldDefaultNetwork.network.getNetId(), 10443 toUidRangeStableParcels(nri.getUids()), 10444 nri.getPreferenceOrderForNetd())); 10445 } 10446 } catch (RemoteException | ServiceSpecificException e) { 10447 loge("Exception setting app default network", e); 10448 } 10449 } 10450 10451 /** 10452 * Collect restricted uid ranges for the given network and UserHandle, these uids 10453 * are not restricted for matched enterprise networks but being restricted for non-matched 10454 * enterprise networks and non-enterprise networks. 10455 */ 10456 @NonNull 10457 private ArraySet<UidRange> getRestrictedUidRangesForEnterpriseBlocking( 10458 @NonNull NetworkAgentInfo nai, @NonNull UserHandle user) { 10459 final ArraySet<UidRange> restrictedUidRanges = new ArraySet<>(); 10460 for (final ProfileNetworkPreferenceInfo pref : mProfileNetworkPreferences) { 10461 if (!pref.user.equals(user) || !pref.blockingNonEnterprise) continue; 10462 10463 if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_ENTERPRISE)) { 10464 // The NC is built from a `ProfileNetworkPreference` which has only one 10465 // enterprise ID, so it's guaranteed to have exactly one. 10466 final int prefId = pref.capabilities.getEnterpriseIds()[0]; 10467 if (nai.networkCapabilities.hasEnterpriseId(prefId)) { 10468 continue; 10469 } 10470 } 10471 10472 if (UidRangeUtils.doesRangeSetOverlap(restrictedUidRanges, 10473 pref.capabilities.getUidRanges())) { 10474 throw new IllegalArgumentException( 10475 "Overlapping uid range in preference: " + pref); 10476 } 10477 restrictedUidRanges.addAll(pref.capabilities.getUidRanges()); 10478 } 10479 return restrictedUidRanges; 10480 } 10481 10482 private void updateProfileAllowedNetworks() { 10483 // Netd command is not implemented before U. 10484 if (!mDeps.isAtLeastU()) return; 10485 10486 ensureRunningOnConnectivityServiceThread(); 10487 final ArrayList<NativeUidRangeConfig> configs = new ArrayList<>(); 10488 final List<UserHandle> users = mContext.getSystemService(UserManager.class) 10489 .getUserHandles(true /* excludeDying */); 10490 if (users.isEmpty()) { 10491 throw new IllegalStateException("No user is available"); 10492 } 10493 10494 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 10495 ArraySet<UidRange> allowedUidRanges = new ArraySet<>(); 10496 for (final UserHandle user : users) { 10497 final ArraySet<UidRange> restrictedUidRanges = 10498 getRestrictedUidRangesForEnterpriseBlocking(nai, user); 10499 allowedUidRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 10500 UidRange.createForUser(user), restrictedUidRanges)); 10501 } 10502 10503 final UidRangeParcel[] rangesParcel = toUidRangeStableParcels(allowedUidRanges); 10504 configs.add(new NativeUidRangeConfig( 10505 nai.network.netId, rangesParcel, 0 /* subPriority */)); 10506 } 10507 10508 // The netd API replaces the previous configs with the current configs. 10509 // Thus, for network disconnection or preference removal, no need to 10510 // unset previous config. Instead, collecting all currently needed 10511 // configs and issue to netd. 10512 try { 10513 mNetd.setNetworkAllowlist(configs.toArray(new NativeUidRangeConfig[0])); 10514 } catch (ServiceSpecificException e) { 10515 // Has the interface disappeared since the network was built? 10516 Log.wtf(TAG, "Unexpected ServiceSpecificException", e); 10517 } catch (RemoteException e) { 10518 // Netd died. This will cause a runtime restart anyway. 10519 Log.wtf(TAG, "Unexpected RemoteException", e); 10520 } 10521 } 10522 10523 private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) { 10524 try { 10525 if (null != newDefaultNetwork) { 10526 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId()); 10527 } else { 10528 mNetd.networkClearDefault(); 10529 } 10530 } catch (RemoteException | ServiceSpecificException e) { 10531 loge("Exception setting default network :" + e); 10532 } 10533 } 10534 10535 private void processListenRequests(@NonNull final NetworkAgentInfo nai) { 10536 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 10537 processNewlyLostListenRequests(nai); 10538 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 10539 processNewlySatisfiedListenRequests(nai); 10540 } 10541 10542 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) { 10543 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 10544 if (nri.isMultilayerRequest()) { 10545 continue; 10546 } 10547 final NetworkRequest nr = nri.mRequests.get(0); 10548 if (!nr.isListen()) continue; 10549 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 10550 nai.removeRequest(nr.requestId); 10551 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0); 10552 } 10553 } 10554 } 10555 10556 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) { 10557 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 10558 if (nri.isMultilayerRequest()) { 10559 continue; 10560 } 10561 final NetworkRequest nr = nri.mRequests.get(0); 10562 if (!nr.isListen()) continue; 10563 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 10564 nai.addRequest(nr); 10565 notifyNetworkAvailable(nai, nri); 10566 } 10567 } 10568 } 10569 10570 // An accumulator class to gather the list of changes that result from a rematch. 10571 private static class NetworkReassignment { 10572 static class RequestReassignment { 10573 @NonNull public final NetworkRequestInfo mNetworkRequestInfo; 10574 @Nullable public final NetworkRequest mOldNetworkRequest; 10575 @Nullable public final NetworkRequest mNewNetworkRequest; 10576 @Nullable public final NetworkAgentInfo mOldNetwork; 10577 @Nullable public final NetworkAgentInfo mNewNetwork; 10578 RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo, 10579 @Nullable final NetworkRequest oldNetworkRequest, 10580 @Nullable final NetworkRequest newNetworkRequest, 10581 @Nullable final NetworkAgentInfo oldNetwork, 10582 @Nullable final NetworkAgentInfo newNetwork) { 10583 mNetworkRequestInfo = networkRequestInfo; 10584 mOldNetworkRequest = oldNetworkRequest; 10585 mNewNetworkRequest = newNetworkRequest; 10586 mOldNetwork = oldNetwork; 10587 mNewNetwork = newNetwork; 10588 } 10589 10590 public String toString() { 10591 final NetworkRequest requestToShow = null != mNewNetworkRequest 10592 ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0); 10593 return requestToShow.requestId + " : " 10594 + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null") 10595 + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null"); 10596 } 10597 } 10598 10599 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>(); 10600 10601 @NonNull Iterable<RequestReassignment> getRequestReassignments() { 10602 return mReassignments; 10603 } 10604 10605 void addRequestReassignment(@NonNull final RequestReassignment reassignment) { 10606 if (Build.isDebuggable()) { 10607 // The code is never supposed to add two reassignments of the same request. Make 10608 // sure this stays true, but without imposing this expensive check on all 10609 // reassignments on all user devices. 10610 for (final RequestReassignment existing : mReassignments) { 10611 if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) { 10612 throw new IllegalStateException("Trying to reassign [" 10613 + reassignment + "] but already have [" 10614 + existing + "]"); 10615 } 10616 } 10617 } 10618 mReassignments.add(reassignment); 10619 } 10620 10621 // Will return null if this reassignment does not change the network assigned to 10622 // the passed request. 10623 @Nullable 10624 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) { 10625 for (final RequestReassignment event : getRequestReassignments()) { 10626 if (nri == event.mNetworkRequestInfo) return event; 10627 } 10628 return null; 10629 } 10630 10631 public String toString() { 10632 final StringJoiner sj = new StringJoiner(", " /* delimiter */, 10633 "NetReassign [" /* prefix */, "]" /* suffix */); 10634 if (mReassignments.isEmpty()) return sj.add("no changes").toString(); 10635 for (final RequestReassignment rr : getRequestReassignments()) { 10636 sj.add(rr.toString()); 10637 } 10638 return sj.toString(); 10639 } 10640 10641 public String debugString() { 10642 final StringBuilder sb = new StringBuilder(); 10643 sb.append("NetworkReassignment :"); 10644 if (mReassignments.isEmpty()) return sb.append(" no changes").toString(); 10645 for (final RequestReassignment rr : getRequestReassignments()) { 10646 sb.append("\n ").append(rr); 10647 } 10648 return sb.append("\n").toString(); 10649 } 10650 } 10651 10652 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri, 10653 @Nullable final NetworkRequest previousRequest, 10654 @Nullable final NetworkRequest newRequest, 10655 @Nullable final NetworkAgentInfo previousSatisfier, 10656 @Nullable final NetworkAgentInfo newSatisfier, 10657 final long now) { 10658 if (null != newSatisfier && mNoServiceNetwork != newSatisfier) { 10659 if (VDBG) log("rematch for " + newSatisfier.toShortString()); 10660 if (null != previousRequest && null != previousSatisfier) { 10661 if (VDBG || DDBG) { 10662 log(" accepting network in place of " + previousSatisfier.toShortString() 10663 + " for " + newRequest); 10664 } 10665 previousSatisfier.removeRequest(previousRequest.requestId); 10666 if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier) 10667 && !previousSatisfier.isDestroyed()) { 10668 // If this network switch can't be supported gracefully, the request is not 10669 // lingered. This allows letting go of the network sooner to reclaim some 10670 // performance on the new network, since the radio can't do both at the same 10671 // time while preserving good performance. 10672 // 10673 // Also don't linger the request if the old network has been destroyed. 10674 // A destroyed network does not provide actual network connectivity, so 10675 // lingering it is not useful. In particular this ensures that a destroyed 10676 // network is outscored by its replacement, 10677 // then it is torn down immediately instead of being lingered, and any apps that 10678 // were using it immediately get onLost and can connect using the new network. 10679 previousSatisfier.lingerRequest(previousRequest.requestId, now); 10680 } 10681 } else { 10682 if (VDBG || DDBG) log(" accepting network in place of null for " + newRequest); 10683 } 10684 10685 // To prevent constantly CPU wake up for nascent timer, if a network comes up 10686 // and immediately satisfies a request then remove the timer. This will happen for 10687 // all networks except in the case of an underlying network for a VCN. 10688 if (newSatisfier.isNascent()) { 10689 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE); 10690 newSatisfier.unsetInactive(); 10691 } 10692 10693 // if newSatisfier is not null, then newRequest may not be null. 10694 newSatisfier.unlingerRequest(newRequest.requestId); 10695 if (!newSatisfier.addRequest(newRequest)) { 10696 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has " 10697 + newRequest); 10698 } 10699 } else if (null != previousRequest && null != previousSatisfier) { 10700 if (DBG) { 10701 log("Network " + previousSatisfier.toShortString() + " stopped satisfying" 10702 + " request " + previousRequest.requestId); 10703 } 10704 previousSatisfier.removeRequest(previousRequest.requestId); 10705 } 10706 nri.setSatisfier(newSatisfier, newRequest); 10707 } 10708 10709 /** 10710 * This function is triggered when something can affect what network should satisfy what 10711 * request, and it computes the network reassignment from the passed collection of requests to 10712 * network match to the one that the system should now have. That data is encoded in an 10713 * object that is a list of changes, each of them having an NRI, and old satisfier, and a new 10714 * satisfier. 10715 * 10716 * After the reassignment is computed, it is applied to the state objects. 10717 * 10718 * @param networkRequests the nri objects to evaluate for possible network reassignment 10719 * @return NetworkReassignment listing of proposed network assignment changes 10720 */ 10721 @NonNull 10722 private NetworkReassignment computeNetworkReassignment( 10723 @NonNull final Collection<NetworkRequestInfo> networkRequests) { 10724 final NetworkReassignment changes = new NetworkReassignment(); 10725 10726 // Gather the list of all relevant agents. 10727 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>(); 10728 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 10729 nais.add(nai); 10730 } 10731 10732 for (final NetworkRequestInfo nri : networkRequests) { 10733 // Non-multilayer listen requests can be ignored. 10734 if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) { 10735 continue; 10736 } 10737 NetworkAgentInfo bestNetwork = null; 10738 NetworkRequest bestRequest = null; 10739 for (final NetworkRequest req : nri.mRequests) { 10740 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier()); 10741 // Stop evaluating as the highest possible priority request is satisfied. 10742 if (null != bestNetwork) { 10743 bestRequest = req; 10744 break; 10745 } 10746 } 10747 if (null == bestNetwork && isDefaultBlocked(nri)) { 10748 // Remove default networking if disallowed for managed default requests. 10749 bestNetwork = mNoServiceNetwork; 10750 } 10751 if (nri.getSatisfier() != bestNetwork) { 10752 // bestNetwork may be null if no network can satisfy this request. 10753 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( 10754 nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork)); 10755 } 10756 } 10757 return changes; 10758 } 10759 10760 private Set<NetworkRequestInfo> getNrisFromGlobalRequests() { 10761 return new HashSet<>(mNetworkRequests.values()); 10762 } 10763 10764 /** 10765 * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks 10766 * being disconnected. 10767 */ 10768 private void rematchAllNetworksAndRequests() { 10769 rematchNetworksAndRequests(getNrisFromGlobalRequests()); 10770 } 10771 10772 /** 10773 * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks 10774 * being disconnected. 10775 */ 10776 private void rematchNetworksAndRequests( 10777 @NonNull final Set<NetworkRequestInfo> networkRequests) { 10778 ensureRunningOnConnectivityServiceThread(); 10779 // TODO: This may be slow, and should be optimized. 10780 final long start = SystemClock.elapsedRealtime(); 10781 final NetworkReassignment changes = computeNetworkReassignment(networkRequests); 10782 final long computed = SystemClock.elapsedRealtime(); 10783 applyNetworkReassignment(changes, start); 10784 final long applied = SystemClock.elapsedRealtime(); 10785 issueNetworkNeeds(); 10786 final long end = SystemClock.elapsedRealtime(); 10787 if (VDBG || DDBG) { 10788 log(String.format("Rematched networks [computed %dms] [applied %dms] [issued %d]", 10789 computed - start, applied - computed, end - applied)); 10790 log(changes.debugString()); 10791 } else if (DBG) { 10792 // Shorter form, only one line of log 10793 log(String.format("%s [c %d] [a %d] [i %d]", changes.toString(), 10794 computed - start, applied - computed, end - applied)); 10795 } 10796 } 10797 10798 private boolean hasSameInterfaceName(@Nullable final NetworkAgentInfo nai1, 10799 @Nullable final NetworkAgentInfo nai2) { 10800 if (null == nai1) return null == nai2; 10801 if (null == nai2) return false; 10802 return nai1.linkProperties.getInterfaceName() 10803 .equals(nai2.linkProperties.getInterfaceName()); 10804 } 10805 10806 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes, 10807 final long now) { 10808 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos; 10809 10810 // Since most of the time there are only 0 or 1 background networks, it would probably 10811 // be more efficient to just use an ArrayList here. TODO : measure performance 10812 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>(); 10813 for (final NetworkAgentInfo nai : nais) { 10814 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai); 10815 } 10816 10817 // First, update the lists of satisfied requests in the network agents. This is necessary 10818 // because some code later depends on this state to be correct, most prominently computing 10819 // the linger status. 10820 for (final NetworkReassignment.RequestReassignment event : 10821 changes.getRequestReassignments()) { 10822 updateSatisfiersForRematchRequest(event.mNetworkRequestInfo, 10823 event.mOldNetworkRequest, event.mNewNetworkRequest, 10824 event.mOldNetwork, event.mNewNetwork, 10825 now); 10826 } 10827 10828 // Process default network changes if applicable. 10829 processDefaultNetworkChanges(changes); 10830 10831 // Update forwarding rules for the upstreams of local networks. Do this before sending 10832 // onAvailable so that by the time onAvailable is sent the forwarding rules are set up. 10833 // Don't send CALLBACK_LOCAL_NETWORK_INFO_CHANGED yet though : they should be sent after 10834 // onAvailable so clients know what network the change is about. Store such changes in 10835 // an array that's only allocated if necessary (because it's almost never necessary). 10836 ArrayList<NetworkAgentInfo> localInfoChangedAgents = null; 10837 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 10838 if (!nai.isLocalNetwork()) continue; 10839 final NetworkRequest nr = nai.localNetworkConfig.getUpstreamSelector(); 10840 if (null == nr) continue; // No upstream for this local network 10841 final NetworkRequestInfo nri = mNetworkRequests.get(nr); 10842 final NetworkReassignment.RequestReassignment change = changes.getReassignment(nri); 10843 if (null == change) continue; // No change in upstreams for this network 10844 final String fromIface = nai.linkProperties.getInterfaceName(); 10845 if (!hasSameInterfaceName(change.mOldNetwork, change.mNewNetwork) 10846 || change.mOldNetwork.isDestroyed()) { 10847 // There can be a change with the same interface name if the new network is the 10848 // replacement for the old network that was unregisteredAfterReplacement. 10849 try { 10850 if (null != change.mOldNetwork) { 10851 mRoutingCoordinatorService.removeInterfaceForward(fromIface, 10852 change.mOldNetwork.linkProperties.getInterfaceName()); 10853 disableMulticastRouting(fromIface, 10854 change.mOldNetwork.linkProperties.getInterfaceName()); 10855 } 10856 // If the new upstream is already destroyed, there is no point in setting up 10857 // a forward (in fact, it might forward to the interface for some new network !) 10858 // Later when the upstream disconnects CS will try to remove the forward, which 10859 // is ignored with a benign log by RoutingCoordinatorService. 10860 if (null != change.mNewNetwork && !change.mNewNetwork.isDestroyed()) { 10861 mRoutingCoordinatorService.addInterfaceForward(fromIface, 10862 change.mNewNetwork.linkProperties.getInterfaceName()); 10863 applyMulticastRoutingConfig(fromIface, 10864 change.mNewNetwork.linkProperties.getInterfaceName(), 10865 nai.localNetworkConfig); 10866 } 10867 } catch (final RemoteException e) { 10868 loge("Can't update forwarding rules", e); 10869 } 10870 } 10871 if (null == localInfoChangedAgents) localInfoChangedAgents = new ArrayList<>(); 10872 localInfoChangedAgents.add(nai); 10873 } 10874 10875 // Notify requested networks are available after the default net is switched, but 10876 // before LegacyTypeTracker sends legacy broadcasts 10877 for (final NetworkReassignment.RequestReassignment event : 10878 changes.getRequestReassignments()) { 10879 if (null != event.mNewNetwork) { 10880 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo); 10881 } else { 10882 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork, 10883 ConnectivityManager.CALLBACK_LOST, 0); 10884 } 10885 } 10886 10887 // Update the inactivity state before processing listen callbacks, because the background 10888 // computation depends on whether the network is inactive. Don't send the LOSING callbacks 10889 // just yet though, because they have to be sent after the listens are processed to keep 10890 // backward compatibility. 10891 final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>(); 10892 for (final NetworkAgentInfo nai : nais) { 10893 // Rematching may have altered the inactivity state of some networks, so update all 10894 // inactivity timers. updateInactivityState reads the state from the network agent 10895 // and does nothing if the state has not changed : the source of truth is controlled 10896 // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which 10897 // have been called while rematching the individual networks above. 10898 if (updateInactivityState(nai, now)) { 10899 inactiveNetworks.add(nai); 10900 } 10901 } 10902 10903 for (final NetworkAgentInfo nai : nais) { 10904 final boolean oldBackground = oldBgNetworks.contains(nai); 10905 // Process listen requests and update capabilities if the background state has 10906 // changed for this network. For consistency with previous behavior, send onLost 10907 // callbacks before onAvailable. 10908 processNewlyLostListenRequests(nai); 10909 if (oldBackground != nai.isBackgroundNetwork()) { 10910 applyBackgroundChangeForRematch(nai); 10911 } 10912 processNewlySatisfiedListenRequests(nai); 10913 } 10914 10915 for (final NetworkAgentInfo nai : inactiveNetworks) { 10916 // For nascent networks, if connecting with no foreground request, skip broadcasting 10917 // LOSING for backward compatibility. This is typical when mobile data connected while 10918 // wifi connected with mobile data always-on enabled. 10919 if (nai.isNascent()) continue; 10920 notifyNetworkLosing(nai, now); 10921 } 10922 10923 // Send LOCAL_NETWORK_INFO_CHANGED callbacks now that onAvailable and onLost have been sent. 10924 if (null != localInfoChangedAgents) { 10925 for (final NetworkAgentInfo nai : localInfoChangedAgents) { 10926 notifyNetworkCallbacks(nai, 10927 ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 10928 } 10929 } 10930 10931 updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais); 10932 10933 // Tear down all unneeded networks. 10934 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 10935 if (unneeded(nai, UnneededFor.TEARDOWN)) { 10936 if (nai.getInactivityExpiry() > 0) { 10937 // This network has active linger timers and no requests, but is not 10938 // lingering. Linger it. 10939 // 10940 // One way (the only way?) this can happen if this network is unvalidated 10941 // and became unneeded due to another network improving its score to the 10942 // point where this network will no longer be able to satisfy any requests 10943 // even if it validates. 10944 if (updateInactivityState(nai, now)) { 10945 notifyNetworkLosing(nai, now); 10946 } 10947 } else { 10948 if (DBG) log("Reaping " + nai.toShortString()); 10949 teardownUnneededNetwork(nai); 10950 } 10951 } 10952 } 10953 } 10954 10955 /** 10956 * Apply a change in background state resulting from rematching networks with requests. 10957 * 10958 * During rematch, a network may change background states by starting to satisfy or stopping 10959 * to satisfy a foreground request. Listens don't count for this. When a network changes 10960 * background states, its capabilities need to be updated and callbacks fired for the 10961 * capability change. 10962 * 10963 * @param nai The network that changed background states 10964 */ 10965 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) { 10966 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities); 10967 if (Objects.equals(nai.networkCapabilities, newNc)) return; 10968 updateNetworkPermissions(nai, newNc); 10969 nai.getAndSetNetworkCapabilities(newNc); 10970 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 10971 } 10972 10973 private void updateLegacyTypeTrackerAndVpnLockdownForRematch( 10974 @NonNull final NetworkReassignment changes, 10975 @NonNull final Collection<NetworkAgentInfo> nais) { 10976 final NetworkReassignment.RequestReassignment reassignmentOfDefault = 10977 changes.getReassignment(mDefaultRequest); 10978 final NetworkAgentInfo oldDefaultNetwork = 10979 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null; 10980 final NetworkAgentInfo newDefaultNetwork = 10981 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null; 10982 10983 if (oldDefaultNetwork != newDefaultNetwork) { 10984 // Maintain the illusion : since the legacy API only understands one network at a time, 10985 // if the default network changed, apps should see a disconnected broadcast for the 10986 // old default network before they see a connected broadcast for the new one. 10987 if (oldDefaultNetwork != null) { 10988 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 10989 oldDefaultNetwork, true); 10990 } 10991 if (newDefaultNetwork != null) { 10992 // The new default network can be newly null if and only if the old default 10993 // network doesn't satisfy the default request any more because it lost a 10994 // capability. 10995 mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0; 10996 mLegacyTypeTracker.add( 10997 newDefaultNetwork.networkInfo.getType(), newDefaultNetwork); 10998 } 10999 } 11000 11001 // Now that all the callbacks have been sent, send the legacy network broadcasts 11002 // as needed. This is necessary so that legacy requests correctly bind dns 11003 // requests to this network. The legacy users are listening for this broadcast 11004 // and will generally do a dns request so they can ensureRouteToHost and if 11005 // they do that before the callbacks happen they'll use the default network. 11006 // 11007 // TODO: Is there still a race here? The legacy broadcast will be sent after sending 11008 // callbacks, but if apps can receive the broadcast before the callback, they still might 11009 // have an inconsistent view of networking. 11010 // 11011 // This *does* introduce a race where if the user uses the new api 11012 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 11013 // they may get old info. Reverse this after the old startUsing api is removed. 11014 // This is on top of the multiple intent sequencing referenced in the todo above. 11015 for (NetworkAgentInfo nai : nais) { 11016 if (nai.everConnected()) { 11017 addNetworkToLegacyTypeTracker(nai); 11018 } 11019 } 11020 } 11021 11022 private void issueNetworkNeeds() { 11023 ensureRunningOnConnectivityServiceThread(); 11024 for (final NetworkOfferInfo noi : mNetworkOffers) { 11025 issueNetworkNeeds(noi); 11026 } 11027 } 11028 11029 private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) { 11030 ensureRunningOnConnectivityServiceThread(); 11031 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 11032 informOffer(nri, noi.offer, mNetworkRanker); 11033 } 11034 } 11035 11036 /** 11037 * Inform a NetworkOffer about any new situation of a request. 11038 * 11039 * This function handles updates to offers. A number of events may happen that require 11040 * updating the registrant for this offer about the situation : 11041 * • The offer itself was updated. This may lead the offer to no longer being able 11042 * to satisfy a request or beat a satisfier (and therefore be no longer needed), 11043 * or conversely being strengthened enough to beat the satisfier (and therefore 11044 * start being needed) 11045 * • The network satisfying a request changed (including cases where the request 11046 * starts or stops being satisfied). The new network may be a stronger or weaker 11047 * match than the old one, possibly affecting whether the offer is needed. 11048 * • The network satisfying a request updated their score. This may lead the offer 11049 * to no longer be able to beat it if the current satisfier got better, or 11050 * conversely start being a good choice if the current satisfier got weaker. 11051 * 11052 * @param nri The request 11053 * @param offer The offer. This may be an updated offer. 11054 */ 11055 private static void informOffer(@NonNull NetworkRequestInfo nri, 11056 @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) { 11057 final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null; 11058 final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null; 11059 11060 // Multi-layer requests have a currently active request, the one being satisfied. 11061 // Since the system will try to bring up a better network than is currently satisfying 11062 // the request, NetworkProviders need to be told the offers matching the requests *above* 11063 // the currently satisfied one are needed, that the ones *below* the satisfied one are 11064 // not needed, and the offer is needed for the active request iff the offer can beat 11065 // the satisfier. 11066 // For non-multilayer requests, the logic above gracefully degenerates to only the 11067 // last case. 11068 // To achieve this, the loop below will proceed in three steps. In a first phase, inform 11069 // providers that the offer is needed for this request, until the active request is found. 11070 // In a second phase, deal with the currently active request. In a third phase, inform 11071 // the providers that offer is unneeded for the remaining requests. 11072 11073 // First phase : inform providers of all requests above the active request. 11074 int i; 11075 for (i = 0; nri.mRequests.size() > i; ++i) { 11076 final NetworkRequest request = nri.mRequests.get(i); 11077 if (activeRequest == request) break; // Found the active request : go to phase 2 11078 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 11079 // Since this request is higher-priority than the one currently satisfied, if the 11080 // offer can satisfy it, the provider should try and bring up the network for sure ; 11081 // no need to even ask the ranker – an offer that can satisfy is always better than 11082 // no network. Hence tell the provider so unless it already knew. 11083 if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) { 11084 offer.onNetworkNeeded(request); 11085 } 11086 } 11087 11088 // Second phase : deal with the active request (if any) 11089 if (null != activeRequest && activeRequest.isRequest()) { 11090 final boolean oldNeeded = offer.neededFor(activeRequest); 11091 // If an offer can satisfy the request, it is considered needed if it is currently 11092 // served by this provider or if this offer can beat the current satisfier. 11093 final boolean currentlyServing = satisfier != null 11094 && satisfier.factorySerialNumber == offer.providerId 11095 && activeRequest.canBeSatisfiedBy(offer.caps); 11096 final boolean newNeeded = currentlyServing 11097 || networkRanker.mightBeat(activeRequest, satisfier, offer); 11098 if (newNeeded != oldNeeded) { 11099 if (newNeeded) { 11100 offer.onNetworkNeeded(activeRequest); 11101 } else { 11102 // The offer used to be able to beat the satisfier. Now it can't. 11103 offer.onNetworkUnneeded(activeRequest); 11104 } 11105 } 11106 } 11107 11108 // Third phase : inform the providers that the offer isn't needed for any request 11109 // below the active one. 11110 for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) { 11111 final NetworkRequest request = nri.mRequests.get(i); 11112 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 11113 // Since this request is lower-priority than the one currently satisfied, if the 11114 // offer can satisfy it, the provider should not try and bring up the network. 11115 // Hence tell the provider so unless it already knew. 11116 if (offer.neededFor(request)) { 11117 offer.onNetworkUnneeded(request); 11118 } 11119 } 11120 } 11121 11122 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) { 11123 for (int i = 0; i < nai.numNetworkRequests(); i++) { 11124 NetworkRequest nr = nai.requestAt(i); 11125 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 11126 // legacy type tracker filters out repeat adds 11127 mLegacyTypeTracker.add(nr.legacyType, nai); 11128 } 11129 } 11130 11131 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 11132 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 11133 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 11134 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 11135 if (nai.isVPN()) { 11136 mLegacyTypeTracker.add(TYPE_VPN, nai); 11137 } 11138 } 11139 11140 private void updateInetCondition(NetworkAgentInfo nai) { 11141 // Don't bother updating until we've graduated to validated at least once. 11142 if (!nai.everValidated()) return; 11143 // For now only update icons for the default connection. 11144 // TODO: Update WiFi and cellular icons separately. b/17237507 11145 if (!isDefaultNetwork(nai)) return; 11146 11147 int newInetCondition = nai.isValidated() ? 100 : 0; 11148 // Don't repeat publish. 11149 if (newInetCondition == mDefaultInetConditionPublished) return; 11150 11151 mDefaultInetConditionPublished = newInetCondition; 11152 sendInetConditionBroadcast(nai.networkInfo); 11153 } 11154 11155 @NonNull 11156 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) { 11157 final NetworkInfo newInfo = new NetworkInfo(info); 11158 // The suspended and roaming bits are managed in NetworkCapabilities. 11159 final boolean suspended = 11160 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 11161 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) { 11162 // Only override the state with SUSPENDED if the network is currently in CONNECTED 11163 // state. This is because the network could have been suspended before connecting, 11164 // or it could be disconnecting while being suspended, and in both these cases 11165 // the state should not be overridden. Note that the only detailed state that 11166 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to 11167 // worry about multiple different substates of CONNECTED. 11168 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(), 11169 info.getExtraInfo()); 11170 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) { 11171 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the 11172 // network agent is created, then goes to suspended, then goes out of suspended without 11173 // ever setting connected. Check if network agent is ever connected to update the state. 11174 newInfo.setDetailedState(nai.everConnected() 11175 ? NetworkInfo.DetailedState.CONNECTED 11176 : NetworkInfo.DetailedState.CONNECTING, 11177 info.getReason(), 11178 info.getExtraInfo()); 11179 } 11180 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 11181 return newInfo; 11182 } 11183 11184 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) { 11185 final NetworkInfo newInfo = mixInInfo(networkAgent, info); 11186 11187 final NetworkInfo.State state = newInfo.getState(); 11188 NetworkInfo oldInfo = null; 11189 synchronized (networkAgent) { 11190 oldInfo = networkAgent.networkInfo; 11191 networkAgent.networkInfo = newInfo; 11192 } 11193 11194 if (DBG) { 11195 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from " 11196 + oldInfo.getState() + " to " + state); 11197 } 11198 11199 if (shouldCreateNativeNetwork(networkAgent, state)) { 11200 // A network that has just connected has zero requests and is thus a foreground network. 11201 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 11202 11203 if (!createNativeNetwork(networkAgent)) return; 11204 11205 networkAgent.setCreated(); 11206 11207 // If the network is created immediately on register, then apply the LinkProperties now. 11208 // Otherwise, this is done further down when the network goes into connected state. 11209 // Applying the LinkProperties means that the network is ready to carry traffic - 11210 // interfaces and routing rules have been added, DNS servers programmed, etc. 11211 // For VPNs, this must be done before the capabilities are updated, because as soon as 11212 // that happens, UIDs are routed to the network. 11213 if (shouldCreateNetworksImmediately()) { 11214 applyInitialLinkProperties(networkAgent); 11215 } 11216 11217 // TODO: should this move earlier? It doesn't seem to have anything to do with whether 11218 // a network is created or not. 11219 if (networkAgent.propagateUnderlyingCapabilities()) { 11220 // Initialize the network's capabilities to their starting values according to the 11221 // underlying networks. This ensures that the capabilities are correct before 11222 // anything happens to the network. 11223 updateCapabilitiesForNetwork(networkAgent); 11224 } 11225 networkAgent.onNetworkCreated(); 11226 updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities); 11227 updateProfileAllowedNetworks(); 11228 } 11229 11230 if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) { 11231 networkAgent.setConnected(); 11232 11233 // NetworkCapabilities need to be set before sending the private DNS config to 11234 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required. 11235 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities); 11236 11237 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 11238 if (!shouldCreateNetworksImmediately()) { 11239 applyInitialLinkProperties(networkAgent); 11240 } else { 11241 // The network was created when the agent registered, and the LinkProperties are 11242 // already up-to-date. However, updateLinkProperties also makes some changes only 11243 // when the network connects. Apply those changes here. On T and below these are 11244 // handled by the applyInitialLinkProperties call just above. 11245 // TODO: stop relying on updateLinkProperties(..., null) to do this. 11246 // If something depends on both LinkProperties and connected state, it should be in 11247 // this method as well. 11248 networkAgent.clatd.update(); 11249 updateProxy(networkAgent.linkProperties, null); 11250 } 11251 11252 // If a rate limit has been configured and is applicable to this network (network 11253 // provides internet connectivity), apply it. The tc police filter cannot be attached 11254 // before the clsact qdisc is added which happens as part of updateLinkProperties -> 11255 // updateInterfaces -> RoutingCoordinatorManager#addInterfaceToNetwork 11256 // Note: in case of a system server crash, the NetworkController constructor in netd 11257 // (called when netd starts up) deletes the clsact qdisc of all interfaces. 11258 if (canNetworkBeRateLimited(networkAgent) && mIngressRateLimit >= 0) { 11259 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 11260 mIngressRateLimit); 11261 } 11262 11263 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect 11264 // command must be sent after updating LinkProperties to maximize chances of 11265 // NetworkMonitor seeing the correct LinkProperties when starting. 11266 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call. 11267 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) { 11268 networkAgent.networkMonitor().setAcceptPartialConnectivity(); 11269 } 11270 final NetworkMonitorParameters params = new NetworkMonitorParameters(); 11271 params.networkAgentConfig = networkAgent.networkAgentConfig; 11272 params.networkCapabilities = networkAgent.networkCapabilities; 11273 params.linkProperties = new LinkProperties(networkAgent.linkProperties, 11274 true /* parcelSensitiveFields */); 11275 // isAtLeastT() is conservative here, as recent versions of NetworkStack support the 11276 // newer callback even before T. However getInterfaceVersion is a synchronized binder 11277 // call that would cause a Log.wtf to be emitted from the system_server process, and 11278 // in the absence of a satisfactory, scalable solution which follows an easy/standard 11279 // process to check the interface version, just use an SDK check. NetworkStack will 11280 // always be new enough when running on T+. 11281 if (mDeps.isAtLeastT()) { 11282 networkAgent.networkMonitor().notifyNetworkConnected(params); 11283 } else { 11284 networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties, 11285 params.networkCapabilities); 11286 } 11287 final long evaluationDelay; 11288 if (!networkAgent.networkCapabilities.hasSingleTransport(TRANSPORT_WIFI)) { 11289 // If the network is anything other than pure wifi, use the default timeout. 11290 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 11291 } else if (networkAgent.networkAgentConfig.isExplicitlySelected()) { 11292 // If the network is explicitly selected, use the default timeout because it's 11293 // shorter and the user is likely staring at the screen expecting it to validate 11294 // right away. 11295 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 11296 } else if (avoidBadWifi() || !activelyPreferBadWifi()) { 11297 // If avoiding bad wifi, or if not avoiding but also not preferring bad wifi 11298 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 11299 } else { 11300 // It's wifi, automatically connected, and bad wifi is preferred : use the 11301 // longer timeout to avoid the device switching to captive portals with bad 11302 // signal or very slow response. 11303 evaluationDelay = ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS; 11304 } 11305 scheduleEvaluationTimeout(networkAgent.network, evaluationDelay); 11306 11307 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 11308 // be communicated to a particular NetworkAgent depends only on the network's immutable, 11309 // capabilities, so it only needs to be done once on initial connect, not every time the 11310 // network's capabilities change. Note that we do this before rematching the network, 11311 // so we could decide to tear it down immediately afterwards. That's fine though - on 11312 // disconnection NetworkAgents should stop any signal strength monitoring they have been 11313 // doing. 11314 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 11315 11316 // Before first rematching networks, put an inactivity timer without any request, this 11317 // allows {@code updateInactivityState} to update the state accordingly and prevent 11318 // tearing down for any {@code unneeded} evaluation in this period. 11319 // Note that the timer will not be rescheduled since the expiry time is 11320 // fixed after connection regardless of the network satisfying other requests or not. 11321 // But it will be removed as soon as the network satisfies a request for the first time. 11322 networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE, 11323 SystemClock.elapsedRealtime(), mNascentDelayMs); 11324 networkAgent.setInactive(); 11325 11326 if (mTrackMultiNetworkActivities) { 11327 // Start tracking activity of this network. 11328 // This must be called before rematchAllNetworksAndRequests since the network 11329 // should be tracked when the network becomes the default network. 11330 // This method does not trigger any callbacks or broadcasts. Callbacks or broadcasts 11331 // can be triggered later if this network becomes the default network. 11332 mNetworkActivityTracker.setupDataActivityTracking(networkAgent); 11333 } 11334 11335 // Consider network even though it is not yet validated. 11336 rematchAllNetworksAndRequests(); 11337 11338 // This has to happen after matching the requests, because callbacks are just requests. 11339 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 11340 } else if (state == NetworkInfo.State.DISCONNECTED) { 11341 networkAgent.disconnect(); 11342 if (networkAgent.isVPN()) { 11343 updateVpnUids(networkAgent, networkAgent.networkCapabilities, null); 11344 } 11345 disconnectAndDestroyNetwork(networkAgent); 11346 if (networkAgent.isVPN()) { 11347 // As the active or bound network changes for apps, broadcast the default proxy, as 11348 // apps may need to update their proxy data. This is called after disconnecting from 11349 // VPN to make sure we do not broadcast the old proxy data. 11350 // TODO(b/122649188): send the broadcast only to VPN users. 11351 mProxyTracker.sendProxyBroadcast(); 11352 } 11353 } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED 11354 || state == NetworkInfo.State.SUSPENDED)) { 11355 mLegacyTypeTracker.update(networkAgent); 11356 } 11357 } 11358 11359 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { 11360 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); 11361 nai.setScore(score); 11362 rematchAllNetworksAndRequests(); 11363 } 11364 11365 // Notify only this one new request of the current state. Transfer all the 11366 // current state by calling NetworkCapabilities and LinkProperties callbacks 11367 // so that callers can be guaranteed to have as close to atomicity in state 11368 // transfer as can be supported by this current API. 11369 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 11370 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 11371 if (nri.mPendingIntent != null) { 11372 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE); 11373 // Attempt no subsequent state pushes where intents are involved. 11374 return; 11375 } 11376 11377 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 11378 final boolean metered = nai.networkCapabilities.isMetered(); 11379 final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges); 11380 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 11381 getBlockedState(nri.mAsUid, blockedReasons, metered, vpnBlocked)); 11382 } 11383 11384 // Notify the requests on this NAI that the network is now lingered. 11385 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) { 11386 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 11387 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 11388 } 11389 11390 private int getPermissionBlockedState(final int uid, final int reasons) { 11391 // Before V, the blocked reasons come from NPMS, and that code already behaves as if the 11392 // change was disabled: apps without the internet permission will never be told they are 11393 // blocked. 11394 if (!mDeps.isAtLeastV()) return reasons; 11395 11396 if (hasInternetPermission(uid)) return reasons; 11397 11398 return mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid) 11399 ? reasons | BLOCKED_REASON_NETWORK_RESTRICTED 11400 : BLOCKED_REASON_NONE; 11401 } 11402 11403 private int getBlockedState(int uid, int reasons, boolean metered, boolean vpnBlocked) { 11404 reasons = getPermissionBlockedState(uid, reasons); 11405 if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK; 11406 return vpnBlocked 11407 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN 11408 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN; 11409 } 11410 11411 private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) { 11412 if (blockedReasons == BLOCKED_REASON_NONE) { 11413 mUidBlockedReasons.delete(uid); 11414 } else { 11415 mUidBlockedReasons.put(uid, blockedReasons); 11416 } 11417 } 11418 11419 /** 11420 * Notify of the blocked state apps with a registered callback matching a given NAI. 11421 * 11422 * Unlike other callbacks, blocked status is different between each individual uid. So for 11423 * any given nai, all requests need to be considered according to the uid who filed it. 11424 * 11425 * @param nai The target NetworkAgentInfo. 11426 * @param oldMetered True if the previous network capabilities were metered. 11427 * @param newMetered True if the current network capabilities are metered. 11428 * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN. 11429 * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN. 11430 */ 11431 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, 11432 boolean newMetered, List<UidRange> oldBlockedUidRanges, 11433 List<UidRange> newBlockedUidRanges) { 11434 11435 for (int i = 0; i < nai.numNetworkRequests(); i++) { 11436 NetworkRequest nr = nai.requestAt(i); 11437 NetworkRequestInfo nri = mNetworkRequests.get(nr); 11438 11439 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 11440 final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges); 11441 final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges) 11442 ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges) 11443 : oldVpnBlocked; 11444 11445 final int oldBlockedState = getBlockedState( 11446 nri.mAsUid, blockedReasons, oldMetered, oldVpnBlocked); 11447 final int newBlockedState = getBlockedState( 11448 nri.mAsUid, blockedReasons, newMetered, newVpnBlocked); 11449 if (oldBlockedState != newBlockedState) { 11450 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 11451 newBlockedState); 11452 } 11453 } 11454 } 11455 11456 /** 11457 * Notify apps with a given UID of the new blocked state according to new uid state. 11458 * @param uid The uid for which the rules changed. 11459 * @param blockedReasons The reasons for why an uid is blocked. 11460 */ 11461 private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) { 11462 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 11463 final boolean metered = nai.networkCapabilities.isMetered(); 11464 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); 11465 11466 final int oldBlockedState = getBlockedState( 11467 uid, mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked); 11468 final int newBlockedState = 11469 getBlockedState(uid, blockedReasons, metered, vpnBlocked); 11470 if (oldBlockedState == newBlockedState) { 11471 continue; 11472 } 11473 for (int i = 0; i < nai.numNetworkRequests(); i++) { 11474 NetworkRequest nr = nai.requestAt(i); 11475 NetworkRequestInfo nri = mNetworkRequests.get(nr); 11476 if (nri != null && nri.mAsUid == uid) { 11477 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 11478 newBlockedState); 11479 } 11480 } 11481 } 11482 } 11483 11484 @VisibleForTesting 11485 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 11486 // The NetworkInfo we actually send out has no bearing on the real 11487 // state of affairs. For example, if the default connection is mobile, 11488 // and a request for HIPRI has just gone away, we need to pretend that 11489 // HIPRI has just disconnected. So we need to set the type to HIPRI and 11490 // the state to DISCONNECTED, even though the network is of type MOBILE 11491 // and is still connected. 11492 NetworkInfo info = new NetworkInfo(nai.networkInfo); 11493 info.setType(type); 11494 filterForLegacyLockdown(info); 11495 if (state != DetailedState.DISCONNECTED) { 11496 info.setDetailedState(state, null, info.getExtraInfo()); 11497 sendConnectedBroadcast(info); 11498 } else { 11499 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 11500 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 11501 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 11502 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 11503 if (info.isFailover()) { 11504 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 11505 nai.networkInfo.setFailover(false); 11506 } 11507 if (info.getReason() != null) { 11508 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 11509 } 11510 if (info.getExtraInfo() != null) { 11511 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 11512 } 11513 NetworkAgentInfo newDefaultAgent = null; 11514 if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { 11515 newDefaultAgent = mDefaultRequest.getSatisfier(); 11516 if (newDefaultAgent != null) { 11517 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 11518 newDefaultAgent.networkInfo); 11519 } else { 11520 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 11521 } 11522 } 11523 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 11524 mDefaultInetConditionPublished); 11525 sendStickyBroadcast(intent); 11526 if (newDefaultAgent != null) { 11527 sendConnectedBroadcast(newDefaultAgent.networkInfo); 11528 } 11529 } 11530 } 11531 11532 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 11533 if (VDBG || DDBG) { 11534 String notification = ConnectivityManager.getCallbackName(notifyType); 11535 log("notifyType " + notification + " for " + networkAgent.toShortString()); 11536 } 11537 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 11538 NetworkRequest nr = networkAgent.requestAt(i); 11539 NetworkRequestInfo nri = mNetworkRequests.get(nr); 11540 if (VDBG) log(" sending notification for " + nr); 11541 if (nri.mPendingIntent == null) { 11542 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 11543 } else { 11544 sendPendingIntentForRequest(nri, networkAgent, notifyType); 11545 } 11546 } 11547 } 11548 11549 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 11550 notifyNetworkCallbacks(networkAgent, notifyType, 0); 11551 } 11552 11553 /** 11554 * Returns the list of all interfaces that could be used by network traffic that does not 11555 * explicitly specify a network. This includes the default network, but also all VPNs that are 11556 * currently connected. 11557 * 11558 * Must be called on the handler thread. 11559 */ 11560 @NonNull 11561 private ArrayList<Network> getDefaultNetworks() { 11562 ensureRunningOnConnectivityServiceThread(); 11563 final ArrayList<Network> defaultNetworks = new ArrayList<>(); 11564 final Set<Integer> activeNetIds = new ArraySet<>(); 11565 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 11566 if (nri.isBeingSatisfied()) { 11567 activeNetIds.add(nri.getSatisfier().network().netId); 11568 } 11569 } 11570 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 11571 if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) { 11572 defaultNetworks.add(nai.network); 11573 } 11574 } 11575 return defaultNetworks; 11576 } 11577 11578 /** 11579 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 11580 * active iface's tracked properties has changed. 11581 */ 11582 private void notifyIfacesChangedForNetworkStats() { 11583 ensureRunningOnConnectivityServiceThread(); 11584 String activeIface = null; 11585 LinkProperties activeLinkProperties = getActiveLinkProperties(); 11586 if (activeLinkProperties != null) { 11587 activeIface = activeLinkProperties.getInterfaceName(); 11588 } 11589 11590 final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo(); 11591 try { 11592 final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>(); 11593 snapshots.addAll(getAllNetworkStateSnapshots()); 11594 mStatsManager.notifyNetworkStatus(getDefaultNetworks(), 11595 snapshots, activeIface, Arrays.asList(underlyingNetworkInfos)); 11596 } catch (Exception ignored) { 11597 } 11598 } 11599 11600 @Override 11601 public String getCaptivePortalServerUrl() { 11602 enforceNetworkStackOrSettingsPermission(); 11603 String settingUrl = mResources.get().getString( 11604 R.string.config_networkCaptivePortalServerUrl); 11605 11606 if (!TextUtils.isEmpty(settingUrl)) { 11607 return settingUrl; 11608 } 11609 11610 settingUrl = Settings.Global.getString(mContext.getContentResolver(), 11611 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL); 11612 if (!TextUtils.isEmpty(settingUrl)) { 11613 return settingUrl; 11614 } 11615 11616 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL; 11617 } 11618 11619 @Override 11620 public void startNattKeepalive(Network network, int intervalSeconds, 11621 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { 11622 enforceKeepalivePermission(); 11623 mKeepaliveTracker.startNattKeepalive( 11624 getNetworkAgentInfoForNetwork(network), null /* fd */, 11625 intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT, 11626 // Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to 11627 // false and set the underpinned network to null because there is no way and no 11628 // plan to configure automaticOnOffKeepalives or underpinnedNetwork in this 11629 // deprecated method. 11630 false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */); 11631 } 11632 11633 @Override 11634 public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, 11635 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, 11636 String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) { 11637 try { 11638 final FileDescriptor fd = pfd.getFileDescriptor(); 11639 mKeepaliveTracker.startNattKeepalive( 11640 getNetworkAgentInfoForNetwork(network), fd, resourceId, 11641 intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT, 11642 automaticOnOffKeepalives, underpinnedNetwork); 11643 } finally { 11644 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 11645 // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately. 11646 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 11647 IoUtils.closeQuietly(pfd); 11648 } 11649 } 11650 } 11651 11652 @Override 11653 public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, 11654 ISocketKeepaliveCallback cb) { 11655 try { 11656 enforceKeepalivePermission(); 11657 final FileDescriptor fd = pfd.getFileDescriptor(); 11658 mKeepaliveTracker.startTcpKeepalive( 11659 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); 11660 } finally { 11661 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 11662 // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately. 11663 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 11664 IoUtils.closeQuietly(pfd); 11665 } 11666 } 11667 } 11668 11669 @Override 11670 public void stopKeepalive(@NonNull final ISocketKeepaliveCallback cb) { 11671 mHandler.sendMessage(mHandler.obtainMessage( 11672 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, 0, SocketKeepalive.SUCCESS, 11673 Objects.requireNonNull(cb).asBinder())); 11674 } 11675 11676 @Override 11677 public int[] getSupportedKeepalives() { 11678 enforceAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS, 11679 // Backwards compatibility with CTS 13 11680 android.Manifest.permission.QUERY_ALL_PACKAGES); 11681 11682 return BinderUtils.withCleanCallingIdentity(() -> 11683 KeepaliveResourceUtil.getSupportedKeepalives(mContext)); 11684 } 11685 11686 @Override 11687 public void factoryReset() { 11688 enforceSettingsPermission(); 11689 11690 final int uid = mDeps.getCallingUid(); 11691 final long token = Binder.clearCallingIdentity(); 11692 try { 11693 if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET, 11694 UserHandle.getUserHandleForUid(uid))) { 11695 return; 11696 } 11697 11698 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext); 11699 ipMemoryStore.factoryReset(); 11700 11701 // Turn airplane mode off 11702 setAirplaneMode(false); 11703 11704 // restore private DNS settings to default mode (opportunistic) 11705 if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, 11706 UserHandle.getUserHandleForUid(uid))) { 11707 ConnectivitySettingsManager.setPrivateDnsMode(mContext, 11708 PRIVATE_DNS_MODE_OPPORTUNISTIC); 11709 } 11710 11711 Settings.Global.putString(mContext.getContentResolver(), 11712 ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 11713 } finally { 11714 Binder.restoreCallingIdentity(token); 11715 } 11716 } 11717 11718 @Override 11719 public byte[] getNetworkWatchlistConfigHash() { 11720 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 11721 if (nwm == null) { 11722 loge("Unable to get NetworkWatchlistManager"); 11723 return null; 11724 } 11725 // Redirect it to network watchlist service to access watchlist file and calculate hash. 11726 return nwm.getWatchlistConfigHash(); 11727 } 11728 11729 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 11730 int[] transports = nai.networkCapabilities.getTransportTypes(); 11731 mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype)); 11732 } 11733 11734 private static boolean toBool(int encodedBoolean) { 11735 return encodedBoolean != 0; // Only 0 means false. 11736 } 11737 11738 private static int encodeBool(boolean b) { 11739 return b ? 1 : 0; 11740 } 11741 11742 @Override 11743 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 11744 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 11745 @NonNull String[] args) { 11746 return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 11747 err.getFileDescriptor(), args); 11748 } 11749 11750 private class ShellCmd extends BasicShellCommandHandler { 11751 11752 private Boolean parseBooleanArgument(final String arg) { 11753 if ("true".equals(arg)) { 11754 return true; 11755 } else if ("false".equals(arg)) { 11756 return false; 11757 } else { 11758 getOutPrintWriter().println("Invalid boolean argument: " + arg); 11759 return null; 11760 } 11761 } 11762 11763 private Integer parseIntegerArgument(final String arg) { 11764 try { 11765 return Integer.valueOf(arg); 11766 } catch (NumberFormatException ne) { 11767 getOutPrintWriter().println("Invalid integer argument: " + arg); 11768 return null; 11769 } 11770 } 11771 11772 @Override 11773 public int onCommand(String cmd) { 11774 if (cmd == null) { 11775 return handleDefaultCommands(cmd); 11776 } 11777 final PrintWriter pw = getOutPrintWriter(); 11778 try { 11779 switch (cmd) { 11780 case "airplane-mode": 11781 // Usage : adb shell cmd connectivity airplane-mode [enable|disable] 11782 // If no argument, get and display the current status 11783 final String action = getNextArg(); 11784 if ("enable".equals(action)) { 11785 setAirplaneMode(true); 11786 return 0; 11787 } else if ("disable".equals(action)) { 11788 setAirplaneMode(false); 11789 return 0; 11790 } else if (action == null) { 11791 final ContentResolver cr = mContext.getContentResolver(); 11792 final int enabled = Settings.Global.getInt(cr, 11793 Settings.Global.AIRPLANE_MODE_ON); 11794 pw.println(enabled == 0 ? "disabled" : "enabled"); 11795 return 0; 11796 } else { 11797 onHelp(); 11798 return -1; 11799 } 11800 case "set-chain3-enabled": { 11801 final Boolean enabled = parseBooleanArgument(getNextArg()); 11802 if (null == enabled) { 11803 onHelp(); 11804 return -1; 11805 } 11806 Log.i(TAG, (enabled ? "En" : "Dis") + "abled FIREWALL_CHAIN_OEM_DENY_3"); 11807 setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, 11808 enabled); 11809 return 0; 11810 } 11811 case "get-chain3-enabled": { 11812 final boolean chainEnabled = getFirewallChainEnabled( 11813 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3); 11814 pw.println("chain:" + (chainEnabled ? "enabled" : "disabled")); 11815 return 0; 11816 } 11817 case "set-package-networking-enabled": { 11818 final Boolean enabled = parseBooleanArgument(getNextArg()); 11819 final String packageName = getNextArg(); 11820 if (null == enabled || null == packageName) { 11821 onHelp(); 11822 return -1; 11823 } 11824 // Throws NameNotFound if the package doesn't exist. 11825 final int appId = setPackageFirewallRule( 11826 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, 11827 packageName, enabled ? FIREWALL_RULE_DEFAULT : FIREWALL_RULE_DENY); 11828 final String msg = (enabled ? "Enabled" : "Disabled") 11829 + " networking for " + packageName + ", appId " + appId; 11830 Log.i(TAG, msg); 11831 pw.println(msg); 11832 return 0; 11833 } 11834 case "get-package-networking-enabled": { 11835 final String packageName = getNextArg(); 11836 final int rule = getPackageFirewallRule( 11837 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, packageName); 11838 if (FIREWALL_RULE_ALLOW == rule || FIREWALL_RULE_DEFAULT == rule) { 11839 pw.println(packageName + ":" + "allow"); 11840 } else if (FIREWALL_RULE_DENY == rule) { 11841 pw.println(packageName + ":" + "deny"); 11842 } else { 11843 throw new IllegalStateException("Unknown rule " + rule + " for package " 11844 + packageName); 11845 } 11846 return 0; 11847 } 11848 case "set-background-networking-enabled-for-uid": { 11849 final Integer uid = parseIntegerArgument(getNextArg()); 11850 final Boolean enabled = parseBooleanArgument(getNextArg()); 11851 if (null == enabled || null == uid) { 11852 onHelp(); 11853 return -1; 11854 } 11855 final int rule = enabled ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DEFAULT; 11856 setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, rule); 11857 final String msg = (enabled ? "Enabled" : "Disabled") 11858 + " background networking for uid " + uid; 11859 Log.i(TAG, msg); 11860 pw.println(msg); 11861 return 0; 11862 } 11863 case "get-background-networking-enabled-for-uid": { 11864 final Integer uid = parseIntegerArgument(getNextArg()); 11865 if (null == uid) { 11866 onHelp(); 11867 return -1; 11868 } 11869 final int rule = getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid); 11870 if (FIREWALL_RULE_ALLOW == rule) { 11871 pw.println(uid + ": allow"); 11872 } else if (FIREWALL_RULE_DENY == rule || FIREWALL_RULE_DEFAULT == rule) { 11873 pw.println(uid + ": deny"); 11874 } else { 11875 throw new IllegalStateException( 11876 "Unknown rule " + rule + " for uid " + uid); 11877 } 11878 return 0; 11879 } 11880 case "reevaluate": 11881 // Usage : adb shell cmd connectivity reevaluate <netId> 11882 // If netId is omitted, then reevaluate the default network 11883 final String netId = getNextArg(); 11884 final NetworkAgentInfo nai; 11885 if (null == netId) { 11886 // Note that the command is running on the wrong thread to call this, 11887 // so this could in principle return stale data. But it can't crash. 11888 nai = getDefaultNetwork(); 11889 } else { 11890 // If netId can't be parsed, this throws NumberFormatException, which 11891 // is passed back to adb who prints it. 11892 nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId)); 11893 } 11894 if (null == nai) { 11895 pw.println("Unknown network (net ID not found or no default network)"); 11896 return 0; 11897 } 11898 Log.d(TAG, "Reevaluating network " + nai.network); 11899 reportNetworkConnectivity(nai.network, !nai.isValidated()); 11900 return 0; 11901 case "bpf-get-cgroup-program-id": { 11902 // Usage : adb shell cmd connectivity bpf-get-cgroup-program-id <type> 11903 // Get cgroup bpf program Id for the given type. See BpfUtils#getProgramId 11904 // for more detail. 11905 // If type can't be parsed, this throws NumberFormatException, which 11906 // is passed back to adb who prints it. 11907 final int type = Integer.parseInt(getNextArg()); 11908 final int ret = BpfUtils.getProgramId(type); 11909 pw.println(ret); 11910 return 0; 11911 } 11912 default: 11913 return handleDefaultCommands(cmd); 11914 } 11915 } catch (Exception e) { 11916 pw.println(e); 11917 } 11918 return -1; 11919 } 11920 11921 @Override 11922 public void onHelp() { 11923 PrintWriter pw = getOutPrintWriter(); 11924 pw.println("Connectivity service commands:"); 11925 pw.println(" help"); 11926 pw.println(" Print this help text."); 11927 pw.println(" airplane-mode [enable|disable]"); 11928 pw.println(" Turn airplane mode on or off."); 11929 pw.println(" airplane-mode"); 11930 pw.println(" Get airplane mode."); 11931 pw.println(" set-chain3-enabled [true|false]"); 11932 pw.println(" Enable or disable FIREWALL_CHAIN_OEM_DENY_3 for debugging."); 11933 pw.println(" get-chain3-enabled"); 11934 pw.println(" Returns whether FIREWALL_CHAIN_OEM_DENY_3 is enabled."); 11935 pw.println(" set-package-networking-enabled [true|false] [package name]"); 11936 pw.println(" Set the deny bit in FIREWALL_CHAIN_OEM_DENY_3 to package. This has\n" 11937 + " no effect if the chain is disabled."); 11938 pw.println(" get-package-networking-enabled [package name]"); 11939 pw.println(" Get the deny bit in FIREWALL_CHAIN_OEM_DENY_3 for package."); 11940 pw.println(" set-background-networking-enabled-for-uid [uid] [true|false]"); 11941 pw.println(" Set the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); 11942 pw.println(" get-background-networking-enabled-for-uid [uid]"); 11943 pw.println(" Get the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); 11944 } 11945 } 11946 11947 private int getVpnType(@Nullable NetworkAgentInfo vpn) { 11948 if (vpn == null) return VpnManager.TYPE_VPN_NONE; 11949 final TransportInfo ti = vpn.networkCapabilities.getTransportInfo(); 11950 if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE; 11951 return ((VpnTransportInfo) ti).getType(); 11952 } 11953 11954 private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai, 11955 @NonNull NetworkCapabilities nc) { 11956 final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo(); 11957 final TransportInfo newInfo = nc.getTransportInfo(); 11958 if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) { 11959 return; 11960 } 11961 if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) { 11962 nai.lastRoamTime = SystemClock.elapsedRealtime(); 11963 } 11964 } 11965 11966 /** 11967 * @param connectionInfo the connection to resolve. 11968 * @return {@code uid} if the connection is found and the app has permission to observe it 11969 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the 11970 * connection is not found. 11971 */ 11972 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { 11973 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { 11974 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); 11975 } 11976 11977 final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol, 11978 connectionInfo.local, connectionInfo.remote); 11979 11980 if (uid == INVALID_UID) return uid; // Not found. 11981 11982 // Connection owner UIDs are visible only to the network stack and to the VpnService-based 11983 // VPN, if any, that applies to the UID that owns the connection. 11984 if (hasNetworkStackPermission()) return uid; 11985 11986 final NetworkAgentInfo vpn = getVpnForUid(uid); 11987 if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE 11988 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) { 11989 return INVALID_UID; 11990 } 11991 11992 return uid; 11993 } 11994 11995 /** 11996 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. 11997 * 11998 * <p>The TestNetworkService must be run in the system server due to TUN creation. 11999 */ 12000 @Override 12001 public IBinder startOrGetTestNetworkService() { 12002 synchronized (mTNSLock) { 12003 TestNetworkService.enforceTestNetworkPermissions(mContext); 12004 12005 if (mTNS == null) { 12006 mTNS = new TestNetworkService(mContext); 12007 } 12008 12009 return mTNS; 12010 } 12011 } 12012 12013 /** 12014 * Handler used for managing all Connectivity Diagnostics related functions. 12015 * 12016 * @see android.net.ConnectivityDiagnosticsManager 12017 * 12018 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file 12019 */ 12020 @VisibleForTesting 12021 class ConnectivityDiagnosticsHandler extends Handler { 12022 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName(); 12023 12024 /** 12025 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link 12026 * android.net.ConnectivityDiagnosticsManager}. 12027 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and 12028 * NetworkRequestInfo to be registered 12029 */ 12030 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1; 12031 12032 /** 12033 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link 12034 * android.net.ConnectivityDiagnosticsManager}. 12035 * obj = the IConnectivityDiagnosticsCallback to be unregistered 12036 * arg1 = the uid of the caller 12037 */ 12038 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2; 12039 12040 /** 12041 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks 12042 * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events. 12043 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from 12044 * NetworkMonitor. 12045 * data = PersistableBundle of extras passed from NetworkMonitor. 12046 */ 12047 private static final int CMD_SEND_CONNECTIVITY_REPORT = 3; 12048 12049 /** 12050 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has 12051 * been detected on the network. 12052 * obj = Long the timestamp (in millis) for when the suspected data stall was detected. 12053 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method. 12054 * arg2 = NetID. 12055 * data = PersistableBundle of extras passed from NetworkMonitor. 12056 */ 12057 private static final int EVENT_DATA_STALL_SUSPECTED = 4; 12058 12059 /** 12060 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to 12061 * the platform. This event will invoke {@link 12062 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned 12063 * callbacks. 12064 * obj = ReportedNetworkConnectivityInfo with info on reported Network connectivity. 12065 */ 12066 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5; 12067 12068 private ConnectivityDiagnosticsHandler(Looper looper) { 12069 super(looper); 12070 } 12071 12072 @Override 12073 public void handleMessage(Message msg) { 12074 switch (msg.what) { 12075 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 12076 handleRegisterConnectivityDiagnosticsCallback( 12077 (ConnectivityDiagnosticsCallbackInfo) msg.obj); 12078 break; 12079 } 12080 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 12081 handleUnregisterConnectivityDiagnosticsCallback( 12082 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1); 12083 break; 12084 } 12085 case CMD_SEND_CONNECTIVITY_REPORT: { 12086 final ConnectivityReportEvent reportEvent = 12087 (ConnectivityReportEvent) msg.obj; 12088 12089 handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras); 12090 break; 12091 } 12092 case EVENT_DATA_STALL_SUSPECTED: { 12093 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 12094 final Pair<Long, PersistableBundle> arg = 12095 (Pair<Long, PersistableBundle>) msg.obj; 12096 if (nai == null) break; 12097 12098 handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second); 12099 break; 12100 } 12101 case EVENT_NETWORK_CONNECTIVITY_REPORTED: { 12102 handleNetworkConnectivityReported((ReportedNetworkConnectivityInfo) msg.obj); 12103 break; 12104 } 12105 default: { 12106 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what); 12107 } 12108 } 12109 } 12110 } 12111 12112 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */ 12113 @VisibleForTesting 12114 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient { 12115 @NonNull private final IConnectivityDiagnosticsCallback mCb; 12116 @NonNull private final NetworkRequestInfo mRequestInfo; 12117 @NonNull private final String mCallingPackageName; 12118 12119 @VisibleForTesting 12120 ConnectivityDiagnosticsCallbackInfo( 12121 @NonNull IConnectivityDiagnosticsCallback cb, 12122 @NonNull NetworkRequestInfo nri, 12123 @NonNull String callingPackageName) { 12124 mCb = cb; 12125 mRequestInfo = nri; 12126 mCallingPackageName = callingPackageName; 12127 } 12128 12129 @Override 12130 public void binderDied() { 12131 log("ConnectivityDiagnosticsCallback IBinder died."); 12132 unregisterConnectivityDiagnosticsCallback(mCb); 12133 } 12134 } 12135 12136 /** 12137 * Class used for sending information from {@link 12138 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it. 12139 */ 12140 private static class NetworkTestedResults { 12141 private final int mNetId; 12142 private final int mTestResult; 12143 @Nullable private final String mRedirectUrl; 12144 12145 private NetworkTestedResults( 12146 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) { 12147 mNetId = netId; 12148 mTestResult = testResult; 12149 mRedirectUrl = redirectUrl; 12150 } 12151 } 12152 12153 /** 12154 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link 12155 * ConnectivityDiagnosticsHandler}. 12156 */ 12157 private static class ConnectivityReportEvent { 12158 private final long mTimestampMillis; 12159 @NonNull private final NetworkAgentInfo mNai; 12160 private final PersistableBundle mExtras; 12161 12162 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, 12163 PersistableBundle p) { 12164 mTimestampMillis = timestampMillis; 12165 mNai = nai; 12166 mExtras = p; 12167 } 12168 } 12169 12170 /** 12171 * Class used for sending info for a call to {@link #reportNetworkConnectivity()} to {@link 12172 * ConnectivityDiagnosticsHandler}. 12173 */ 12174 private static class ReportedNetworkConnectivityInfo { 12175 public final boolean hasConnectivity; 12176 public final boolean isNetworkRevalidating; 12177 public final int reporterUid; 12178 @NonNull public final NetworkAgentInfo nai; 12179 12180 private ReportedNetworkConnectivityInfo( 12181 boolean hasConnectivity, 12182 boolean isNetworkRevalidating, 12183 int reporterUid, 12184 @NonNull NetworkAgentInfo nai) { 12185 this.hasConnectivity = hasConnectivity; 12186 this.isNetworkRevalidating = isNetworkRevalidating; 12187 this.reporterUid = reporterUid; 12188 this.nai = nai; 12189 } 12190 } 12191 12192 private void handleRegisterConnectivityDiagnosticsCallback( 12193 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) { 12194 ensureRunningOnConnectivityServiceThread(); 12195 12196 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb; 12197 final IBinder iCb = cb.asBinder(); 12198 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 12199 12200 // Connectivity Diagnostics are meant to be used with a single network request. It would be 12201 // confusing for these networks to change when an NRI is satisfied in another layer. 12202 if (nri.isMultilayerRequest()) { 12203 throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer " 12204 + "network requests."); 12205 } 12206 12207 // This means that the client registered the same callback multiple times. Do 12208 // not override the previous entry, and exit silently. 12209 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) { 12210 if (VDBG) log("Diagnostics callback is already registered"); 12211 12212 // Decrement the reference count for this NetworkRequestInfo. The reference count is 12213 // incremented when the NetworkRequestInfo is created as part of 12214 // enforceRequestCountLimit(). 12215 nri.mPerUidCounter.decrementCount(nri.mUid); 12216 return; 12217 } 12218 12219 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo); 12220 12221 try { 12222 iCb.linkToDeath(cbInfo, 0); 12223 } catch (RemoteException e) { 12224 cbInfo.binderDied(); 12225 return; 12226 } 12227 12228 // Once registered, provide ConnectivityReports for matching Networks 12229 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>(); 12230 synchronized (mNetworkForNetId) { 12231 for (int i = 0; i < mNetworkForNetId.size(); i++) { 12232 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 12233 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0) 12234 if (nai.satisfies(nri.mRequests.get(0))) { 12235 matchingNetworks.add(nai); 12236 } 12237 } 12238 } 12239 for (final NetworkAgentInfo nai : matchingNetworks) { 12240 final ConnectivityReport report = nai.getConnectivityReport(); 12241 if (report == null) { 12242 continue; 12243 } 12244 if (!hasConnectivityDiagnosticsPermissions( 12245 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 12246 continue; 12247 } 12248 12249 try { 12250 cb.onConnectivityReportAvailable(report); 12251 } catch (RemoteException e) { 12252 // Exception while sending the ConnectivityReport. Move on to the next network. 12253 } 12254 } 12255 } 12256 12257 private void handleUnregisterConnectivityDiagnosticsCallback( 12258 @NonNull IConnectivityDiagnosticsCallback cb, int uid) { 12259 ensureRunningOnConnectivityServiceThread(); 12260 final IBinder iCb = cb.asBinder(); 12261 12262 final ConnectivityDiagnosticsCallbackInfo cbInfo = 12263 mConnectivityDiagnosticsCallbacks.remove(iCb); 12264 if (cbInfo == null) { 12265 if (VDBG) log("Removing diagnostics callback that is not currently registered"); 12266 return; 12267 } 12268 12269 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 12270 12271 // Caller's UID must either be the registrants (if they are unregistering) or the System's 12272 // (if the Binder died) 12273 if (uid != nri.mUid && uid != Process.SYSTEM_UID) { 12274 if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's"); 12275 return; 12276 } 12277 12278 // Decrement the reference count for this NetworkRequestInfo. The reference count is 12279 // incremented when the NetworkRequestInfo is created as part of 12280 // enforceRequestCountLimit(). 12281 nri.mPerUidCounter.decrementCount(nri.mUid); 12282 12283 iCb.unlinkToDeath(cbInfo, 0); 12284 } 12285 12286 private void handleNetworkTestedWithExtras( 12287 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) { 12288 final NetworkAgentInfo nai = reportEvent.mNai; 12289 final NetworkCapabilities networkCapabilities = 12290 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 12291 final ConnectivityReport report = 12292 new ConnectivityReport( 12293 reportEvent.mNai.network, 12294 reportEvent.mTimestampMillis, 12295 nai.linkProperties, 12296 networkCapabilities, 12297 extras); 12298 nai.setConnectivityReport(report); 12299 12300 final List<IConnectivityDiagnosticsCallback> results = 12301 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 12302 for (final IConnectivityDiagnosticsCallback cb : results) { 12303 try { 12304 cb.onConnectivityReportAvailable(report); 12305 } catch (RemoteException ex) { 12306 loge("Error invoking onConnectivityReportAvailable", ex); 12307 } 12308 } 12309 } 12310 12311 private void handleDataStallSuspected( 12312 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, 12313 @NonNull PersistableBundle extras) { 12314 final NetworkCapabilities networkCapabilities = 12315 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 12316 final DataStallReport report = 12317 new DataStallReport( 12318 nai.network, 12319 timestampMillis, 12320 detectionMethod, 12321 nai.linkProperties, 12322 networkCapabilities, 12323 extras); 12324 final List<IConnectivityDiagnosticsCallback> results = 12325 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 12326 for (final IConnectivityDiagnosticsCallback cb : results) { 12327 try { 12328 cb.onDataStallSuspected(report); 12329 } catch (RemoteException ex) { 12330 loge("Error invoking onDataStallSuspected", ex); 12331 } 12332 } 12333 } 12334 12335 private void handleNetworkConnectivityReported( 12336 @NonNull ReportedNetworkConnectivityInfo reportedNetworkConnectivityInfo) { 12337 final NetworkAgentInfo nai = reportedNetworkConnectivityInfo.nai; 12338 final ConnectivityReport cachedReport = nai.getConnectivityReport(); 12339 12340 // If the Network is being re-validated as a result of this call to 12341 // reportNetworkConnectivity(), notify all permissioned callbacks. Otherwise, only notify 12342 // permissioned callbacks registered by the reporter. 12343 final List<IConnectivityDiagnosticsCallback> results = 12344 getMatchingPermissionedCallbacks( 12345 nai, 12346 reportedNetworkConnectivityInfo.isNetworkRevalidating 12347 ? Process.INVALID_UID 12348 : reportedNetworkConnectivityInfo.reporterUid); 12349 12350 for (final IConnectivityDiagnosticsCallback cb : results) { 12351 try { 12352 cb.onNetworkConnectivityReported( 12353 nai.network, reportedNetworkConnectivityInfo.hasConnectivity); 12354 } catch (RemoteException ex) { 12355 loge("Error invoking onNetworkConnectivityReported", ex); 12356 } 12357 12358 // If the Network isn't re-validating, also provide the cached report. If there is no 12359 // cached report, the Network is still being validated and a report will be sent once 12360 // validation is complete. Note that networks which never undergo validation will still 12361 // have a cached ConnectivityReport with RESULT_SKIPPED. 12362 if (!reportedNetworkConnectivityInfo.isNetworkRevalidating && cachedReport != null) { 12363 try { 12364 cb.onConnectivityReportAvailable(cachedReport); 12365 } catch (RemoteException ex) { 12366 loge("Error invoking onConnectivityReportAvailable", ex); 12367 } 12368 } 12369 } 12370 } 12371 12372 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) { 12373 final NetworkCapabilities sanitized = new NetworkCapabilities(nc, 12374 NetworkCapabilities.REDACT_ALL); 12375 sanitized.setUids(null); 12376 sanitized.setAdministratorUids(new int[0]); 12377 sanitized.setOwnerUid(Process.INVALID_UID); 12378 return sanitized; 12379 } 12380 12381 /** 12382 * Gets a list of ConnectivityDiagnostics callbacks that match the specified Network and uid. 12383 * 12384 * <p>If Process.INVALID_UID is specified, all matching callbacks will be returned. 12385 */ 12386 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks( 12387 @NonNull NetworkAgentInfo nai, int uid) { 12388 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); 12389 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry : 12390 mConnectivityDiagnosticsCallbacks.entrySet()) { 12391 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue(); 12392 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 12393 12394 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0). 12395 if (!nai.satisfies(nri.mRequests.get(0))) { 12396 continue; 12397 } 12398 12399 // UID for this callback must either be: 12400 // - INVALID_UID (which sends callbacks to all UIDs), or 12401 // - The callback's owner (the owner called reportNetworkConnectivity() and is being 12402 // notified as a result) 12403 if (uid != Process.INVALID_UID && uid != nri.mUid) { 12404 continue; 12405 } 12406 12407 if (!hasConnectivityDiagnosticsPermissions( 12408 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 12409 continue; 12410 } 12411 12412 results.add(entry.getValue().mCb); 12413 } 12414 return results; 12415 } 12416 12417 private boolean isLocationPermissionRequiredForConnectivityDiagnostics( 12418 @NonNull NetworkAgentInfo nai) { 12419 // TODO(b/188483916): replace with a transport-agnostic location-aware check 12420 return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI); 12421 } 12422 12423 private boolean hasLocationPermission(String packageName, int uid) { 12424 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid 12425 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the 12426 // call in a try-catch. 12427 try { 12428 if (!mLocationPermissionChecker.checkLocationPermission( 12429 packageName, null /* featureId */, uid, null /* message */)) { 12430 return false; 12431 } 12432 } catch (SecurityException e) { 12433 return false; 12434 } 12435 12436 return true; 12437 } 12438 12439 private boolean ownsVpnRunningOverNetwork(int uid, Network network) { 12440 for (NetworkAgentInfo virtual : mNetworkAgentInfos) { 12441 if (virtual.propagateUnderlyingCapabilities() 12442 && virtual.networkCapabilities.getOwnerUid() == uid 12443 && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) { 12444 return true; 12445 } 12446 } 12447 12448 return false; 12449 } 12450 12451 @CheckResult 12452 @VisibleForTesting 12453 boolean hasConnectivityDiagnosticsPermissions( 12454 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) { 12455 if (hasNetworkStackPermission(callbackPid, callbackUid)) { 12456 return true; 12457 } 12458 if (mAllowSysUiConnectivityReports 12459 && hasSystemBarServicePermission(callbackPid, callbackUid)) { 12460 return true; 12461 } 12462 12463 // Administrator UIDs also contains the Owner UID 12464 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); 12465 if (!CollectionUtils.contains(administratorUids, callbackUid) 12466 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) { 12467 return false; 12468 } 12469 12470 return !isLocationPermissionRequiredForConnectivityDiagnostics(nai) 12471 || hasLocationPermission(callbackPackageName, callbackUid); 12472 } 12473 12474 @Override 12475 public void registerConnectivityDiagnosticsCallback( 12476 @NonNull IConnectivityDiagnosticsCallback callback, 12477 @NonNull NetworkRequest request, 12478 @NonNull String callingPackageName) { 12479 Objects.requireNonNull(callback, "callback must not be null"); 12480 Objects.requireNonNull(request, "request must not be null"); 12481 Objects.requireNonNull(callingPackageName, "callingPackageName must not be null"); 12482 12483 if (request.legacyType != TYPE_NONE) { 12484 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." 12485 + " Please use NetworkCapabilities instead."); 12486 } 12487 final int callingUid = mDeps.getCallingUid(); 12488 mAppOpsManager.checkPackage(callingUid, callingPackageName); 12489 12490 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid 12491 // and administrator uids to be safe. 12492 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); 12493 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 12494 12495 final NetworkRequest requestWithId = 12496 new NetworkRequest( 12497 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); 12498 12499 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit. 12500 // 12501 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in 12502 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the 12503 // callback's binder death. 12504 final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId); 12505 nri.mPerUidCounter.incrementCountOrThrow(nri.mUid); 12506 final ConnectivityDiagnosticsCallbackInfo cbInfo = 12507 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName); 12508 12509 mConnectivityDiagnosticsHandler.sendMessage( 12510 mConnectivityDiagnosticsHandler.obtainMessage( 12511 ConnectivityDiagnosticsHandler 12512 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 12513 cbInfo)); 12514 } 12515 12516 @Override 12517 public void unregisterConnectivityDiagnosticsCallback( 12518 @NonNull IConnectivityDiagnosticsCallback callback) { 12519 Objects.requireNonNull(callback, "callback must be non-null"); 12520 mConnectivityDiagnosticsHandler.sendMessage( 12521 mConnectivityDiagnosticsHandler.obtainMessage( 12522 ConnectivityDiagnosticsHandler 12523 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 12524 mDeps.getCallingUid(), 12525 0, 12526 callback)); 12527 } 12528 12529 private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) { 12530 final List<Network> underlyingNetworks = nc.getUnderlyingNetworks(); 12531 if (underlyingNetworks == null) return false; 12532 12533 for (Network network : underlyingNetworks) { 12534 if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) { 12535 return true; 12536 } 12537 } 12538 return false; 12539 } 12540 12541 @Override 12542 public void simulateDataStall(int detectionMethod, long timestampMillis, 12543 @NonNull Network network, @NonNull PersistableBundle extras) { 12544 Objects.requireNonNull(network, "network must not be null"); 12545 Objects.requireNonNull(extras, "extras must not be null"); 12546 12547 enforceAnyPermissionOf(mContext, 12548 android.Manifest.permission.MANAGE_TEST_NETWORKS, 12549 android.Manifest.permission.NETWORK_STACK); 12550 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 12551 if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) { 12552 throw new SecurityException( 12553 "Data Stall simulation is only possible for test networks or networks built on" 12554 + " top of test networks"); 12555 } 12556 12557 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 12558 if (nai == null 12559 || (nai.creatorUid != mDeps.getCallingUid() 12560 && nai.creatorUid != Process.SYSTEM_UID)) { 12561 throw new SecurityException( 12562 "Data Stall simulation is only possible for network " + "creators"); 12563 } 12564 12565 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat 12566 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the 12567 // Data Stall information as a DataStallReportParcelable and passing to 12568 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are 12569 // still passed to ConnectivityDiagnostics (with new detection methods masked). 12570 final DataStallReportParcelable p = new DataStallReportParcelable(); 12571 p.timestampMillis = timestampMillis; 12572 p.detectionMethod = detectionMethod; 12573 12574 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 12575 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS); 12576 } 12577 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 12578 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE); 12579 p.tcpMetricsCollectionPeriodMillis = extras.getInt( 12580 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS); 12581 } 12582 12583 notifyDataStallSuspected(p, network.getNetId()); 12584 } 12585 12586 /** 12587 * Class to hold the information for network activity change event from idle timers 12588 * {@link NetdCallback#onInterfaceClassActivityChanged(boolean, int, long, int)} 12589 */ 12590 private static final class NetworkActivityParams { 12591 public final boolean isActive; 12592 // If TrackMultiNetworkActivities is enabled, idleTimer label is netid. 12593 // If TrackMultiNetworkActivities is disabled, idleTimer label is transport type. 12594 public final int label; 12595 public final long timestampNs; 12596 // Uid represents the uid that was responsible for waking the radio. 12597 // -1 for no uid and uid is -1 if isActive is false. 12598 public final int uid; 12599 12600 NetworkActivityParams(boolean isActive, int label, long timestampNs, int uid) { 12601 this.isActive = isActive; 12602 this.label = label; 12603 this.timestampNs = timestampNs; 12604 this.uid = uid; 12605 } 12606 } 12607 12608 private class NetdCallback extends BaseNetdUnsolicitedEventListener { 12609 @Override 12610 public void onInterfaceClassActivityChanged(boolean isActive, int label, 12611 long timestampNs, int uid) { 12612 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY, 12613 new NetworkActivityParams(isActive, label, timestampNs, uid))); 12614 } 12615 12616 @Override 12617 public void onInterfaceLinkStateChanged(@NonNull String iface, boolean up) { 12618 mHandler.post(() -> { 12619 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 12620 nai.clatd.handleInterfaceLinkStateChanged(iface, up); 12621 } 12622 }); 12623 } 12624 12625 @Override 12626 public void onInterfaceRemoved(@NonNull String iface) { 12627 mHandler.post(() -> { 12628 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 12629 nai.clatd.handleInterfaceRemoved(iface); 12630 } 12631 }); 12632 } 12633 } 12634 12635 private final boolean mTrackMultiNetworkActivities; 12636 private final LegacyNetworkActivityTracker mNetworkActivityTracker; 12637 12638 /** 12639 * Class used for updating network activity tracking with netd and notify network activity 12640 * changes. 12641 */ 12642 @VisibleForTesting 12643 public static final class LegacyNetworkActivityTracker { 12644 private static final int NO_UID = -1; 12645 private final Context mContext; 12646 private final INetd mNetd; 12647 private final Handler mHandler; 12648 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 12649 new RemoteCallbackList<>(); 12650 // Indicate the current system default network activity is active or not. 12651 // This needs to be volatile to allow non handler threads to read this value without lock. 12652 // If there is no default network, default network is considered active to keep the existing 12653 // behavior. Initial value is used until first connect to the default network. 12654 private volatile boolean mIsDefaultNetworkActive = true; 12655 private Network mDefaultNetwork; 12656 // Key is netId. Value is configured idle timer information. 12657 private final SparseArray<IdleTimerParams> mActiveIdleTimers = new SparseArray<>(); 12658 private final boolean mTrackMultiNetworkActivities; 12659 // Store netIds of Wi-Fi networks whose idletimers report that they are active 12660 private final Set<Integer> mActiveWifiNetworks = new ArraySet<>(); 12661 // Store netIds of cellular networks whose idletimers report that they are active 12662 private final Set<Integer> mActiveCellularNetworks = new ArraySet<>(); 12663 12664 private static class IdleTimerParams { 12665 public final int timeout; 12666 public final int transportType; 12667 12668 IdleTimerParams(int timeout, int transport) { 12669 this.timeout = timeout; 12670 this.transportType = transport; 12671 } 12672 } 12673 12674 LegacyNetworkActivityTracker(@NonNull Context context, @NonNull INetd netd, 12675 @NonNull Handler handler, boolean trackMultiNetworkActivities) { 12676 mContext = context; 12677 mNetd = netd; 12678 mHandler = handler; 12679 mTrackMultiNetworkActivities = trackMultiNetworkActivities; 12680 } 12681 12682 private void ensureRunningOnConnectivityServiceThread() { 12683 if (mHandler.getLooper().getThread() != Thread.currentThread()) { 12684 throw new IllegalStateException("Not running on ConnectivityService thread: " 12685 + Thread.currentThread().getName()); 12686 } 12687 } 12688 12689 /** 12690 * Update network activity and call BatteryStats to update radio power state if the 12691 * mobile or Wi-Fi activity is changed. 12692 * LegacyNetworkActivityTracker considers the mobile network is active if at least one 12693 * mobile network is active since BatteryStatsService only maintains a single power state 12694 * for the mobile network. 12695 * The Wi-Fi network is also the same. 12696 * 12697 * {@link #setupDataActivityTracking} and {@link #removeDataActivityTracking} use 12698 * TRANSPORT_CELLULAR as the transportType argument if the network has both cell and Wi-Fi 12699 * transports. 12700 */ 12701 private void maybeUpdateRadioPowerState(final int netId, final int transportType, 12702 final boolean isActive, final int uid) { 12703 if (transportType != TRANSPORT_WIFI && transportType != TRANSPORT_CELLULAR) { 12704 Log.e(TAG, "Unexpected transportType in maybeUpdateRadioPowerState: " 12705 + transportType); 12706 return; 12707 } 12708 final Set<Integer> activeNetworks = transportType == TRANSPORT_WIFI 12709 ? mActiveWifiNetworks : mActiveCellularNetworks; 12710 12711 final boolean wasEmpty = activeNetworks.isEmpty(); 12712 if (isActive) { 12713 activeNetworks.add(netId); 12714 } else { 12715 activeNetworks.remove(netId); 12716 } 12717 12718 if (wasEmpty != activeNetworks.isEmpty()) { 12719 updateRadioPowerState(isActive, transportType, uid); 12720 } 12721 } 12722 12723 private void handleDefaultNetworkActivity(final int transportType, 12724 final boolean isActive, final long timestampNs) { 12725 mIsDefaultNetworkActive = isActive; 12726 sendDataActivityBroadcast(transportTypeToLegacyType(transportType), 12727 isActive, timestampNs); 12728 if (isActive) { 12729 reportNetworkActive(); 12730 } 12731 } 12732 12733 private void handleReportNetworkActivityWithNetIdLabel( 12734 NetworkActivityParams activityParams) { 12735 final int netId = activityParams.label; 12736 final IdleTimerParams idleTimerParams = mActiveIdleTimers.get(netId); 12737 if (idleTimerParams == null) { 12738 // This network activity change is not tracked anymore 12739 // This can happen if netd callback post activity change event message but idle 12740 // timer is removed before processing this message. 12741 return; 12742 } 12743 // TODO: if a network changes transports, storing the transport type in the 12744 // IdleTimerParams is not correct. Consider getting it from the network's 12745 // NetworkCapabilities instead. 12746 final int transportType = idleTimerParams.transportType; 12747 maybeUpdateRadioPowerState(netId, transportType, 12748 activityParams.isActive, activityParams.uid); 12749 12750 if (mDefaultNetwork == null || mDefaultNetwork.netId != netId) { 12751 // This activity change is not for the default network. 12752 return; 12753 } 12754 12755 handleDefaultNetworkActivity(transportType, activityParams.isActive, 12756 activityParams.timestampNs); 12757 } 12758 12759 private void handleReportNetworkActivityWithTransportTypeLabel( 12760 NetworkActivityParams activityParams) { 12761 if (mActiveIdleTimers.size() == 0) { 12762 // This activity change is not for the current default network. 12763 // This can happen if netd callback post activity change event message but 12764 // the default network is lost before processing this message. 12765 return; 12766 } 12767 handleDefaultNetworkActivity(activityParams.label, activityParams.isActive, 12768 activityParams.timestampNs); 12769 } 12770 12771 /** 12772 * Handle network activity change 12773 */ 12774 public void handleReportNetworkActivity(NetworkActivityParams activityParams) { 12775 ensureRunningOnConnectivityServiceThread(); 12776 if (mTrackMultiNetworkActivities) { 12777 handleReportNetworkActivityWithNetIdLabel(activityParams); 12778 } else { 12779 handleReportNetworkActivityWithTransportTypeLabel(activityParams); 12780 } 12781 } 12782 12783 private void reportNetworkActive() { 12784 final int length = mNetworkActivityListeners.beginBroadcast(); 12785 if (DDBG) log("reportNetworkActive, notify " + length + " listeners"); 12786 try { 12787 for (int i = 0; i < length; i++) { 12788 try { 12789 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 12790 } catch (RemoteException | RuntimeException e) { 12791 loge("Fail to send network activity to listener " + e); 12792 } 12793 } 12794 } finally { 12795 mNetworkActivityListeners.finishBroadcast(); 12796 } 12797 } 12798 12799 // This is deprecated and only to support legacy use cases. 12800 private int transportTypeToLegacyType(int type) { 12801 switch (type) { 12802 case NetworkCapabilities.TRANSPORT_CELLULAR: 12803 return TYPE_MOBILE; 12804 case NetworkCapabilities.TRANSPORT_WIFI: 12805 return TYPE_WIFI; 12806 case NetworkCapabilities.TRANSPORT_BLUETOOTH: 12807 return TYPE_BLUETOOTH; 12808 case NetworkCapabilities.TRANSPORT_ETHERNET: 12809 return TYPE_ETHERNET; 12810 default: 12811 loge("Unexpected transport in transportTypeToLegacyType: " + type); 12812 } 12813 return ConnectivityManager.TYPE_NONE; 12814 } 12815 12816 public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 12817 final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 12818 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 12819 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 12820 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 12821 final long ident = Binder.clearCallingIdentity(); 12822 try { 12823 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 12824 RECEIVE_DATA_ACTIVITY_CHANGE, 12825 null /* resultReceiver */, 12826 null /* scheduler */, 12827 0 /* initialCode */, 12828 null /* initialData */, 12829 null /* initialExtra */); 12830 } finally { 12831 Binder.restoreCallingIdentity(ident); 12832 } 12833 } 12834 12835 /** 12836 * Get idle timer label 12837 */ 12838 @VisibleForTesting 12839 public static int getIdleTimerLabel(final boolean trackMultiNetworkActivities, 12840 final int netId, final int transportType) { 12841 return trackMultiNetworkActivities ? netId : transportType; 12842 } 12843 12844 private boolean maybeCreateIdleTimer( 12845 String iface, int netId, int timeout, int transportType) { 12846 if (timeout <= 0 || iface == null) return false; 12847 try { 12848 final String label = Integer.toString(getIdleTimerLabel( 12849 mTrackMultiNetworkActivities, netId, transportType)); 12850 mNetd.idletimerAddInterface(iface, timeout, label); 12851 mActiveIdleTimers.put(netId, new IdleTimerParams(timeout, transportType)); 12852 return true; 12853 } catch (Exception e) { 12854 loge("Exception in createIdleTimer", e); 12855 return false; 12856 } 12857 } 12858 12859 /** 12860 * Setup data activity tracking for the given network. 12861 * 12862 * Every {@code setupDataActivityTracking} should be paired with a 12863 * {@link #removeDataActivityTracking} for cleanup. 12864 * 12865 * @return true if the idleTimer is added to the network, false otherwise 12866 */ 12867 private boolean setupDataActivityTracking(NetworkAgentInfo networkAgent) { 12868 ensureRunningOnConnectivityServiceThread(); 12869 final String iface = networkAgent.linkProperties.getInterfaceName(); 12870 final int netId = networkAgent.network().netId; 12871 12872 final int timeout; 12873 final int type; 12874 12875 if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) { 12876 // Do not track VPN network. 12877 return false; 12878 } else if (networkAgent.networkCapabilities.hasTransport( 12879 NetworkCapabilities.TRANSPORT_CELLULAR)) { 12880 timeout = Settings.Global.getInt(mContext.getContentResolver(), 12881 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE, 12882 10); 12883 type = NetworkCapabilities.TRANSPORT_CELLULAR; 12884 } else if (networkAgent.networkCapabilities.hasTransport( 12885 NetworkCapabilities.TRANSPORT_WIFI)) { 12886 timeout = Settings.Global.getInt(mContext.getContentResolver(), 12887 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI, 12888 15); 12889 type = NetworkCapabilities.TRANSPORT_WIFI; 12890 } else { 12891 return false; // do not track any other networks 12892 } 12893 12894 final boolean hasIdleTimer = maybeCreateIdleTimer(iface, netId, timeout, type); 12895 if (hasIdleTimer || !mTrackMultiNetworkActivities) { 12896 // If trackMultiNetwork is disabled, NetworkActivityTracker updates radio power 12897 // state in all cases. If trackMultiNetwork is enabled, it updates radio power 12898 // state only about a network that has an idletimer. 12899 maybeUpdateRadioPowerState(netId, type, true /* isActive */, NO_UID); 12900 } 12901 return hasIdleTimer; 12902 } 12903 12904 /** 12905 * Remove data activity tracking when network disconnects. 12906 */ 12907 public void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 12908 ensureRunningOnConnectivityServiceThread(); 12909 final String iface = networkAgent.linkProperties.getInterfaceName(); 12910 final int netId = networkAgent.network().netId; 12911 final NetworkCapabilities caps = networkAgent.networkCapabilities; 12912 12913 if (iface == null) return; 12914 12915 final int type; 12916 if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) { 12917 // Do not track VPN network. 12918 return; 12919 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { 12920 type = NetworkCapabilities.TRANSPORT_CELLULAR; 12921 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 12922 type = NetworkCapabilities.TRANSPORT_WIFI; 12923 } else { 12924 return; // do not track any other networks 12925 } 12926 12927 try { 12928 maybeUpdateRadioPowerState(netId, type, false /* isActive */, NO_UID); 12929 final IdleTimerParams params = mActiveIdleTimers.get(netId); 12930 if (params == null) { 12931 // IdleTimer is not added if the configured timeout is 0 or negative value 12932 return; 12933 } 12934 mActiveIdleTimers.remove(netId); 12935 final String label = Integer.toString(getIdleTimerLabel( 12936 mTrackMultiNetworkActivities, netId, params.transportType)); 12937 // The call fails silently if no idle timer setup for this interface 12938 mNetd.idletimerRemoveInterface(iface, params.timeout, label); 12939 } catch (Exception e) { 12940 // You shall not crash! 12941 loge("Exception in removeDataActivityTracking " + e); 12942 } 12943 } 12944 12945 private void updateDefaultNetworkActivity(NetworkAgentInfo defaultNetwork, 12946 boolean hasIdleTimer) { 12947 if (defaultNetwork != null) { 12948 mDefaultNetwork = defaultNetwork.network(); 12949 mIsDefaultNetworkActive = true; 12950 // If only the default network is tracked, callbacks are called only when the 12951 // network has the idle timer. 12952 if (mTrackMultiNetworkActivities || hasIdleTimer) { 12953 reportNetworkActive(); 12954 } 12955 } else { 12956 mDefaultNetwork = null; 12957 // If there is no default network, default network is considered active to keep the 12958 // existing behavior. 12959 mIsDefaultNetworkActive = true; 12960 } 12961 } 12962 12963 /** 12964 * Update the default network this class tracks the activity of. 12965 */ 12966 public void updateDefaultNetwork(NetworkAgentInfo newNetwork, 12967 NetworkAgentInfo oldNetwork) { 12968 ensureRunningOnConnectivityServiceThread(); 12969 // If TrackMultiNetworkActivities is enabled, devices add idleTimer when the network is 12970 // first connected and remove when the network is disconnected. 12971 // If TrackMultiNetworkActivities is disabled, devices add idleTimer when the network 12972 // becomes the default network and remove when the network becomes no longer the default 12973 // network. 12974 boolean hasIdleTimer = false; 12975 if (!mTrackMultiNetworkActivities && newNetwork != null) { 12976 hasIdleTimer = setupDataActivityTracking(newNetwork); 12977 } 12978 updateDefaultNetworkActivity(newNetwork, hasIdleTimer); 12979 if (!mTrackMultiNetworkActivities && oldNetwork != null) { 12980 removeDataActivityTracking(oldNetwork); 12981 } 12982 } 12983 12984 private void updateRadioPowerState(boolean isActive, int transportType, int uid) { 12985 final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class); 12986 switch (transportType) { 12987 case NetworkCapabilities.TRANSPORT_CELLULAR: 12988 bs.reportMobileRadioPowerState(isActive, uid); 12989 break; 12990 case NetworkCapabilities.TRANSPORT_WIFI: 12991 bs.reportWifiRadioPowerState(isActive, uid); 12992 break; 12993 default: 12994 logw("Untracked transport type:" + transportType); 12995 } 12996 } 12997 12998 public boolean isDefaultNetworkActive() { 12999 return mIsDefaultNetworkActive; 13000 } 13001 13002 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 13003 mNetworkActivityListeners.register(l); 13004 } 13005 13006 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 13007 mNetworkActivityListeners.unregister(l); 13008 } 13009 13010 public void dump(IndentingPrintWriter pw) { 13011 pw.print("mTrackMultiNetworkActivities="); pw.println(mTrackMultiNetworkActivities); 13012 pw.print("mIsDefaultNetworkActive="); pw.println(mIsDefaultNetworkActive); 13013 pw.print("mDefaultNetwork="); pw.println(mDefaultNetwork); 13014 pw.println("Idle timers:"); 13015 try { 13016 for (int i = 0; i < mActiveIdleTimers.size(); i++) { 13017 pw.print(" "); pw.print(mActiveIdleTimers.keyAt(i)); pw.println(":"); 13018 final IdleTimerParams params = mActiveIdleTimers.valueAt(i); 13019 pw.print(" timeout="); pw.print(params.timeout); 13020 pw.print(" type="); pw.println(params.transportType); 13021 } 13022 pw.println("WiFi active networks: " + mActiveWifiNetworks); 13023 pw.println("Cellular active networks: " + mActiveCellularNetworks); 13024 } catch (Exception e) { 13025 // mActiveIdleTimers, mActiveWifiNetworks, and mActiveCellularNetworks should only 13026 // be accessed from handler thread, except dump(). As dump() is never called in 13027 // normal usage, it would be needlessly expensive to lock the collection only for 13028 // its benefit. Also, they are not expected to be updated frequently. 13029 // So catching the exception and logging. 13030 pw.println("Failed to dump NetworkActivityTracker: " + e); 13031 } 13032 } 13033 } 13034 13035 /** 13036 * Registers {@link QosSocketFilter} with {@link IQosCallback}. 13037 * 13038 * @param socketInfo the socket information 13039 * @param callback the callback to register 13040 */ 13041 @Override 13042 public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo, 13043 @NonNull final IQosCallback callback) { 13044 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork()); 13045 if (nai == null || nai.networkCapabilities == null) { 13046 try { 13047 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); 13048 } catch (final RemoteException ex) { 13049 loge("registerQosCallbackInternal: RemoteException", ex); 13050 } 13051 return; 13052 } 13053 registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai); 13054 } 13055 13056 /** 13057 * Register a {@link IQosCallback} with base {@link QosFilter}. 13058 * 13059 * @param filter the filter to register 13060 * @param callback the callback to register 13061 * @param nai the agent information related to the filter's network 13062 */ 13063 @VisibleForTesting 13064 public void registerQosCallbackInternal(@NonNull final QosFilter filter, 13065 @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) { 13066 Objects.requireNonNull(filter, "filter must be non-null"); 13067 Objects.requireNonNull(callback, "callback must be non-null"); 13068 13069 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 13070 // TODO: Check allowed list here and ensure that either a) any QoS callback registered 13071 // on this network is unregistered when the app loses permission or b) no QoS 13072 // callbacks are sent for restricted networks unless the app currently has permission 13073 // to access restricted networks. 13074 enforceConnectivityRestrictedNetworksPermission(false /* checkUidsAllowedList */); 13075 } 13076 mQosCallbackTracker.registerCallback(callback, filter, nai); 13077 } 13078 13079 /** 13080 * Unregisters the given callback. 13081 * 13082 * @param callback the callback to unregister 13083 */ 13084 @Override 13085 public void unregisterQosCallback(@NonNull final IQosCallback callback) { 13086 Objects.requireNonNull(callback, "callback must be non-null"); 13087 mQosCallbackTracker.unregisterCallback(callback); 13088 } 13089 13090 private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) { 13091 // UserManager.isManagedProfile returns true for all apps in managed user profiles. 13092 // Enterprise device can be fully managed like device owner and such use case 13093 // also should be supported. Calling app check for work profile and fully managed device 13094 // is already done in DevicePolicyManager. 13095 // This check is an extra caution to be sure device is fully managed or not. 13096 final UserManager um = mContext.getSystemService(UserManager.class); 13097 final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); 13098 if (um.isManagedProfile(profile.getIdentifier())) { 13099 return true; 13100 } 13101 13102 return mDeps.isAtLeastT() && dpm.getDeviceOwnerComponentOnAnyUser() != null; 13103 } 13104 13105 /** 13106 * Set a list of default network selection policies for a user profile or device owner. 13107 * 13108 * See the documentation for the individual preferences for a description of the supported 13109 * behaviors. 13110 * 13111 * @param profile If the device owner is set, any profile is allowed. 13112 Otherwise, the given profile can only be managed profile. 13113 * @param preferences the list of profile network preferences for the 13114 * provided profile. 13115 * @param listener an optional listener to listen for completion of the operation. 13116 */ 13117 @Override 13118 public void setProfileNetworkPreferences( 13119 @NonNull final UserHandle profile, 13120 @NonNull List<ProfileNetworkPreference> preferences, 13121 @Nullable final IOnCompleteListener listener) { 13122 Objects.requireNonNull(preferences); 13123 Objects.requireNonNull(profile); 13124 13125 if (preferences.size() == 0) { 13126 final ProfileNetworkPreference pref = new ProfileNetworkPreference.Builder() 13127 .setPreference(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT) 13128 .build(); 13129 preferences.add(pref); 13130 } 13131 13132 enforceNetworkStackPermission(mContext); 13133 if (DBG) { 13134 log("setProfileNetworkPreferences " + profile + " to " + preferences); 13135 } 13136 if (profile.getIdentifier() < 0) { 13137 throw new IllegalArgumentException("Must explicitly specify a user handle (" 13138 + "UserHandle.CURRENT not supported)"); 13139 } 13140 if (!isNetworkPreferenceAllowedForProfile(profile)) { 13141 throw new IllegalArgumentException("Profile must be a managed profile " 13142 + "or the device owner must be set. "); 13143 } 13144 13145 final List<ProfileNetworkPreferenceInfo> preferenceList = new ArrayList<>(); 13146 boolean hasDefaultPreference = false; 13147 for (final ProfileNetworkPreference preference : preferences) { 13148 final NetworkCapabilities nc; 13149 boolean allowFallback = true; 13150 boolean blockingNonEnterprise = false; 13151 switch (preference.getPreference()) { 13152 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT: 13153 nc = null; 13154 hasDefaultPreference = true; 13155 if (preference.getPreferenceEnterpriseId() != 0) { 13156 throw new IllegalArgumentException( 13157 "Invalid enterprise identifier in setProfileNetworkPreferences"); 13158 } 13159 break; 13160 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING: 13161 blockingNonEnterprise = true; 13162 // continue to process the enterprise preference. 13163 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK: 13164 allowFallback = false; 13165 // continue to process the enterprise preference. 13166 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE: 13167 // This code is needed even though there is a check later on, 13168 // because isRangeAlreadyInPreferenceList assumes that every preference 13169 // has a UID list. 13170 if (hasDefaultPreference) { 13171 throw new IllegalArgumentException( 13172 "Default profile preference should not be set along with other " 13173 + "preference"); 13174 } 13175 if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) { 13176 throw new IllegalArgumentException( 13177 "Invalid enterprise identifier in setProfileNetworkPreferences"); 13178 } 13179 final Set<UidRange> uidRangeSet = 13180 getUidListToBeAppliedForNetworkPreference(profile, preference); 13181 if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) { 13182 nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet); 13183 } else { 13184 throw new IllegalArgumentException( 13185 "Overlapping uid range in setProfileNetworkPreferences"); 13186 } 13187 nc.addCapability(NET_CAPABILITY_ENTERPRISE); 13188 nc.addEnterpriseId( 13189 preference.getPreferenceEnterpriseId()); 13190 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13191 break; 13192 default: 13193 throw new IllegalArgumentException( 13194 "Invalid preference in setProfileNetworkPreferences"); 13195 } 13196 preferenceList.add(new ProfileNetworkPreferenceInfo( 13197 profile, nc, allowFallback, blockingNonEnterprise)); 13198 if (hasDefaultPreference && preferenceList.size() > 1) { 13199 throw new IllegalArgumentException( 13200 "Default profile preference should not be set along with other preference"); 13201 } 13202 } 13203 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE, 13204 new Pair<>(preferenceList, listener))); 13205 } 13206 13207 private Set<UidRange> getUidListToBeAppliedForNetworkPreference( 13208 @NonNull final UserHandle profile, 13209 @NonNull final ProfileNetworkPreference profileNetworkPreference) { 13210 final UidRange profileUids = UidRange.createForUser(profile); 13211 Set<UidRange> uidRangeSet = UidRangeUtils.convertArrayToUidRange( 13212 profileNetworkPreference.getIncludedUids()); 13213 13214 if (uidRangeSet.size() > 0) { 13215 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) { 13216 throw new IllegalArgumentException( 13217 "Allow uid range is outside the uid range of profile."); 13218 } 13219 } else { 13220 ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertArrayToUidRange( 13221 profileNetworkPreference.getExcludedUids()); 13222 if (disallowUidRangeSet.size() > 0) { 13223 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) { 13224 throw new IllegalArgumentException( 13225 "disallow uid range is outside the uid range of profile."); 13226 } 13227 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids, 13228 disallowUidRangeSet); 13229 } else { 13230 uidRangeSet = new ArraySet<>(); 13231 uidRangeSet.add(profileUids); 13232 } 13233 } 13234 return uidRangeSet; 13235 } 13236 13237 private boolean isEnterpriseIdentifierValid( 13238 @NetworkCapabilities.EnterpriseId int identifier) { 13239 if ((identifier >= NET_ENTERPRISE_ID_1) && (identifier <= NET_ENTERPRISE_ID_5)) { 13240 return true; 13241 } 13242 return false; 13243 } 13244 13245 private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences( 13246 @NonNull final NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> prefs) { 13247 final ArraySet<NetworkRequestInfo> result = new ArraySet<>(); 13248 for (final ProfileNetworkPreferenceInfo pref : prefs) { 13249 // The NRI for a user should contain the request for capabilities. 13250 // If fallback to default network is needed then NRI should include 13251 // the request for the default network. Create an image of it to 13252 // have the correct UIDs in it (also a request can only be part of one NRI, because 13253 // of lookups in 1:1 associations like mNetworkRequests). 13254 final ArrayList<NetworkRequest> nrs = new ArrayList<>(); 13255 nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities)); 13256 if (pref.allowFallback) { 13257 nrs.add(createDefaultInternetRequestForTransport( 13258 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 13259 } 13260 if (VDBG) { 13261 loge("pref.capabilities.getUids():" + UidRange.fromIntRanges( 13262 pref.capabilities.getUids())); 13263 } 13264 13265 setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids())); 13266 final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs, 13267 PREFERENCE_ORDER_PROFILE); 13268 result.add(nri); 13269 } 13270 return result; 13271 } 13272 13273 /** 13274 * Compare if the given UID range sets have the same UIDs. 13275 * 13276 */ 13277 private boolean isRangeAlreadyInPreferenceList( 13278 @NonNull List<ProfileNetworkPreferenceInfo> preferenceList, 13279 @NonNull Set<UidRange> uidRangeSet) { 13280 if (uidRangeSet.size() == 0 || preferenceList.size() == 0) { 13281 return false; 13282 } 13283 for (ProfileNetworkPreferenceInfo pref : preferenceList) { 13284 if (UidRangeUtils.doesRangeSetOverlap( 13285 UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) { 13286 return true; 13287 } 13288 } 13289 return false; 13290 } 13291 13292 private void handleSetProfileNetworkPreference( 13293 @NonNull final List<ProfileNetworkPreferenceInfo> preferenceList, 13294 @Nullable final IOnCompleteListener listener) { 13295 /* 13296 * handleSetProfileNetworkPreference is always called for single user. 13297 * preferenceList only contains preferences for different uids within the same user 13298 * (enforced by getUidListToBeAppliedForNetworkPreference). 13299 * Clear all the existing preferences for the user before applying new preferences. 13300 * 13301 */ 13302 mProfileNetworkPreferences = mProfileNetworkPreferences.minus(preferenceList.get(0).user); 13303 for (final ProfileNetworkPreferenceInfo preference : preferenceList) { 13304 mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference); 13305 } 13306 13307 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_PROFILE); 13308 addPerAppDefaultNetworkRequests( 13309 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences)); 13310 updateProfileAllowedNetworks(); 13311 13312 // Finally, rematch. 13313 rematchAllNetworksAndRequests(); 13314 13315 if (null != listener) { 13316 try { 13317 listener.onComplete(); 13318 } catch (RemoteException e) { 13319 loge("Listener for setProfileNetworkPreference has died"); 13320 } 13321 } 13322 } 13323 13324 @VisibleForTesting 13325 @NonNull 13326 ArraySet<NetworkRequestInfo> createNrisForPreferenceOrder(@NonNull final Set<Integer> uids, 13327 @NonNull final List<NetworkRequest> requests, 13328 final int preferenceOrder) { 13329 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 13330 if (uids.size() == 0) { 13331 // Should not create NetworkRequestInfo if no preferences. Without uid range in 13332 // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI. 13333 return nris; 13334 } 13335 13336 final Set<UidRange> ranges = new ArraySet<>(); 13337 for (final int uid : uids) { 13338 ranges.add(new UidRange(uid, uid)); 13339 } 13340 setNetworkRequestUids(requests, ranges); 13341 nris.add(new NetworkRequestInfo(Process.myUid(), requests, preferenceOrder)); 13342 return nris; 13343 } 13344 13345 ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids( 13346 @NonNull final Set<Integer> uids) { 13347 final List<NetworkRequest> requests = new ArrayList<>(); 13348 // The NRI should be comprised of two layers: 13349 // - The request for the mobile network preferred. 13350 // - The request for the default network, for fallback. 13351 requests.add(createDefaultInternetRequestForTransport( 13352 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST)); 13353 requests.add(createDefaultInternetRequestForTransport( 13354 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 13355 return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED 13356 ); 13357 } 13358 13359 ArraySet<NetworkRequestInfo> createMultiLayerNrisFromSatelliteNetworkFallbackUids( 13360 @NonNull final Set<Integer> uids) { 13361 final List<NetworkRequest> requests = new ArrayList<>(); 13362 13363 // request: track default(unrestricted internet network) 13364 requests.add(createDefaultInternetRequestForTransport( 13365 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 13366 13367 // request: Satellite internet, satellite network could be restricted or constrained 13368 final NetworkCapabilities cap = new NetworkCapabilities.Builder() 13369 .addCapability(NET_CAPABILITY_INTERNET) 13370 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 13371 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 13372 .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) 13373 .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE) 13374 .build(); 13375 requests.add(createNetworkRequest(NetworkRequest.Type.REQUEST, cap)); 13376 13377 return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_SATELLITE_FALLBACK); 13378 } 13379 13380 private void handleMobileDataPreferredUidsChanged() { 13381 mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext); 13382 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 13383 addPerAppDefaultNetworkRequests( 13384 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids)); 13385 // Finally, rematch. 13386 rematchAllNetworksAndRequests(); 13387 } 13388 13389 private void handleSetSatelliteNetworkPreference( 13390 @NonNull final Set<Integer> satelliteNetworkPreferredUids) { 13391 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_SATELLITE_FALLBACK); 13392 addPerAppDefaultNetworkRequests( 13393 createMultiLayerNrisFromSatelliteNetworkFallbackUids(satelliteNetworkPreferredUids) 13394 ); 13395 // Finally, rematch. 13396 rematchAllNetworksAndRequests(); 13397 } 13398 13399 private void handleIngressRateLimitChanged() { 13400 final long oldIngressRateLimit = mIngressRateLimit; 13401 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 13402 mContext); 13403 for (final NetworkAgentInfo networkAgent : mNetworkAgentInfos) { 13404 if (canNetworkBeRateLimited(networkAgent)) { 13405 // If rate limit has previously been enabled, remove the old limit first. 13406 if (oldIngressRateLimit >= 0) { 13407 mDeps.disableIngressRateLimit(networkAgent.linkProperties.getInterfaceName()); 13408 } 13409 if (mIngressRateLimit >= 0) { 13410 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 13411 mIngressRateLimit); 13412 } 13413 } 13414 } 13415 } 13416 13417 private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) { 13418 // Rate-limiting cannot run correctly before T because the BPF program is not loaded. 13419 if (!mDeps.isAtLeastT()) return false; 13420 13421 final NetworkCapabilities agentCaps = networkAgent.networkCapabilities; 13422 // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide 13423 // internet connectivity can be rate limited. 13424 if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport( 13425 TRANSPORT_TEST)) { 13426 return false; 13427 } 13428 13429 final String iface = networkAgent.linkProperties.getInterfaceName(); 13430 if (iface == null) { 13431 // This may happen in tests, but if there is no interface then there is nothing that 13432 // can be rate limited. 13433 loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null"); 13434 return false; 13435 } 13436 return true; 13437 } 13438 13439 private void enforceAutomotiveDevice() { 13440 PermissionUtils.enforceSystemFeature(mContext, PackageManager.FEATURE_AUTOMOTIVE, 13441 "setOemNetworkPreference() is only available on automotive devices."); 13442 } 13443 13444 /** 13445 * Used by automotive devices to set the network preferences used to direct traffic at an 13446 * application level as per the given OemNetworkPreferences. An example use-case would be an 13447 * automotive OEM wanting to provide connectivity for applications critical to the usage of a 13448 * vehicle via a particular network. 13449 * 13450 * Calling this will overwrite the existing preference. 13451 * 13452 * @param preference {@link OemNetworkPreferences} The application network preference to be set. 13453 * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used 13454 * to communicate completion of setOemNetworkPreference(); 13455 */ 13456 @Override 13457 public void setOemNetworkPreference( 13458 @NonNull final OemNetworkPreferences preference, 13459 @Nullable final IOnCompleteListener listener) { 13460 13461 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 13462 // Only bypass the permission/device checks if this is a valid test request. 13463 if (isValidTestOemNetworkPreference(preference)) { 13464 enforceManageTestNetworksPermission(); 13465 } else { 13466 enforceAutomotiveDevice(); 13467 enforceOemNetworkPreferencesPermission(); 13468 validateOemNetworkPreferences(preference); 13469 } 13470 13471 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE, 13472 new Pair<>(preference, listener))); 13473 } 13474 13475 /** 13476 * Sets the specified UIDs to get/receive the VPN as the only default network. 13477 * 13478 * Calling this will overwrite the existing network preference for this session, and the 13479 * specified UIDs won't get any default network when no VPN is connected. 13480 * 13481 * @param session The VPN session which manages the passed UIDs. 13482 * @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the 13483 * setting for this session if the array is empty. Null is not allowed, the 13484 * method will use {@link Objects#requireNonNull(Object)} to check this variable. 13485 * @hide 13486 */ 13487 @Override 13488 public void setVpnNetworkPreference(String session, UidRange[] ranges) { 13489 Objects.requireNonNull(ranges); 13490 enforceNetworkStackOrSettingsPermission(); 13491 final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges); 13492 if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) { 13493 throw new IllegalArgumentException( 13494 "setVpnNetworkPreference: Passed UID ranges overlap"); 13495 } 13496 13497 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE, 13498 new VpnNetworkPreferenceInfo(session, 13499 new ArraySet<UidRange>(Arrays.asList(ranges))))); 13500 } 13501 13502 private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) { 13503 Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo); 13504 13505 mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey()); 13506 mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo); 13507 13508 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN); 13509 addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences)); 13510 // Finally, rematch. 13511 rematchAllNetworksAndRequests(); 13512 } 13513 13514 private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference( 13515 @NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) { 13516 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 13517 for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) { 13518 final List<NetworkRequest> requests = new ArrayList<>(); 13519 // Request VPN only, so other networks won't be the fallback options when VPN is not 13520 // connected temporarily. 13521 requests.add(createVpnRequest()); 13522 final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy()); 13523 setNetworkRequestUids(requests, uidRanges); 13524 nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN)); 13525 } 13526 return nris; 13527 } 13528 13529 /** 13530 * Check the validity of an OEM network preference to be used for testing purposes. 13531 * @param preference the preference to validate 13532 * @return true if this is a valid OEM network preference test request. 13533 */ 13534 private boolean isValidTestOemNetworkPreference( 13535 @NonNull final OemNetworkPreferences preference) { 13536 // Allow for clearing of an existing OemNetworkPreference used for testing. 13537 // This isn't called on the handler thread so it is possible that mOemNetworkPreferences 13538 // changes after this check is complete. This is an unlikely scenario as calling of this API 13539 // is controlled by the OEM therefore the added complexity is not worth adding given those 13540 // circumstances. That said, it is an edge case to be aware of hence this comment. 13541 final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0 13542 && isTestOemNetworkPreference(mOemNetworkPreferences); 13543 return isTestOemNetworkPreference(preference) || isValidTestClearPref; 13544 } 13545 13546 private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) { 13547 final Map<String, Integer> prefMap = preference.getNetworkPreferences(); 13548 return prefMap.size() == 1 13549 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST) 13550 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY)); 13551 } 13552 13553 private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) { 13554 for (@OemNetworkPreferences.OemNetworkPreference final int pref 13555 : preference.getNetworkPreferences().values()) { 13556 if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) { 13557 throw new IllegalArgumentException( 13558 OemNetworkPreferences.oemNetworkPreferenceToString(pref) 13559 + " is an invalid value."); 13560 } 13561 } 13562 } 13563 13564 private void handleSetOemNetworkPreference( 13565 @NonNull final OemNetworkPreferences preference, 13566 @Nullable final IOnCompleteListener listener) { 13567 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 13568 if (DBG) { 13569 log("set OEM network preferences :" + preference.toString()); 13570 } 13571 13572 mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference); 13573 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_OEM); 13574 addPerAppDefaultNetworkRequests(new OemNetworkRequestFactory() 13575 .createNrisFromOemNetworkPreferences(preference)); 13576 mOemNetworkPreferences = preference; 13577 13578 if (null != listener) { 13579 try { 13580 listener.onComplete(); 13581 } catch (RemoteException e) { 13582 loge("Can't send onComplete in handleSetOemNetworkPreference", e); 13583 } 13584 } 13585 } 13586 13587 private void removeDefaultNetworkRequestsForPreference(final int preferenceOrder) { 13588 // Skip the requests which are set by other network preference. Because the uid range rules 13589 // should stay in netd. 13590 final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests); 13591 requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder); 13592 handleRemoveNetworkRequests(requests); 13593 } 13594 13595 private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 13596 ensureRunningOnConnectivityServiceThread(); 13597 mDefaultNetworkRequests.addAll(nris); 13598 final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate = 13599 getPerAppCallbackRequestsToUpdate(); 13600 final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris); 13601 // This method does not need to modify perUidCounter and mBlockedStatusTrackingUids because: 13602 // - |nris| only contains per-app network requests created by ConnectivityService which 13603 // are internal requests and have no messenger and are not associated with any callbacks, 13604 // and so do not need to be tracked in perUidCounter and mBlockedStatusTrackingUids. 13605 // - The requests in perAppCallbackRequestsToUpdate are removed, modified, and re-added, 13606 // but the same number of requests is removed and re-added, and none of the requests 13607 // changes mUid and mAsUid, so the perUidCounter and mBlockedStatusTrackingUids before 13608 // and after this method remains the same. Re-adding the requests does not modify 13609 // perUidCounter and mBlockedStatusTrackingUids (that is done when the app registers the 13610 // request), so removing them must not modify perUidCounter and mBlockedStatusTrackingUids 13611 // either. 13612 // TODO(b/341228979): Modify nris in place instead of removing them and re-adding them 13613 handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate, 13614 false /* untrackUids */); 13615 nrisToRegister.addAll( 13616 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate)); 13617 handleRegisterNetworkRequests(nrisToRegister); 13618 } 13619 13620 /** 13621 * All current requests that are tracking the default network need to be assessed as to whether 13622 * or not the current set of per-application default requests will be changing their default 13623 * network. If so, those requests will need to be updated so that they will send callbacks for 13624 * default network changes at the appropriate time. Additionally, those requests tracking the 13625 * default that were previously updated by this flow will need to be reassessed. 13626 * @return the nris which will need to be updated. 13627 */ 13628 private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() { 13629 final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>(); 13630 // Get the distinct nris to check since for multilayer requests, it is possible to have the 13631 // same nri in the map's values for each of its NetworkRequest objects. 13632 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values()); 13633 for (final NetworkRequestInfo nri : nris) { 13634 // Include this nri if it is currently being tracked. 13635 if (isPerAppTrackedNri(nri)) { 13636 defaultCallbackRequests.add(nri); 13637 continue; 13638 } 13639 // We only track callbacks for requests tracking the default. 13640 if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) { 13641 continue; 13642 } 13643 // Include this nri if it will be tracked by the new per-app default requests. 13644 final boolean isNriGoingToBeTracked = 13645 getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest; 13646 if (isNriGoingToBeTracked) { 13647 defaultCallbackRequests.add(nri); 13648 } 13649 } 13650 return defaultCallbackRequests; 13651 } 13652 13653 /** 13654 * Create nris for those network requests that are currently tracking the default network that 13655 * are being controlled by a per-application default. 13656 * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the 13657 * foundation when creating the nri. Important items include the calling uid's original 13658 * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These 13659 * requests are assumed to have already been validated as needing to be updated. 13660 * @return the Set of nris to use when registering network requests. 13661 */ 13662 private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister( 13663 @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) { 13664 final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>(); 13665 for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) { 13666 final NetworkRequestInfo trackingNri = 13667 getDefaultRequestTrackingUid(callbackRequest.mAsUid); 13668 13669 // If this nri is not being tracked, then change it back to an untracked nri. 13670 if (trackingNri == mDefaultRequest) { 13671 callbackRequestsToRegister.add(new NetworkRequestInfo( 13672 callbackRequest, 13673 Collections.singletonList(callbackRequest.getNetworkRequestForCallback()))); 13674 continue; 13675 } 13676 13677 final NetworkRequest request = callbackRequest.mRequests.get(0); 13678 callbackRequestsToRegister.add(new NetworkRequestInfo( 13679 callbackRequest, 13680 copyNetworkRequestsForUid( 13681 trackingNri.mRequests, callbackRequest.mAsUid, 13682 callbackRequest.mUid, request.getRequestorPackageName()))); 13683 } 13684 return callbackRequestsToRegister; 13685 } 13686 13687 private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests, 13688 @NonNull final Set<UidRange> uids) { 13689 for (final NetworkRequest req : requests) { 13690 req.networkCapabilities.setUids(UidRange.toIntRanges(uids)); 13691 } 13692 } 13693 13694 /** 13695 * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}. 13696 */ 13697 @VisibleForTesting 13698 final class OemNetworkRequestFactory { 13699 ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences( 13700 @NonNull final OemNetworkPreferences preference) { 13701 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 13702 final SparseArray<Set<Integer>> uids = 13703 createUidsFromOemNetworkPreferences(preference); 13704 for (int i = 0; i < uids.size(); i++) { 13705 final int key = uids.keyAt(i); 13706 final Set<Integer> value = uids.valueAt(i); 13707 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value); 13708 // No need to add an nri without any requests. 13709 if (0 == nri.mRequests.size()) { 13710 continue; 13711 } 13712 nris.add(nri); 13713 } 13714 13715 return nris; 13716 } 13717 13718 private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences( 13719 @NonNull final OemNetworkPreferences preference) { 13720 final SparseArray<Set<Integer>> prefToUids = new SparseArray<>(); 13721 final PackageManager pm = mContext.getPackageManager(); 13722 final List<UserHandle> users = 13723 mContext.getSystemService(UserManager.class).getUserHandles(true); 13724 if (null == users || users.size() == 0) { 13725 if (VDBG || DDBG) { 13726 log("No users currently available for setting the OEM network preference."); 13727 } 13728 return prefToUids; 13729 } 13730 for (final Map.Entry<String, Integer> entry : 13731 preference.getNetworkPreferences().entrySet()) { 13732 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue(); 13733 // Add the rules for all users as this policy is device wide. 13734 for (final UserHandle user : users) { 13735 try { 13736 final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid; 13737 if (!prefToUids.contains(pref)) { 13738 prefToUids.put(pref, new ArraySet<>()); 13739 } 13740 prefToUids.get(pref).add(uid); 13741 } catch (PackageManager.NameNotFoundException e) { 13742 // Although this may seem like an error scenario, it is ok that uninstalled 13743 // packages are sent on a network preference as the system will watch for 13744 // package installations associated with this network preference and update 13745 // accordingly. This is done to minimize race conditions on app install. 13746 continue; 13747 } 13748 } 13749 } 13750 return prefToUids; 13751 } 13752 13753 private NetworkRequestInfo createNriFromOemNetworkPreferences( 13754 @OemNetworkPreferences.OemNetworkPreference final int preference, 13755 @NonNull final Set<Integer> uids) { 13756 final List<NetworkRequest> requests = new ArrayList<>(); 13757 // Requests will ultimately be evaluated by order of insertion therefore it matters. 13758 switch (preference) { 13759 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID: 13760 requests.add(createUnmeteredNetworkRequest()); 13761 requests.add(createOemPaidNetworkRequest()); 13762 requests.add(createDefaultInternetRequestForTransport( 13763 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 13764 break; 13765 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK: 13766 requests.add(createUnmeteredNetworkRequest()); 13767 requests.add(createOemPaidNetworkRequest()); 13768 break; 13769 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY: 13770 requests.add(createOemPaidNetworkRequest()); 13771 break; 13772 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY: 13773 requests.add(createOemPrivateNetworkRequest()); 13774 break; 13775 case OEM_NETWORK_PREFERENCE_TEST: 13776 requests.add(createUnmeteredNetworkRequest()); 13777 requests.add(createTestNetworkRequest()); 13778 requests.add(createDefaultRequest()); 13779 break; 13780 case OEM_NETWORK_PREFERENCE_TEST_ONLY: 13781 requests.add(createTestNetworkRequest()); 13782 break; 13783 default: 13784 // This should never happen. 13785 throw new IllegalArgumentException("createNriFromOemNetworkPreferences()" 13786 + " called with invalid preference of " + preference); 13787 } 13788 13789 final ArraySet<UidRange> ranges = new ArraySet<>(); 13790 for (final int uid : uids) { 13791 ranges.add(new UidRange(uid, uid)); 13792 } 13793 setNetworkRequestUids(requests, ranges); 13794 return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM); 13795 } 13796 13797 private NetworkRequest createUnmeteredNetworkRequest() { 13798 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 13799 .addCapability(NET_CAPABILITY_NOT_METERED) 13800 .addCapability(NET_CAPABILITY_VALIDATED); 13801 return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap); 13802 } 13803 13804 private NetworkRequest createOemPaidNetworkRequest() { 13805 // NET_CAPABILITY_OEM_PAID is a restricted capability. 13806 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 13807 .addCapability(NET_CAPABILITY_OEM_PAID) 13808 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13809 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 13810 } 13811 13812 private NetworkRequest createOemPrivateNetworkRequest() { 13813 // NET_CAPABILITY_OEM_PRIVATE is a restricted capability. 13814 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 13815 .addCapability(NET_CAPABILITY_OEM_PRIVATE) 13816 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13817 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 13818 } 13819 13820 private NetworkCapabilities createDefaultPerAppNetCap() { 13821 final NetworkCapabilities netcap = new NetworkCapabilities(); 13822 netcap.addCapability(NET_CAPABILITY_INTERNET); 13823 netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 13824 return netcap; 13825 } 13826 13827 private NetworkRequest createTestNetworkRequest() { 13828 final NetworkCapabilities netcap = new NetworkCapabilities(); 13829 netcap.clearAll(); 13830 netcap.addTransportType(TRANSPORT_TEST); 13831 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 13832 } 13833 } 13834 13835 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 13836 @Override 13837 public void setDataSaverEnabled(final boolean enable) { 13838 enforceNetworkStackOrSettingsPermission(); 13839 try { 13840 final boolean ret = mNetd.bandwidthEnableDataSaver(enable); 13841 if (!ret) { 13842 throw new IllegalStateException("Error when changing iptables: " + enable); 13843 } 13844 } catch (RemoteException e) { 13845 // Lack of permission or binder errors. 13846 throw new IllegalStateException(e); 13847 } 13848 13849 synchronized (mBlockedStatusTrackingUids) { 13850 try { 13851 mBpfNetMaps.setDataSaverEnabled(enable); 13852 } catch (ServiceSpecificException | UnsupportedOperationException e) { 13853 Log.e(TAG, "Failed to set data saver " + enable + " : " + e); 13854 return; 13855 } 13856 13857 if (shouldTrackUidsForBlockedStatusCallbacks()) { 13858 updateTrackingUidsBlockedReasons(); 13859 } 13860 } 13861 } 13862 13863 private int setPackageFirewallRule(final int chain, final String packageName, final int rule) 13864 throws PackageManager.NameNotFoundException { 13865 final PackageManager pm = mContext.getPackageManager(); 13866 final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */)); 13867 if (appId < Process.FIRST_APPLICATION_UID) { 13868 throw new RuntimeException("Can't set package firewall rule for system app " 13869 + packageName + " with appId " + appId); 13870 } 13871 for (final UserHandle uh : mUserManager.getUserHandles(false /* excludeDying */)) { 13872 final int uid = uh.getUid(appId); 13873 setUidFirewallRule(chain, uid, rule); 13874 } 13875 return appId; 13876 } 13877 13878 @Override 13879 public void setUidFirewallRule(final int chain, final int uid, final int rule) { 13880 enforceNetworkStackOrSettingsPermission(); 13881 13882 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 13883 Log.i(TAG, "Ignoring operation setUidFirewallRule on the background chain because the" 13884 + " feature is disabled."); 13885 return; 13886 } 13887 13888 // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY 13889 int firewallRule = getFirewallRuleType(chain, rule); 13890 13891 if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) { 13892 throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule); 13893 } 13894 13895 synchronized (mBlockedStatusTrackingUids) { 13896 try { 13897 mBpfNetMaps.setUidRule(chain, uid, firewallRule); 13898 } catch (ServiceSpecificException e) { 13899 throw new IllegalStateException(e); 13900 } 13901 if (shouldTrackUidsForBlockedStatusCallbacks() 13902 && mBlockedStatusTrackingUids.get(uid, 0) != 0) { 13903 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 13904 List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))))); 13905 } 13906 if (shouldTrackFirewallDestroySocketReasons()) { 13907 maybePostFirewallDestroySocketReasons(chain, Set.of(uid)); 13908 } 13909 } 13910 } 13911 13912 private int getPackageFirewallRule(final int chain, final String packageName) 13913 throws PackageManager.NameNotFoundException { 13914 final PackageManager pm = mContext.getPackageManager(); 13915 final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */)); 13916 return getUidFirewallRule(chain, appId); 13917 } 13918 13919 @Override 13920 public int getUidFirewallRule(final int chain, final int uid) { 13921 enforceNetworkStackOrSettingsPermission(); 13922 return mBpfNetMaps.getUidRule(chain, uid); 13923 } 13924 13925 private int getFirewallRuleType(int chain, int rule) { 13926 final int defaultRule; 13927 switch (chain) { 13928 case ConnectivityManager.FIREWALL_CHAIN_STANDBY: 13929 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1: 13930 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2: 13931 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3: 13932 case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER: 13933 case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN: 13934 defaultRule = FIREWALL_RULE_ALLOW; 13935 break; 13936 case ConnectivityManager.FIREWALL_CHAIN_DOZABLE: 13937 case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: 13938 case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: 13939 case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: 13940 case ConnectivityManager.FIREWALL_CHAIN_BACKGROUND: 13941 case ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW: 13942 defaultRule = FIREWALL_RULE_DENY; 13943 break; 13944 default: 13945 throw new IllegalArgumentException("Unsupported firewall chain: " + chain); 13946 } 13947 if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule; 13948 13949 return rule; 13950 } 13951 13952 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 13953 private Set<Integer> getUidsOnFirewallChain(final int chain) throws ErrnoException { 13954 if (BpfNetMapsUtils.isFirewallAllowList(chain)) { 13955 return mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(chain); 13956 } else { 13957 return mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(chain); 13958 } 13959 } 13960 13961 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 13962 private void closeSocketsForFirewallChainLocked(final int chain) 13963 throws ErrnoException, SocketException, InterruptedIOException { 13964 final Set<Integer> uidsOnChain = getUidsOnFirewallChain(chain); 13965 if (BpfNetMapsUtils.isFirewallAllowList(chain)) { 13966 // Allowlist means the firewall denies all by default, uids must be explicitly allowed 13967 // So, close all non-system socket owned by uids that are not explicitly allowed 13968 Set<Range<Integer>> ranges = new ArraySet<>(); 13969 ranges.add(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE)); 13970 mDeps.destroyLiveTcpSockets(ranges, uidsOnChain /* exemptUids */); 13971 } else { 13972 // Denylist means the firewall allows all by default, uids must be explicitly denied 13973 // So, close socket owned by uids that are explicitly denied 13974 mDeps.destroyLiveTcpSocketsByOwnerUids(uidsOnChain /* ownerUids */); 13975 } 13976 } 13977 13978 private void maybePostClearFirewallDestroySocketReasons(int chain) { 13979 if (chain != FIREWALL_CHAIN_BACKGROUND) { 13980 // TODO (b/300681644): Support other firewall chains 13981 return; 13982 } 13983 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS, 13984 DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND, 0 /* arg2 */)); 13985 } 13986 13987 @Override 13988 public void setFirewallChainEnabled(final int chain, final boolean enable) { 13989 enforceNetworkStackOrSettingsPermission(); 13990 13991 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 13992 Log.i(TAG, "Ignoring operation setFirewallChainEnabled on the background chain because" 13993 + " the feature is disabled."); 13994 return; 13995 } 13996 if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) { 13997 // Metered chains are used from a separate bpf program that is triggered by iptables 13998 // and can not be controlled by setFirewallChainEnabled. 13999 throw new UnsupportedOperationException( 14000 "Chain (" + chain + ") can not be controlled by setFirewallChainEnabled"); 14001 } 14002 14003 synchronized (mBlockedStatusTrackingUids) { 14004 try { 14005 mBpfNetMaps.setChildChain(chain, enable); 14006 } catch (ServiceSpecificException e) { 14007 throw new IllegalStateException(e); 14008 } 14009 if (shouldTrackUidsForBlockedStatusCallbacks()) { 14010 updateTrackingUidsBlockedReasons(); 14011 } 14012 if (shouldTrackFirewallDestroySocketReasons() && !enable) { 14013 // Clear destroy socket reasons so that CS does not destroy sockets of apps that 14014 // have network access. 14015 maybePostClearFirewallDestroySocketReasons(chain); 14016 } 14017 } 14018 14019 if (mDeps.isAtLeastU() && enable) { 14020 try { 14021 closeSocketsForFirewallChainLocked(chain); 14022 } catch (ErrnoException | SocketException | InterruptedIOException e) { 14023 Log.e(TAG, "Failed to close sockets after enabling chain (" + chain + "): " + e); 14024 } 14025 } 14026 } 14027 14028 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14029 @GuardedBy("mBlockedStatusTrackingUids") 14030 private void updateTrackingUidsBlockedReasons() { 14031 if (mBlockedStatusTrackingUids.size() == 0) { 14032 return; 14033 } 14034 final ArrayList<Pair<Integer, Integer>> uidBlockedReasonsList = new ArrayList<>(); 14035 for (int i = 0; i < mBlockedStatusTrackingUids.size(); i++) { 14036 final int uid = mBlockedStatusTrackingUids.keyAt(i); 14037 uidBlockedReasonsList.add( 14038 new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))); 14039 } 14040 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 14041 uidBlockedReasonsList)); 14042 } 14043 14044 private int getFirewallDestroySocketReasons(final int blockedReasons) { 14045 int destroySocketReasons = DESTROY_SOCKET_REASON_NONE; 14046 if ((blockedReasons & BLOCKED_REASON_APP_BACKGROUND) != BLOCKED_REASON_NONE) { 14047 destroySocketReasons |= DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND; 14048 } 14049 return destroySocketReasons; 14050 } 14051 14052 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14053 @GuardedBy("mBlockedStatusTrackingUids") 14054 private void maybePostFirewallDestroySocketReasons(int chain, Set<Integer> uids) { 14055 if (chain != FIREWALL_CHAIN_BACKGROUND) { 14056 // TODO (b/300681644): Support other firewall chains 14057 return; 14058 } 14059 final ArrayList<Pair<Integer, Integer>> reasonsList = new ArrayList<>(); 14060 for (int uid: uids) { 14061 final int blockedReasons = mBpfNetMaps.getUidNetworkingBlockedReasons(uid); 14062 final int destroySocketReaons = getFirewallDestroySocketReasons(blockedReasons); 14063 reasonsList.add(new Pair<>(uid, destroySocketReaons)); 14064 } 14065 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS, 14066 reasonsList)); 14067 } 14068 14069 @Override 14070 public boolean getFirewallChainEnabled(final int chain) { 14071 enforceNetworkStackOrSettingsPermission(); 14072 14073 if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) { 14074 // Metered chains are used from a separate bpf program that is triggered by iptables 14075 // and can not be controlled by setFirewallChainEnabled. 14076 throw new UnsupportedOperationException( 14077 "getFirewallChainEnabled can not return status of chain (" + chain + ")"); 14078 } 14079 14080 return mBpfNetMaps.isChainEnabled(chain); 14081 } 14082 14083 @Override 14084 public void replaceFirewallChain(final int chain, final int[] uids) { 14085 enforceNetworkStackOrSettingsPermission(); 14086 14087 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 14088 Log.i(TAG, "Ignoring operation replaceFirewallChain on the background chain because" 14089 + " the feature is disabled."); 14090 return; 14091 } 14092 14093 synchronized (mBlockedStatusTrackingUids) { 14094 // replaceFirewallChain removes uids that are currently on the chain and put |uids| on 14095 // the chain. 14096 // So this method could change blocked reasons of uids that are currently on chain + 14097 // |uids|. 14098 final Set<Integer> affectedUids = new ArraySet<>(); 14099 if (shouldTrackFirewallDestroySocketReasons()) { 14100 try { 14101 affectedUids.addAll(getUidsOnFirewallChain(chain)); 14102 } catch (ErrnoException e) { 14103 Log.e(TAG, "Failed to get uids on chain(" + chain + "): " + e); 14104 } 14105 for (final int uid: uids) { 14106 affectedUids.add(uid); 14107 } 14108 } 14109 14110 mBpfNetMaps.replaceUidChain(chain, uids); 14111 if (shouldTrackUidsForBlockedStatusCallbacks()) { 14112 updateTrackingUidsBlockedReasons(); 14113 } 14114 if (shouldTrackFirewallDestroySocketReasons()) { 14115 maybePostFirewallDestroySocketReasons(chain, affectedUids); 14116 } 14117 } 14118 } 14119 14120 @Override 14121 public IBinder getCompanionDeviceManagerProxyService() { 14122 enforceNetworkStackPermission(mContext); 14123 return mCdmps; 14124 } 14125 14126 @Override 14127 public IBinder getRoutingCoordinatorService() { 14128 enforceNetworkStackPermission(mContext); 14129 return mRoutingCoordinatorService; 14130 } 14131 14132 @Override 14133 public long getEnabledConnectivityManagerFeatures() { 14134 long features = 0; 14135 // The bitmask must be built based on final properties initialized in the constructor, to 14136 // ensure that it does not change over time and is always consistent between 14137 // ConnectivityManager and ConnectivityService. 14138 if (mUseDeclaredMethodsForCallbacksEnabled) { 14139 features |= ConnectivityManager.FEATURE_USE_DECLARED_METHODS_FOR_CALLBACKS; 14140 } 14141 return features; 14142 } 14143 } 14144