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_NETWORK_RESTRICTED; 42 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 43 import static android.net.ConnectivityManager.CALLBACK_AVAILABLE; 44 import static android.net.ConnectivityManager.CALLBACK_BLK_CHANGED; 45 import static android.net.ConnectivityManager.CALLBACK_CAP_CHANGED; 46 import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED; 47 import static android.net.ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED; 48 import static android.net.ConnectivityManager.CALLBACK_LOSING; 49 import static android.net.ConnectivityManager.CALLBACK_LOST; 50 import static android.net.ConnectivityManager.CALLBACK_PRECHECK; 51 import static android.net.ConnectivityManager.CALLBACK_RESERVED; 52 import static android.net.ConnectivityManager.CALLBACK_RESUMED; 53 import static android.net.ConnectivityManager.CALLBACK_SUSPENDED; 54 import static android.net.ConnectivityManager.CALLBACK_UNAVAIL; 55 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; 57 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 58 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 59 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 60 import static android.net.ConnectivityManager.NETID_UNSET; 61 import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_ALL; 62 import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_NONE; 63 import static android.net.ConnectivityManager.TYPE_BLUETOOTH; 64 import static android.net.ConnectivityManager.TYPE_ETHERNET; 65 import static android.net.ConnectivityManager.TYPE_MOBILE; 66 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS; 67 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 68 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY; 69 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 70 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 71 import static android.net.ConnectivityManager.TYPE_MOBILE_IA; 72 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS; 73 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 74 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 75 import static android.net.ConnectivityManager.TYPE_NONE; 76 import static android.net.ConnectivityManager.TYPE_PROXY; 77 import static android.net.ConnectivityManager.TYPE_VPN; 78 import static android.net.ConnectivityManager.TYPE_WIFI; 79 import static android.net.ConnectivityManager.TYPE_WIFI_P2P; 80 import static android.net.ConnectivityManager.getNetworkTypeName; 81 import static android.net.ConnectivityManager.isNetworkTypeValid; 82 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 83 import static android.net.INetd.PERMISSION_INTERNET; 84 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 85 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 86 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_SKIPPED; 87 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 88 import static android.net.MulticastRoutingConfig.FORWARD_NONE; 89 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 90 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 91 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 92 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 93 import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK; 94 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED; 95 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 96 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 97 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 98 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 103 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 104 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 105 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 106 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 107 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 108 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 109 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 110 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 111 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 112 import static android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS; 113 import static android.net.NetworkCapabilities.RES_ID_UNSET; 114 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 115 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 116 import static android.net.NetworkCapabilities.TRANSPORT_THREAD; 117 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 118 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 119 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; 120 import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY; 121 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 122 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 123 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_LOCAL_NETWORK; 124 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_NON_THREAD_LOCAL_NETWORKS; 125 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION; 126 import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION; 127 import static android.os.Process.INVALID_UID; 128 import static android.os.Process.VPN_UID; 129 import static android.system.OsConstants.ENOENT; 130 import static android.system.OsConstants.ENOTCONN; 131 import static android.system.OsConstants.EOPNOTSUPP; 132 import static android.system.OsConstants.ETH_P_ALL; 133 import static android.system.OsConstants.IPPROTO_TCP; 134 import static android.system.OsConstants.IPPROTO_UDP; 135 136 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_GETSOCKOPT; 137 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND; 138 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_CONNECT; 139 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND; 140 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_CONNECT; 141 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS; 142 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS; 143 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE; 144 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_RELEASE; 145 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_SETSOCKOPT; 146 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_RECVMSG; 147 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_SENDMSG; 148 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_RECVMSG; 149 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_SENDMSG; 150 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired; 151 import static com.android.net.module.util.NetworkStackConstants.IPV4_LOCAL_PREFIXES; 152 import static com.android.net.module.util.NetworkStackConstants.MULTICAST_AND_BROADCAST_PREFIXES; 153 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf; 154 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission; 155 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr; 156 import static com.android.net.module.util.PermissionUtils.hasAnyPermissionOf; 157 import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE; 158 import static com.android.server.connectivity.ConnectivityFlags.CELLULAR_DATA_INACTIVITY_TIMEOUT; 159 import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS; 160 import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING; 161 import static com.android.server.connectivity.ConnectivityFlags.NAMESPACE_TETHERING_BOOT; 162 import static com.android.server.connectivity.ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS; 163 import static com.android.server.connectivity.ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER; 164 import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI; 165 import static com.android.server.connectivity.ConnectivityFlags.WIFI_DATA_INACTIVITY_TIMEOUT; 166 167 import android.Manifest; 168 import android.annotation.CheckResult; 169 import android.annotation.NonNull; 170 import android.annotation.Nullable; 171 import android.annotation.RequiresApi; 172 import android.annotation.SuppressLint; 173 import android.annotation.TargetApi; 174 import android.app.ActivityManager; 175 import android.app.ActivityManager.UidFrozenStateChangedCallback; 176 import android.app.AppOpsManager; 177 import android.app.BroadcastOptions; 178 import android.app.PendingIntent; 179 import android.app.admin.DevicePolicyManager; 180 import android.app.compat.CompatChanges; 181 import android.app.usage.NetworkStatsManager; 182 import android.content.BroadcastReceiver; 183 import android.content.ComponentName; 184 import android.content.ContentResolver; 185 import android.content.Context; 186 import android.content.Intent; 187 import android.content.IntentFilter; 188 import android.content.pm.PackageManager; 189 import android.content.res.XmlResourceParser; 190 import android.database.ContentObserver; 191 import android.net.BpfNetMapsUtils; 192 import android.net.CaptivePortal; 193 import android.net.CaptivePortalData; 194 import android.net.ConnectionInfo; 195 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 196 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 197 import android.net.ConnectivityManager; 198 import android.net.ConnectivityManager.BlockedReason; 199 import android.net.ConnectivityManager.NetworkCallback; 200 import android.net.ConnectivityManager.RestrictBackgroundStatus; 201 import android.net.ConnectivitySettingsManager; 202 import android.net.DataStallReportParcelable; 203 import android.net.DnsResolverServiceManager; 204 import android.net.DscpPolicy; 205 import android.net.ICaptivePortal; 206 import android.net.IConnectivityDiagnosticsCallback; 207 import android.net.IConnectivityManager; 208 import android.net.IDnsResolver; 209 import android.net.IIntResultListener; 210 import android.net.INetd; 211 import android.net.INetworkActivityListener; 212 import android.net.INetworkAgent; 213 import android.net.INetworkMonitor; 214 import android.net.INetworkMonitorCallbacks; 215 import android.net.INetworkOfferCallback; 216 import android.net.IOnCompleteListener; 217 import android.net.IQosCallback; 218 import android.net.ISocketKeepaliveCallback; 219 import android.net.InetAddresses; 220 import android.net.IpMemoryStore; 221 import android.net.IpPrefix; 222 import android.net.LinkAddress; 223 import android.net.LinkProperties; 224 import android.net.LocalNetworkConfig; 225 import android.net.LocalNetworkInfo; 226 import android.net.MatchAllNetworkSpecifier; 227 import android.net.MulticastRoutingConfig; 228 import android.net.NativeNetworkConfig; 229 import android.net.NativeNetworkType; 230 import android.net.NattSocketKeepalive; 231 import android.net.Network; 232 import android.net.NetworkAgent; 233 import android.net.NetworkAgentConfig; 234 import android.net.NetworkAndAgentRegistryParcelable; 235 import android.net.NetworkCapabilities; 236 import android.net.NetworkInfo; 237 import android.net.NetworkInfo.DetailedState; 238 import android.net.NetworkMonitorManager; 239 import android.net.NetworkPolicyManager; 240 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 241 import android.net.NetworkProvider; 242 import android.net.NetworkRequest; 243 import android.net.NetworkScore; 244 import android.net.NetworkSpecifier; 245 import android.net.NetworkStack; 246 import android.net.NetworkState; 247 import android.net.NetworkStateSnapshot; 248 import android.net.NetworkTestResultParcelable; 249 import android.net.NetworkUtils; 250 import android.net.NetworkWatchlistManager; 251 import android.net.OemNetworkPreferences; 252 import android.net.PrivateDnsConfigParcel; 253 import android.net.ProfileNetworkPreference; 254 import android.net.ProxyInfo; 255 import android.net.QosCallbackException; 256 import android.net.QosFilter; 257 import android.net.QosSocketFilter; 258 import android.net.QosSocketInfo; 259 import android.net.RouteInfo; 260 import android.net.SocketKeepalive; 261 import android.net.TetheringManager; 262 import android.net.TransportInfo; 263 import android.net.UidRange; 264 import android.net.UidRangeParcel; 265 import android.net.UnderlyingNetworkInfo; 266 import android.net.Uri; 267 import android.net.VpnManager; 268 import android.net.VpnTransportInfo; 269 import android.net.metrics.IpConnectivityLog; 270 import android.net.metrics.NetworkEvent; 271 import android.net.netd.aidl.NativeUidRangeConfig; 272 import android.net.networkstack.ModuleNetworkStackClient; 273 import android.net.networkstack.NetworkStackClientBase; 274 import android.net.networkstack.aidl.NetworkMonitorParameters; 275 import android.net.resolv.aidl.DnsHealthEventParcel; 276 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; 277 import android.net.resolv.aidl.Nat64PrefixEventParcel; 278 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 279 import android.net.shared.PrivateDnsConfig; 280 import android.net.wifi.WifiInfo; 281 import android.os.BatteryStatsManager; 282 import android.os.Binder; 283 import android.os.Build; 284 import android.os.Bundle; 285 import android.os.ConditionVariable; 286 import android.os.Handler; 287 import android.os.HandlerThread; 288 import android.os.IBinder; 289 import android.os.Looper; 290 import android.os.Message; 291 import android.os.Messenger; 292 import android.os.ParcelFileDescriptor; 293 import android.os.Parcelable; 294 import android.os.PersistableBundle; 295 import android.os.PowerManager; 296 import android.os.Process; 297 import android.os.RemoteCallbackList; 298 import android.os.RemoteException; 299 import android.os.ServiceSpecificException; 300 import android.os.SystemClock; 301 import android.os.SystemProperties; 302 import android.os.UserHandle; 303 import android.os.UserManager; 304 import android.provider.Settings; 305 import android.stats.connectivity.MeteredState; 306 import android.stats.connectivity.RequestType; 307 import android.stats.connectivity.ValidatedState; 308 import android.sysprop.NetworkProperties; 309 import android.system.ErrnoException; 310 import android.telephony.SubscriptionManager; 311 import android.telephony.TelephonyManager; 312 import android.text.TextUtils; 313 import android.util.ArrayMap; 314 import android.util.ArraySet; 315 import android.util.LocalLog; 316 import android.util.Log; 317 import android.util.Pair; 318 import android.util.Range; 319 import android.util.SparseArray; 320 import android.util.SparseIntArray; 321 import android.util.StatsEvent; 322 323 import com.android.connectivity.resources.R; 324 import com.android.internal.annotations.GuardedBy; 325 import com.android.internal.annotations.VisibleForTesting; 326 import com.android.internal.util.IndentingPrintWriter; 327 import com.android.internal.util.MessageUtils; 328 import com.android.metrics.ConnectionDurationForTransports; 329 import com.android.metrics.ConnectionDurationPerTransports; 330 import com.android.metrics.ConnectivitySampleMetricsHelper; 331 import com.android.metrics.ConnectivityStateSample; 332 import com.android.metrics.NetworkCountForTransports; 333 import com.android.metrics.NetworkCountPerTransports; 334 import com.android.metrics.NetworkDescription; 335 import com.android.metrics.NetworkList; 336 import com.android.metrics.NetworkRequestCount; 337 import com.android.metrics.RequestCountForType; 338 import com.android.modules.utils.BasicShellCommandHandler; 339 import com.android.modules.utils.build.SdkLevel; 340 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 341 import com.android.net.module.util.BinderUtils; 342 import com.android.net.module.util.BitUtils; 343 import com.android.net.module.util.BpfUtils; 344 import com.android.net.module.util.CollectionUtils; 345 import com.android.net.module.util.DeviceConfigUtils; 346 import com.android.net.module.util.HandlerUtils; 347 import com.android.net.module.util.InterfaceParams; 348 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; 349 import com.android.net.module.util.LinkPropertiesUtils.CompareResult; 350 import com.android.net.module.util.LocationPermissionChecker; 351 import com.android.net.module.util.PerUidCounter; 352 import com.android.net.module.util.PermissionUtils; 353 import com.android.net.module.util.RoutingCoordinatorService; 354 import com.android.net.module.util.TcUtils; 355 import com.android.net.module.util.netlink.InetDiagMessage; 356 import com.android.networkstack.apishim.BroadcastOptionsShimImpl; 357 import com.android.networkstack.apishim.ConstantsShim; 358 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 359 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 360 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 361 import com.android.server.connectivity.AutodestructReference; 362 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 363 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive; 364 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 365 import com.android.server.connectivity.ClatCoordinator; 366 import com.android.server.connectivity.ConnectivityFlags; 367 import com.android.server.connectivity.ConnectivityResources; 368 import com.android.server.connectivity.DnsManager; 369 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; 370 import com.android.server.connectivity.DscpPolicyTracker; 371 import com.android.server.connectivity.FullScore; 372 import com.android.server.connectivity.InterfaceTracker; 373 import com.android.server.connectivity.InvalidTagException; 374 import com.android.server.connectivity.KeepaliveResourceUtil; 375 import com.android.server.connectivity.KeepaliveTracker; 376 import com.android.server.connectivity.LingerMonitor; 377 import com.android.server.connectivity.MockableSystemProperties; 378 import com.android.server.connectivity.MulticastRoutingCoordinatorService; 379 import com.android.server.connectivity.MultinetworkPolicyTracker; 380 import com.android.server.connectivity.NetworkAgentInfo; 381 import com.android.server.connectivity.NetworkDiagnostics; 382 import com.android.server.connectivity.NetworkNotificationManager; 383 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 384 import com.android.server.connectivity.NetworkOffer; 385 import com.android.server.connectivity.NetworkPreferenceList; 386 import com.android.server.connectivity.NetworkRanker; 387 import com.android.server.connectivity.NetworkRequestStateStatsMetrics; 388 import com.android.server.connectivity.PermissionMonitor; 389 import com.android.server.connectivity.ProfileNetworkPreferenceInfo; 390 import com.android.server.connectivity.ProxyTracker; 391 import com.android.server.connectivity.QosCallbackTracker; 392 import com.android.server.connectivity.SatelliteAccessController; 393 import com.android.server.connectivity.UidRangeUtils; 394 import com.android.server.connectivity.VpnNetworkPreferenceInfo; 395 import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService; 396 397 import libcore.io.IoUtils; 398 399 import org.xmlpull.v1.XmlPullParserException; 400 401 import java.io.FileDescriptor; 402 import java.io.IOException; 403 import java.io.InterruptedIOException; 404 import java.io.PrintWriter; 405 import java.io.Writer; 406 import java.net.Inet4Address; 407 import java.net.InetAddress; 408 import java.net.InetSocketAddress; 409 import java.net.SocketException; 410 import java.net.UnknownHostException; 411 import java.util.ArrayList; 412 import java.util.Arrays; 413 import java.util.Collection; 414 import java.util.Collections; 415 import java.util.Comparator; 416 import java.util.ConcurrentModificationException; 417 import java.util.HashMap; 418 import java.util.HashSet; 419 import java.util.List; 420 import java.util.Map; 421 import java.util.Map.Entry; 422 import java.util.NoSuchElementException; 423 import java.util.Objects; 424 import java.util.Set; 425 import java.util.SortedSet; 426 import java.util.StringJoiner; 427 import java.util.TreeSet; 428 import java.util.concurrent.CopyOnWriteArraySet; 429 import java.util.concurrent.TimeUnit; 430 import java.util.concurrent.atomic.AtomicInteger; 431 import java.util.concurrent.atomic.AtomicReference; 432 import java.util.function.BiConsumer; 433 import java.util.function.Consumer; 434 import java.util.function.Predicate; 435 436 /** 437 * @hide 438 */ 439 public class ConnectivityService extends IConnectivityManager.Stub { 440 private static final String TAG = ConnectivityService.class.getSimpleName(); 441 442 private static final String DIAG_ARG = "--diag"; 443 public static final String SHORT_ARG = "--short"; 444 private static final String NETWORK_ARG = "networks"; 445 private static final String REQUEST_ARG = "requests"; 446 private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller"; 447 public static final String CLATEGRESS4RAWBPFMAP_ARG = "clatEgress4RawBpfMap"; 448 public static final String CLATINGRESS6RAWBPFMAP_ARG = "clatIngress6RawBpfMap"; 449 450 private static final boolean DBG = true; 451 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); 452 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 453 454 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 455 456 /** 457 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed 458 * by OEMs for configuration purposes, as this value is overridden by 459 * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL. 460 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose 461 * (preferably via runtime resource overlays). 462 */ 463 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL = 464 "http://connectivitycheck.gstatic.com/generate_204"; 465 466 // TODO: create better separation between radio types and network types 467 468 // how long to wait before switching back to a radio's default network 469 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 470 // system property that can override the above value 471 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 472 "android.telephony.apn-restore"; 473 474 // How long to wait before putting up a "This network doesn't have an Internet connection, 475 // connect anyway?" dialog after the user selects a network that doesn't validate. 476 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 477 478 // How long to wait before considering that a network is bad in the absence of any form 479 // of connectivity (valid, partial, captive portal). If none has been detected after this 480 // delay, the stack considers this network bad, which may affect how it's handled in ranking 481 // according to config_networkAvoidBadWifi. 482 // Timeout in case the "actively prefer bad wifi" feature is on 483 private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000; 484 // Timeout in case the "actively prefer bad wifi" feature is off 485 private static final int DEFAULT_EVALUATION_TIMEOUT_MS = 8 * 1000; 486 487 // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing. 488 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 489 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 490 private static final int DEFAULT_NASCENT_DELAY_MS = 5_000; 491 492 // Delimiter used when creating the broadcast delivery group for sending 493 // CONNECTIVITY_ACTION broadcast. 494 private static final char DELIVERY_GROUP_KEY_DELIMITER = ';'; 495 496 // The maximum value for the blocking validation result, in milliseconds. 497 public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000; 498 499 // The maximum number of network request allowed per uid before an exception is thrown. 500 @VisibleForTesting 501 static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 502 503 // The maximum number of network request allowed for system UIDs before an exception is thrown. 504 @VisibleForTesting 505 static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250; 506 507 @VisibleForTesting 508 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 509 @VisibleForTesting 510 protected int mNascentDelayMs; 511 // True if the cell radio of the device is capable of time-sharing. 512 @VisibleForTesting 513 protected boolean mCellularRadioTimesharingCapable = true; 514 515 // How long to delay to removal of a pending intent based request. 516 // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 517 private final int mReleasePendingIntentDelayMs; 518 519 private final MockableSystemProperties mSystemProperties; 520 521 private final PermissionMonitor mPermissionMonitor; 522 523 @VisibleForTesting 524 final RequestInfoPerUidCounter mNetworkRequestCounter; 525 @VisibleForTesting 526 final RequestInfoPerUidCounter mSystemNetworkRequestCounter; 527 528 private volatile boolean mLockdownEnabled; 529 530 private final boolean mRequestRestrictedWifiEnabled; 531 private final boolean mBackgroundFirewallChainEnabled; 532 533 private final boolean mUseDeclaredMethodsForCallbacksEnabled; 534 private final boolean mQueueNetworkAgentEventsInSystemServer; 535 536 // Flag to delay callbacks for frozen apps, suppressing duplicate and stale callbacks. 537 private final boolean mQueueCallbacksForFrozenApps; 538 539 /** 540 * Uids ConnectivityService tracks blocked status of to send blocked status callbacks. 541 * Key is uid based on mAsUid of registered networkRequestInfo 542 * Value is count of registered networkRequestInfo 543 * 544 * This is necessary because when a firewall chain is enabled or disabled, that affects all UIDs 545 * on the system, not just UIDs on that firewall chain. For example, entering doze mode affects 546 * all UIDs that are not on the dozable chain. ConnectivityService doesn't know which UIDs are 547 * running. But it only needs to send onBlockedStatusChanged to UIDs that have at least one 548 * NetworkCallback registered. 549 * 550 * UIDs are added to this list on the binder thread when processing requestNetwork and similar 551 * IPCs. They are removed from this list on the handler thread, when the callback unregistration 552 * is fully processed. They cannot be unregistered when the unregister IPC is processed because 553 * sometimes requests are unregistered on the handler thread. 554 */ 555 @GuardedBy("mBlockedStatusTrackingUids") 556 private final SparseIntArray mBlockedStatusTrackingUids = new SparseIntArray(); 557 558 /** 559 * Stale copy of UID blocked reasons. This is used to send onBlockedStatusChanged 560 * callbacks. This is only used on the handler thread, so it does not require a lock. 561 * On U-, the blocked reasons come from NPMS. 562 * On V+, the blocked reasons come from the BPF map contents and only maintains blocked reasons 563 * of uids that register network callbacks. 564 */ 565 private final SparseIntArray mUidBlockedReasons = new SparseIntArray(); 566 567 private final Context mContext; 568 private final ConnectivityResources mResources; 569 private final int mWakeUpMark; 570 private final int mWakeUpMask; 571 // The Context is created for UserHandle.ALL. 572 private final Context mUserAllContext; 573 private final Dependencies mDeps; 574 private final PermissionMonitor.Dependencies mPermissionMonitorDeps; 575 private final ConnectivityFlags mFlags; 576 // 0 is full bad, 100 is full good 577 private int mDefaultInetConditionPublished = 0; 578 579 @VisibleForTesting 580 protected IDnsResolver mDnsResolver; 581 @VisibleForTesting 582 protected INetd mNetd; 583 private DscpPolicyTracker mDscpPolicyTracker = null; 584 private final NetworkStatsManager mStatsManager; 585 private final NetworkPolicyManager mPolicyManager; 586 private final BpfNetMaps mBpfNetMaps; 587 private final InterfaceTracker mInterfaceTracker; 588 589 /** 590 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple 591 * instances. 592 */ 593 @GuardedBy("mTNSLock") 594 private TestNetworkService mTNS; 595 private final CompanionDeviceManagerProxyService mCdmps; 596 private final MulticastRoutingCoordinatorService mMulticastRoutingCoordinatorService; 597 private final RoutingCoordinatorService mRoutingCoordinatorService; 598 599 private final Object mTNSLock = new Object(); 600 601 private String mCurrentTcpBufferSizes; 602 603 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 604 new Class[] { 605 ConnectivityService.class, 606 NetworkAgent.class, 607 NetworkAgentInfo.class, 608 AutomaticOnOffKeepaliveTracker.class }); 609 610 private enum ReapUnvalidatedNetworks { 611 // Tear down networks that have no chance (e.g. even if validated) of becoming 612 // the highest scoring network satisfying a NetworkRequest. This should be passed when 613 // all networks have been rematched against all NetworkRequests. 614 REAP, 615 // Don't reap networks. This should be passed when some networks have not yet been 616 // rematched against all NetworkRequests. 617 DONT_REAP 618 } 619 620 private enum UnneededFor { 621 LINGER, // Determine whether this network is unneeded and should be lingered. 622 TEARDOWN, // Determine whether this network is unneeded and should be torn down. 623 } 624 625 /** 626 * For per-app preferences, requests contain an int to signify which request 627 * should have priority. The order is passed to netd which will use it together 628 * with UID ranges to generate the corresponding IP rule. This serves to 629 * direct device-originated data traffic of the specific UIDs to the correct 630 * default network for each app. 631 * Order ints passed to netd must be in the 0~999 range. Larger values code for 632 * a lower priority, see {@link NativeUidRangeConfig}. 633 * Note that only the highest priority preference is applied if the uid is the target of 634 * multiple preferences. 635 * 636 * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID. 637 * The default request uses PREFERENCE_ORDER_DEFAULT. 638 */ 639 // Used when sending to netd to code for "no order". 640 static final int PREFERENCE_ORDER_NONE = 0; 641 // Order for requests that don't code for a per-app preference. As it is 642 // out of the valid range, the corresponding order should be 643 // PREFERENCE_ORDER_NONE when sending to netd. 644 @VisibleForTesting 645 static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE; 646 // As a security feature, VPNs have the top priority. 647 static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN. 648 // Order of per-app OEM preference. See {@link #setOemNetworkPreference}. 649 @VisibleForTesting 650 static final int PREFERENCE_ORDER_OEM = 10; 651 // Order of per-profile preference, such as used by enterprise networks. 652 // See {@link #setProfileNetworkPreference}. 653 @VisibleForTesting 654 static final int PREFERENCE_ORDER_PROFILE = 20; 655 // Order of user setting to prefer mobile data even when networks with 656 // better scores are connected. 657 // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids} 658 @VisibleForTesting 659 static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30; 660 // Order of setting satellite network preference fallback when default message application 661 // with role_sms role and android.permission.SATELLITE_COMMUNICATION permission detected 662 @VisibleForTesting 663 static final int PREFERENCE_ORDER_SATELLITE_FALLBACK = 40; 664 // Preference order that signifies the network shouldn't be set as a default network for 665 // the UIDs, only give them access to it. TODO : replace this with a boolean 666 // in NativeUidRangeConfig 667 @VisibleForTesting 668 static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999; 669 // Bound for the lowest valid preference order. 670 static final int PREFERENCE_ORDER_LOWEST = 999; 671 672 /** 673 * used internally to clear a wakelock when transitioning 674 * from one net to another. Clear happens when we get a new 675 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 676 * after a timeout if no network is found (typically 1 min). 677 */ 678 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 679 680 /** 681 * used internally to reload global proxy settings 682 */ 683 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 684 685 /** 686 * PAC manager has received new port. 687 */ 688 private static final int EVENT_PAC_PROXY_HAS_CHANGED = 16; 689 690 /** 691 * used internally when registering NetworkProviders 692 * obj = NetworkProviderInfo 693 */ 694 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; 695 696 /** 697 * used internally when registering NetworkAgents 698 * obj = Messenger 699 */ 700 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 701 702 /** 703 * used to add a network request 704 * includes a NetworkRequestInfo 705 */ 706 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 707 708 /** 709 * indicates a timeout period is over - check if we had a network yet or not 710 * and if not, call the timeout callback (but leave the request live until they 711 * cancel it. 712 * includes a NetworkRequestInfo 713 */ 714 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 715 716 /** 717 * used to add a network listener - no request 718 * includes a NetworkRequestInfo 719 */ 720 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 721 722 /** 723 * used to remove a network request, either a listener or a real request 724 * arg1 = UID of caller 725 * obj = NetworkRequest 726 */ 727 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 728 729 /** 730 * used internally when registering NetworkProviders 731 * obj = Messenger 732 */ 733 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; 734 735 /** 736 * used internally to expire a wakelock when transitioning 737 * from one net to another. Expire happens when we fail to find 738 * a new network (typically after 1 minute) - 739 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 740 * a replacement network. 741 */ 742 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 743 744 /** 745 * used to add a network request with a pending intent 746 * obj = NetworkRequestInfo 747 */ 748 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 749 750 /** 751 * used to remove a pending intent and its associated network request. 752 * arg1 = UID of caller 753 * obj = PendingIntent 754 */ 755 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 756 757 /** 758 * used to specify whether a network should be used even if unvalidated. 759 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 760 * arg2 = whether to remember this choice in the future (1 or 0) 761 * obj = network 762 */ 763 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 764 765 /** 766 * used internally to (re)configure always-on networks. 767 */ 768 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; 769 770 /** 771 * used to add a network listener with a pending intent 772 * obj = NetworkRequestInfo 773 */ 774 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 775 776 /** 777 * used to specify whether a network should not be penalized when it becomes unvalidated. 778 */ 779 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 780 781 /** 782 * used to handle reported network connectivity. May trigger revalidation of a network. 783 */ 784 private static final int EVENT_REPORT_NETWORK_CONNECTIVITY = 36; 785 786 // Handle changes in Private DNS settings. 787 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; 788 789 // Handle private DNS validation status updates. 790 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; 791 792 /** 793 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has 794 * been tested. 795 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor. 796 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link 797 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null. 798 */ 799 private static final int EVENT_NETWORK_TESTED = 41; 800 801 /** 802 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS 803 * config was resolved. 804 * obj = PrivateDnsConfig 805 * arg2 = netid 806 */ 807 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; 808 809 /** 810 * Request ConnectivityService display provisioning notification. 811 * arg1 = Whether to make the notification visible. 812 * arg2 = NetID. 813 * obj = Intent to be launched when notification selected by user, null if !arg1. 814 */ 815 private static final int EVENT_PROVISIONING_NOTIFICATION = 43; 816 817 /** 818 * Used to specify whether a network should be used even if connectivity is partial. 819 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for 820 * false) 821 * arg2 = whether to remember this choice in the future (1 for true or 0 for false) 822 * obj = network 823 */ 824 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44; 825 826 /** 827 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed. 828 * Both of the arguments are bitmasks, and the value of bits come from 829 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*. 830 * arg1 = unused 831 * arg2 = netId 832 * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes. 833 */ 834 public static final int EVENT_PROBE_STATUS_CHANGED = 45; 835 836 /** 837 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed. 838 * arg1 = unused 839 * arg2 = netId 840 * obj = captive portal data 841 */ 842 private static final int EVENT_CAPPORT_DATA_CHANGED = 46; 843 844 /** 845 * Used by setRequireVpnForUids. 846 * arg1 = whether the specified UID ranges are required to use a VPN. 847 * obj = Array of UidRange objects. 848 */ 849 private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47; 850 851 /** 852 * Used internally when setting the default networks for OemNetworkPreferences. 853 * obj = Pair<OemNetworkPreferences, listener> 854 */ 855 private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48; 856 857 /** 858 * Used to indicate the system default network becomes active. 859 */ 860 private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49; 861 862 /** 863 * Used internally when setting a network preference for a user profile. 864 * obj = Pair<ProfileNetworkPreference, Listener> 865 */ 866 private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50; 867 868 /** 869 * Event to update blocked reasons for uids. 870 * obj = List of Pair(uid, blockedReasons) 871 */ 872 private static final int EVENT_BLOCKED_REASONS_CHANGED = 51; 873 874 /** 875 * Event to register a new network offer 876 * obj = NetworkOffer 877 */ 878 private static final int EVENT_REGISTER_NETWORK_OFFER = 52; 879 880 /** 881 * Event to unregister an existing network offer 882 * obj = INetworkOfferCallback 883 */ 884 private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53; 885 886 /** 887 * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed. 888 */ 889 private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54; 890 891 /** 892 * Event to set temporary allow bad wifi within a limited time to override 893 * {@code config_networkAvoidBadWifi}. 894 */ 895 private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55; 896 897 /** 898 * Used internally when INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting changes. 899 */ 900 private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56; 901 902 /** 903 * The initial evaluation period is over for this network. 904 * 905 * If no form of connectivity has been found on this network (valid, partial, captive portal) 906 * then the stack will now consider it to have been determined bad. 907 */ 908 private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57; 909 910 /** 911 * Used internally when the user does not want the network from captive portal app. 912 * obj = Network 913 */ 914 private static final int EVENT_USER_DOES_NOT_WANT = 58; 915 916 /** 917 * Event to set VPN as preferred network for specific apps. 918 * obj = VpnNetworkPreferenceInfo 919 */ 920 private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59; 921 922 /** 923 * Event to use low TCP polling timer used in automatic on/off keepalive temporarily. 924 */ 925 private static final int EVENT_SET_LOW_TCP_POLLING_UNTIL = 60; 926 927 /** 928 * Event to inform the ConnectivityService handler when a uid has been frozen or unfrozen. 929 */ 930 private static final int EVENT_UID_FROZEN_STATE_CHANGED = 61; 931 932 /** 933 * Event to update firewall socket destroy reasons for uids. 934 * obj = List of Pair(uid, socketDestroyReasons) 935 */ 936 private static final int EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS = 62; 937 938 /** 939 * Event to clear firewall socket destroy reasons for all uids. 940 * arg1 = socketDestroyReason 941 */ 942 private static final int EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS = 63; 943 944 /** 945 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 946 * should be shown. 947 */ 948 private static final int PROVISIONING_NOTIFICATION_SHOW = 1; 949 950 /** 951 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 952 * should be hidden. 953 */ 954 private static final int PROVISIONING_NOTIFICATION_HIDE = 0; 955 956 /** 957 * The maximum alive time to allow bad wifi configuration for testing. 958 */ 959 private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L; 960 961 /** 962 * The maximum alive time to decrease TCP polling timer in automatic on/off keepalive for 963 * testing. 964 */ 965 private static final long MAX_TEST_LOW_TCP_POLLING_UNTIL_MS = 5 * 60 * 1000L; 966 967 /** 968 * The priority of the tc police rate limiter -- smaller value is higher priority. 969 * This value needs to be coordinated with PRIO_CLAT, PRIO_TETHER4, and PRIO_TETHER6. 970 */ 971 private static final short TC_PRIO_POLICE = 1; 972 973 /** 974 * The BPF program attached to the tc-police hook to account for to-be-dropped traffic. 975 */ 976 private static final String TC_POLICE_BPF_PROG_PATH = 977 "/sys/fs/bpf/netd_shared/prog_netd_schedact_ingress_account"; 978 eventName(int what)979 private static String eventName(int what) { 980 return sMagicDecoderRing.get(what, Integer.toString(what)); 981 } 982 getDnsResolver(Context context)983 private static IDnsResolver getDnsResolver(Context context) { 984 final DnsResolverServiceManager dsm = context.getSystemService( 985 DnsResolverServiceManager.class); 986 return IDnsResolver.Stub.asInterface(dsm.getService()); 987 } 988 989 /** Handler thread used for all of the handlers below. */ 990 @VisibleForTesting 991 protected final HandlerThread mHandlerThread; 992 /** Handler used for internal events. */ 993 final private InternalHandler mHandler; 994 /** Handler used for incoming {@link NetworkStateTracker} events. */ 995 final private NetworkStateTrackerHandler mTrackerHandler; 996 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */ 997 @VisibleForTesting 998 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler; 999 1000 private final DnsManager mDnsManager; 1001 @VisibleForTesting 1002 final NetworkRanker mNetworkRanker; 1003 1004 private boolean mSystemReady; 1005 private Intent mInitialBroadcast; 1006 1007 private final PowerManager.WakeLock mNetTransitionWakeLock; 1008 private final PowerManager.WakeLock mPendingIntentWakeLock; 1009 1010 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell 1011 // the world when it changes. 1012 private final ProxyTracker mProxyTracker; 1013 1014 final private SettingsObserver mSettingsObserver; 1015 1016 private final UserManager mUserManager; 1017 1018 // the set of network types that can only be enabled by system/sig apps 1019 private final List<Integer> mProtectedNetworks; 1020 1021 private Set<String> mWolSupportedInterfaces; 1022 1023 private final TelephonyManager mTelephonyManager; 1024 private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 1025 private final AppOpsManager mAppOpsManager; 1026 1027 private final LocationPermissionChecker mLocationPermissionChecker; 1028 1029 private final AutomaticOnOffKeepaliveTracker mKeepaliveTracker; 1030 private final QosCallbackTracker mQosCallbackTracker; 1031 private final NetworkNotificationManager mNotifier; 1032 private final LingerMonitor mLingerMonitor; 1033 private final SatelliteAccessController mSatelliteAccessController; 1034 1035 private final L2capNetworkProvider mL2capNetworkProvider; 1036 1037 // sequence number of NetworkRequests 1038 private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID; 1039 1040 // Sequence number for NetworkProvider IDs. 1041 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( 1042 NetworkProvider.FIRST_PROVIDER_ID); 1043 1044 // NetworkRequest activity String log entries. 1045 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 1046 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 1047 1048 // NetworkInfo blocked and unblocked String log entries 1049 private static final int MAX_NETWORK_INFO_LOGS = 40; 1050 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 1051 1052 private static final int MAX_WAKELOCK_LOGS = 20; 1053 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS); 1054 private int mTotalWakelockAcquisitions = 0; 1055 private int mTotalWakelockReleases = 0; 1056 private long mTotalWakelockDurationMs = 0; 1057 private long mMaxWakelockDurationMs = 0; 1058 private long mLastWakeLockAcquireTimestamp = 0; 1059 1060 private final IpConnectivityLog mMetricsLog; 1061 1062 @Nullable private final NetworkRequestStateStatsMetrics mNetworkRequestStateStatsMetrics; 1063 1064 @GuardedBy("mBandwidthRequests") 1065 private final SparseArray<Integer> mBandwidthRequests = new SparseArray<>(10); 1066 1067 @VisibleForTesting 1068 final MultinetworkPolicyTracker mMultinetworkPolicyTracker; 1069 1070 @VisibleForTesting 1071 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks = 1072 new HashMap<>(); 1073 1074 // Rate limit applicable to all internet capable networks (-1 = disabled). This value is 1075 // configured via {@link 1076 // ConnectivitySettingsManager#INGRESS_RATE_LIMIT_BYTES_PER_SECOND} 1077 // Only the handler thread is allowed to access this field. 1078 private long mIngressRateLimit = -1; 1079 1080 // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This 1081 // value can be accessed from both handler thread and any random binder thread. Therefore, 1082 // accessing this value requires holding a lock. The cache is the same across all the users. 1083 @GuardedBy("mSelfCertifiedCapabilityCache") 1084 private final Map<String, ApplicationSelfCertifiedNetworkCapabilities> 1085 mSelfCertifiedCapabilityCache = new HashMap<>(); 1086 1087 // Flag to enable the feature of closing frozen app sockets. 1088 private final boolean mDestroyFrozenSockets; 1089 1090 // Flag to optimize closing app sockets by waiting for the cellular modem to wake up. 1091 private final boolean mDelayDestroySockets; 1092 1093 // Flag to allow SysUI to receive connectivity reports for wifi picker UI. 1094 private final boolean mAllowSysUiConnectivityReports; 1095 1096 // Uids that ConnectivityService is pending to close sockets of. 1097 // Key is uid and value is reasons of socket destroy 1098 private final SparseIntArray mDestroySocketPendingUids = new SparseIntArray(); 1099 1100 private static final int DESTROY_SOCKET_REASON_NONE = 0; 1101 private static final int DESTROY_SOCKET_REASON_FROZEN = 1 << 0; 1102 private static final int DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND = 1 << 1; 1103 1104 // Flag to drop packets to VPN addresses ingressing via non-VPN interfaces. 1105 private final boolean mIngressToVpnAddressFiltering; 1106 1107 /** 1108 * Implements support for the legacy "one network per network type" model. 1109 * 1110 * We used to have a static array of NetworkStateTrackers, one for each 1111 * network type, but that doesn't work any more now that we can have, 1112 * for example, more that one wifi network. This class stores all the 1113 * NetworkAgentInfo objects that support a given type, but the legacy 1114 * API will only see the first one. 1115 * 1116 * It serves two main purposes: 1117 * 1118 * 1. Provide information about "the network for a given type" (since this 1119 * API only supports one). 1120 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 1121 * the first network for a given type changes, or if the default network 1122 * changes. 1123 */ 1124 @VisibleForTesting 1125 static class LegacyTypeTracker { 1126 1127 private static final boolean DBG = true; 1128 private static final boolean VDBG = false; 1129 1130 /** 1131 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 1132 * Each list holds references to all NetworkAgentInfos that are used to 1133 * satisfy requests for that network type. 1134 * 1135 * This array is built out at startup such that an unsupported network 1136 * doesn't get an ArrayList instance, making this a tristate: 1137 * unsupported, supported but not active and active. 1138 * 1139 * The actual lists are populated when we scan the network types that 1140 * are supported on this device. 1141 * 1142 * Threading model: 1143 * - addSupportedType() is only called in the constructor 1144 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 1145 * They are therefore not thread-safe with respect to each other. 1146 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 1147 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 1148 * - getRestoreTimerForType(type) is also synchronized on mTypeLists. 1149 * - dump is thread-safe with respect to concurrent add and remove calls. 1150 */ 1151 private final ArrayList<NetworkAgentInfo>[] mTypeLists; 1152 @NonNull 1153 private final ConnectivityService mService; 1154 1155 // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without 1156 // an entry have no timer (equivalent to -1). Lazily loaded. 1157 @NonNull 1158 private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>(); 1159 LegacyTypeTracker(@onNull ConnectivityService service)1160 LegacyTypeTracker(@NonNull ConnectivityService service) { 1161 mService = service; 1162 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 1163 } 1164 1165 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is 1166 // addressed. 1167 @TargetApi(Build.VERSION_CODES.S) loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)1168 public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) { 1169 final PackageManager pm = ctx.getPackageManager(); 1170 if (pm.hasSystemFeature(FEATURE_WIFI)) { 1171 addSupportedType(TYPE_WIFI); 1172 } 1173 if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) { 1174 addSupportedType(TYPE_WIFI_P2P); 1175 } 1176 if (tm.isDataCapable()) { 1177 // Telephony does not have granular support for these types: they are either all 1178 // supported, or none is supported 1179 addSupportedType(TYPE_MOBILE); 1180 addSupportedType(TYPE_MOBILE_MMS); 1181 addSupportedType(TYPE_MOBILE_SUPL); 1182 addSupportedType(TYPE_MOBILE_DUN); 1183 addSupportedType(TYPE_MOBILE_HIPRI); 1184 addSupportedType(TYPE_MOBILE_FOTA); 1185 addSupportedType(TYPE_MOBILE_IMS); 1186 addSupportedType(TYPE_MOBILE_CBS); 1187 addSupportedType(TYPE_MOBILE_IA); 1188 addSupportedType(TYPE_MOBILE_EMERGENCY); 1189 } 1190 if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) { 1191 addSupportedType(TYPE_BLUETOOTH); 1192 } 1193 if (pm.hasSystemFeature(FEATURE_WATCH)) { 1194 // TYPE_PROXY is only used on Wear 1195 addSupportedType(TYPE_PROXY); 1196 } 1197 // Ethernet is often not specified in the configs, although many devices can use it via 1198 // USB host adapters. Add it as long as the ethernet service is here. 1199 if (deviceSupportsEthernet(ctx)) { 1200 addSupportedType(TYPE_ETHERNET); 1201 } 1202 1203 // Always add TYPE_VPN as a supported type 1204 addSupportedType(TYPE_VPN); 1205 } 1206 addSupportedType(int type)1207 private void addSupportedType(int type) { 1208 if (mTypeLists[type] != null) { 1209 throw new IllegalStateException( 1210 "legacy list for type " + type + "already initialized"); 1211 } 1212 mTypeLists[type] = new ArrayList<>(); 1213 } 1214 isTypeSupported(int type)1215 public boolean isTypeSupported(int type) { 1216 return isNetworkTypeValid(type) && mTypeLists[type] != null; 1217 } 1218 getNetworkForType(int type)1219 public NetworkAgentInfo getNetworkForType(int type) { 1220 synchronized (mTypeLists) { 1221 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 1222 return mTypeLists[type].get(0); 1223 } 1224 } 1225 return null; 1226 } 1227 getRestoreTimerForType(int type)1228 public int getRestoreTimerForType(int type) { 1229 synchronized (mTypeLists) { 1230 if (mRestoreTimers == null) { 1231 mRestoreTimers = loadRestoreTimers(); 1232 } 1233 return mRestoreTimers.getOrDefault(type, -1); 1234 } 1235 } 1236 loadRestoreTimers()1237 private ArrayMap<Integer, Integer> loadRestoreTimers() { 1238 final String[] configs = mService.mResources.get().getStringArray( 1239 R.array.config_legacy_networktype_restore_timers); 1240 final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length); 1241 for (final String config : configs) { 1242 final String[] splits = TextUtils.split(config, ","); 1243 if (splits.length != 2) { 1244 logwtf("Invalid restore timer token count: " + config); 1245 continue; 1246 } 1247 try { 1248 ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1])); 1249 } catch (NumberFormatException e) { 1250 logwtf("Invalid restore timer number format: " + config, e); 1251 } 1252 } 1253 return ret; 1254 } 1255 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)1256 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 1257 boolean isDefaultNetwork) { 1258 if (DBG) { 1259 log("Sending " + state 1260 + " broadcast for type " + type + " " + nai.toShortString() 1261 + " isDefaultNetwork=" + isDefaultNetwork); 1262 } 1263 } 1264 1265 // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying 1266 // network type, to preserve previous behaviour. maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)1267 private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) { 1268 if (vpnNai != mService.getLegacyLockdownNai()) return; 1269 1270 if (vpnNai.declaredUnderlyingNetworks == null 1271 || vpnNai.declaredUnderlyingNetworks.length != 1) { 1272 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: " 1273 + Arrays.toString(vpnNai.declaredUnderlyingNetworks)); 1274 return; 1275 } 1276 final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork( 1277 vpnNai.declaredUnderlyingNetworks[0]); 1278 if (underlyingNai == null) return; 1279 1280 final int type = underlyingNai.networkInfo.getType(); 1281 final DetailedState state = DetailedState.CONNECTED; 1282 maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */); 1283 mService.sendLegacyNetworkBroadcast(underlyingNai, state, type); 1284 } 1285 1286 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)1287 public void add(int type, NetworkAgentInfo nai) { 1288 if (!isTypeSupported(type)) { 1289 return; // Invalid network type. 1290 } 1291 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 1292 1293 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1294 if (list.contains(nai)) { 1295 return; 1296 } 1297 synchronized (mTypeLists) { 1298 list.add(nai); 1299 } 1300 1301 // Send a broadcast if this is the first network of its type or if it's the default. 1302 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); 1303 1304 // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts 1305 // to preserve previous behaviour. 1306 final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED); 1307 if ((list.size() == 1) || isDefaultNetwork) { 1308 maybeLogBroadcast(nai, state, type, isDefaultNetwork); 1309 mService.sendLegacyNetworkBroadcast(nai, state, type); 1310 } 1311 1312 if (type == TYPE_VPN && state == DetailedState.CONNECTED) { 1313 maybeSendLegacyLockdownBroadcast(nai); 1314 } 1315 } 1316 1317 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)1318 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 1319 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1320 if (list == null || list.isEmpty()) { 1321 return; 1322 } 1323 final boolean wasFirstNetwork = list.get(0).equals(nai); 1324 1325 synchronized (mTypeLists) { 1326 if (!list.remove(nai)) { 1327 return; 1328 } 1329 } 1330 1331 if (wasFirstNetwork || wasDefault) { 1332 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault); 1333 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type); 1334 } 1335 1336 if (!list.isEmpty() && wasFirstNetwork) { 1337 if (DBG) log("Other network available for type " + type + 1338 ", sending connected broadcast"); 1339 final NetworkAgentInfo replacement = list.get(0); 1340 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type, 1341 mService.isDefaultNetwork(replacement)); 1342 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type); 1343 } 1344 } 1345 1346 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)1347 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 1348 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 1349 for (int type = 0; type < mTypeLists.length; type++) { 1350 remove(type, nai, wasDefault); 1351 } 1352 } 1353 1354 // send out another legacy broadcast - currently only used for suspend/unsuspend toggle update(NetworkAgentInfo nai)1355 public void update(NetworkAgentInfo nai) { 1356 final boolean isDefault = mService.isDefaultNetwork(nai); 1357 final DetailedState state = nai.networkInfo.getDetailedState(); 1358 for (int type = 0; type < mTypeLists.length; type++) { 1359 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1360 final boolean contains = (list != null && list.contains(nai)); 1361 final boolean isFirst = contains && (nai == list.get(0)); 1362 if (isFirst || contains && isDefault) { 1363 maybeLogBroadcast(nai, state, type, isDefault); 1364 mService.sendLegacyNetworkBroadcast(nai, state, type); 1365 } 1366 } 1367 } 1368 dump(IndentingPrintWriter pw)1369 public void dump(IndentingPrintWriter pw) { 1370 pw.println("mLegacyTypeTracker:"); 1371 pw.increaseIndent(); 1372 pw.print("Supported types:"); 1373 for (int type = 0; type < mTypeLists.length; type++) { 1374 if (mTypeLists[type] != null) pw.print(" " + type); 1375 } 1376 pw.println(); 1377 pw.println("Current state:"); 1378 pw.increaseIndent(); 1379 synchronized (mTypeLists) { 1380 for (int type = 0; type < mTypeLists.length; type++) { 1381 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 1382 for (NetworkAgentInfo nai : mTypeLists[type]) { 1383 pw.println(type + " " + nai.toShortString()); 1384 } 1385 } 1386 } 1387 pw.decreaseIndent(); 1388 pw.decreaseIndent(); 1389 pw.println(); 1390 } 1391 } 1392 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this); 1393 1394 final LocalPriorityDump mPriorityDumper = new LocalPriorityDump(); 1395 /** 1396 * Helper class which parses out priority arguments and dumps sections according to their 1397 * priority. If priority arguments are omitted, function calls the legacy dump command. 1398 */ 1399 private class LocalPriorityDump { 1400 private static final String PRIORITY_ARG = "--dump-priority"; 1401 private static final String PRIORITY_ARG_HIGH = "HIGH"; 1402 private static final String PRIORITY_ARG_NORMAL = "NORMAL"; 1403 private static final int DUMPSYS_DEFAULT_TIMEOUT_MS = 10_000; 1404 LocalPriorityDump()1405 LocalPriorityDump() {} 1406 dumpHigh(FileDescriptor fd, PrintWriter pw)1407 private void dumpHigh(FileDescriptor fd, PrintWriter pw) { 1408 if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> { 1409 doDump(fd, pw, new String[]{DIAG_ARG}); 1410 doDump(fd, pw, new String[]{SHORT_ARG}); 1411 }, DUMPSYS_DEFAULT_TIMEOUT_MS)) { 1412 pw.println("dumpHigh timeout"); 1413 } 1414 } 1415 dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1416 private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { 1417 if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> doDump(fd, pw, args), 1418 DUMPSYS_DEFAULT_TIMEOUT_MS)) { 1419 pw.println("dumpNormal timeout"); 1420 } 1421 } 1422 dump(FileDescriptor fd, PrintWriter pw, String[] args)1423 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1424 if (args == null) { 1425 dumpNormal(fd, pw, args); 1426 return; 1427 } 1428 1429 String priority = null; 1430 for (int argIndex = 0; argIndex < args.length; argIndex++) { 1431 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) { 1432 argIndex++; 1433 priority = args[argIndex]; 1434 } 1435 } 1436 1437 if (PRIORITY_ARG_HIGH.equals(priority)) { 1438 dumpHigh(fd, pw); 1439 } else if (PRIORITY_ARG_NORMAL.equals(priority)) { 1440 dumpNormal(fd, pw, args); 1441 } else { 1442 // ConnectivityService publishes binder service using publishBinderService() with 1443 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send 1444 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the 1445 // legacy output for dumpsys connectivity. 1446 // TODO: Integrate into signal dump. 1447 dumpNormal(fd, pw, args); 1448 } 1449 } 1450 } 1451 1452 /** 1453 * Dependencies of ConnectivityService, for injection in tests. 1454 */ 1455 @VisibleForTesting 1456 public static class Dependencies { getCallingUid()1457 public int getCallingUid() { 1458 return Binder.getCallingUid(); 1459 } 1460 isAtLeastS()1461 public boolean isAtLeastS() { 1462 return SdkLevel.isAtLeastS(); 1463 } 1464 isAtLeastT()1465 public boolean isAtLeastT() { 1466 return SdkLevel.isAtLeastT(); 1467 } 1468 isAtLeastU()1469 public boolean isAtLeastU() { 1470 return SdkLevel.isAtLeastU(); 1471 } 1472 isAtLeastV()1473 public boolean isAtLeastV() { 1474 return SdkLevel.isAtLeastV(); 1475 } 1476 isAtLeastB()1477 public boolean isAtLeastB() { 1478 return SdkLevel.isAtLeastB(); 1479 } 1480 1481 /** 1482 * Get system properties to use in ConnectivityService. 1483 */ getSystemProperties()1484 public MockableSystemProperties getSystemProperties() { 1485 return new MockableSystemProperties(); 1486 } 1487 1488 /** 1489 * Get the {@link ConnectivityResources} to use in ConnectivityService. 1490 */ getResources(@onNull Context ctx)1491 public ConnectivityResources getResources(@NonNull Context ctx) { 1492 return new ConnectivityResources(ctx); 1493 } 1494 1495 /** 1496 * Create a HandlerThread to use in ConnectivityService. 1497 */ makeHandlerThread(@onNull final String tag)1498 public HandlerThread makeHandlerThread(@NonNull final String tag) { 1499 return new HandlerThread(tag); 1500 } 1501 1502 /** 1503 * Get a reference to the ModuleNetworkStackClient. 1504 */ getNetworkStack()1505 public NetworkStackClientBase getNetworkStack() { 1506 return ModuleNetworkStackClient.getInstance(null); 1507 } 1508 1509 /** 1510 * @see ProxyTracker 1511 */ makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1512 public ProxyTracker makeProxyTracker(@NonNull Context context, 1513 @NonNull Handler connServiceHandler) { 1514 return new ProxyTracker(context, connServiceHandler, EVENT_PAC_PROXY_HAS_CHANGED); 1515 } 1516 1517 /** 1518 * @see NetIdManager 1519 */ makeNetIdManager()1520 public NetIdManager makeNetIdManager() { 1521 return new NetIdManager(); 1522 } 1523 1524 /** 1525 * @see NetworkUtils#queryUserAccess(int, int) 1526 */ queryUserAccess(int uid, Network network, ConnectivityService cs)1527 public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) { 1528 return cs.queryUserAccess(uid, network); 1529 } 1530 1531 /** 1532 * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets 1533 * requires CAP_NET_ADMIN, which the unit tests do not have. 1534 */ getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1535 public int getConnectionOwnerUid(int protocol, InetSocketAddress local, 1536 InetSocketAddress remote) { 1537 return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote); 1538 } 1539 1540 /** 1541 * @see MultinetworkPolicyTracker 1542 */ makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1543 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( 1544 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { 1545 return new MultinetworkPolicyTracker(c, h, r); 1546 } 1547 1548 /** 1549 * @see AutomaticOnOffKeepaliveTracker 1550 */ makeAutomaticOnOffKeepaliveTracker( @onNull Context c, @NonNull Handler h)1551 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker( 1552 @NonNull Context c, @NonNull Handler h) { 1553 return new AutomaticOnOffKeepaliveTracker(c, h); 1554 } 1555 makeMulticastRoutingCoordinatorService( @onNull Handler h)1556 public MulticastRoutingCoordinatorService makeMulticastRoutingCoordinatorService( 1557 @NonNull Handler h) { 1558 try { 1559 return new MulticastRoutingCoordinatorService(h); 1560 } catch (UnsupportedOperationException e) { 1561 // Multicast routing is not supported by the kernel 1562 Log.i(TAG, "Skipping unsupported MulticastRoutingCoordinatorService"); 1563 return null; 1564 } 1565 } 1566 1567 /** 1568 * @see NetworkRequestStateStatsMetrics 1569 */ makeNetworkRequestStateStatsMetrics( Context context)1570 public NetworkRequestStateStatsMetrics makeNetworkRequestStateStatsMetrics( 1571 Context context) { 1572 // We currently have network requests metric for Watch devices only 1573 if (context.getPackageManager().hasSystemFeature(FEATURE_WATCH)) { 1574 return new NetworkRequestStateStatsMetrics(); 1575 } else { 1576 return null; 1577 } 1578 } 1579 1580 /** 1581 * @see BatteryStatsManager 1582 */ reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1583 public void reportNetworkInterfaceForTransports(Context context, String iface, 1584 int[] transportTypes) { 1585 final BatteryStatsManager batteryStats = 1586 context.getSystemService(BatteryStatsManager.class); 1587 batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes); 1588 } 1589 getCellular464XlatEnabled()1590 public boolean getCellular464XlatEnabled() { 1591 return NetworkProperties.isCellular464XlatEnabled().orElse(true); 1592 } 1593 1594 /** 1595 * @see PendingIntent#intentFilterEquals 1596 */ intentFilterEquals(PendingIntent a, PendingIntent b)1597 public boolean intentFilterEquals(PendingIntent a, PendingIntent b) { 1598 return a.intentFilterEquals(b); 1599 } 1600 1601 /** 1602 * @see LocationPermissionChecker 1603 */ makeLocationPermissionChecker(Context context)1604 public LocationPermissionChecker makeLocationPermissionChecker(Context context) { 1605 return new LocationPermissionChecker(context); 1606 } 1607 1608 /** 1609 * @see CarrierPrivilegeAuthenticator 1610 * 1611 * This method returns null in versions before T, where carrier privilege 1612 * authentication is not supported. 1613 */ 1614 @Nullable makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm, boolean requestRestrictedWifiEnabled, @NonNull BiConsumer<Integer, Integer> listener, @NonNull final Handler connectivityServiceHandler)1615 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 1616 @NonNull final Context context, 1617 @NonNull final TelephonyManager tm, 1618 boolean requestRestrictedWifiEnabled, 1619 @NonNull BiConsumer<Integer, Integer> listener, 1620 @NonNull final Handler connectivityServiceHandler) { 1621 if (isAtLeastT()) { 1622 return new CarrierPrivilegeAuthenticator(context, tm, requestRestrictedWifiEnabled, 1623 listener, connectivityServiceHandler); 1624 } else { 1625 return null; 1626 } 1627 } 1628 1629 /** 1630 * @see SatelliteAccessController 1631 */ 1632 @Nullable makeSatelliteAccessController( @onNull final Context context, Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, @NonNull final Handler connectivityServiceInternalHandler)1633 public SatelliteAccessController makeSatelliteAccessController( 1634 @NonNull final Context context, 1635 Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, 1636 @NonNull final Handler connectivityServiceInternalHandler) { 1637 return new SatelliteAccessController(context, updateSatelliteNetworkFallbackUidCallback, 1638 connectivityServiceInternalHandler); 1639 } 1640 1641 /** Creates an L2capNetworkProvider */ makeL2capNetworkProvider(Context context)1642 public L2capNetworkProvider makeL2capNetworkProvider(Context context) { 1643 return new L2capNetworkProvider(context); 1644 } 1645 1646 /** Returns the data inactivity timeout to be used for cellular networks */ getDefaultCellularDataInactivityTimeout()1647 public int getDefaultCellularDataInactivityTimeout() { 1648 return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT, 1649 CELLULAR_DATA_INACTIVITY_TIMEOUT, 10); 1650 } 1651 1652 /** Returns the data inactivity timeout to be used for WiFi networks */ getDefaultWifiDataInactivityTimeout()1653 public int getDefaultWifiDataInactivityTimeout() { 1654 return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT, 1655 WIFI_DATA_INACTIVITY_TIMEOUT, 15); 1656 } 1657 1658 /** 1659 * @see DeviceConfigUtils#isTetheringFeatureEnabled 1660 */ isFeatureEnabled(Context context, String name)1661 public boolean isFeatureEnabled(Context context, String name) { 1662 return DeviceConfigUtils.isTetheringFeatureEnabled(context, name); 1663 } 1664 1665 /** 1666 * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut 1667 */ isFeatureNotChickenedOut(Context context, String name)1668 public boolean isFeatureNotChickenedOut(Context context, String name) { 1669 return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name); 1670 } 1671 1672 /** 1673 * Get the BpfNetMaps implementation to use in ConnectivityService. 1674 * @param netd a netd binder 1675 * @return BpfNetMaps implementation. 1676 */ getBpfNetMaps(Context context, INetd netd, InterfaceTracker interfaceTracker)1677 public BpfNetMaps getBpfNetMaps(Context context, INetd netd, 1678 InterfaceTracker interfaceTracker) { 1679 return new BpfNetMaps(context, netd, interfaceTracker); 1680 } 1681 1682 /** 1683 * Get the InterfaceTracker implementation to use in ConnectivityService. 1684 * @return InterfaceTracker implementation. 1685 */ getInterfaceTracker(Context context)1686 public InterfaceTracker getInterfaceTracker(Context context) { 1687 return new InterfaceTracker(context); 1688 } 1689 1690 /** 1691 * @see ClatCoordinator 1692 */ 1693 @RequiresApi(Build.VERSION_CODES.TIRAMISU) getClatCoordinator(INetd netd)1694 public ClatCoordinator getClatCoordinator(INetd netd) { 1695 return new ClatCoordinator( 1696 new ClatCoordinator.Dependencies() { 1697 @NonNull 1698 public INetd getNetd() { 1699 return netd; 1700 } 1701 }); 1702 } 1703 1704 /** 1705 * Wraps {@link TcUtils#tcFilterAddDevIngressPolice} 1706 */ enableIngressRateLimit(String iface, long rateInBytesPerSecond)1707 public void enableIngressRateLimit(String iface, long rateInBytesPerSecond) { 1708 final InterfaceParams params = InterfaceParams.getByName(iface); 1709 if (params == null) { 1710 // the interface might have disappeared. 1711 logw("Failed to get interface params for interface " + iface); 1712 return; 1713 } 1714 try { 1715 // converting rateInBytesPerSecond from long to int is safe here because the 1716 // setting's range is limited to INT_MAX. 1717 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice. 1718 Log.i(TAG, 1719 "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s"); 1720 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL, 1721 (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH); 1722 } catch (IOException e) { 1723 loge("TcUtils.tcFilterAddDevIngressPolice(ifaceIndex=" + params.index 1724 + ", PRIO_POLICE, ETH_P_ALL, rateInBytesPerSecond=" 1725 + rateInBytesPerSecond + ", bpfProgPath=" + TC_POLICE_BPF_PROG_PATH 1726 + ") failure: ", e); 1727 } 1728 } 1729 1730 /** 1731 * Wraps {@link TcUtils#tcFilterDelDev} 1732 */ disableIngressRateLimit(String iface)1733 public void disableIngressRateLimit(String iface) { 1734 final InterfaceParams params = InterfaceParams.getByName(iface); 1735 if (params == null) { 1736 // the interface might have disappeared. 1737 logw("Failed to get interface params for interface " + iface); 1738 return; 1739 } 1740 try { 1741 Log.i(TAG, 1742 "disableIngressRateLimit on " + iface); 1743 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL); 1744 } catch (IOException e) { 1745 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index 1746 + ", ingress=true, PRIO_POLICE, ETH_P_ALL) failure: ", e); 1747 } 1748 } 1749 1750 /** 1751 * Get BPF program Id from CGROUP. See {@link BpfUtils#getProgramId}. 1752 */ getBpfProgramId(final int attachType)1753 public int getBpfProgramId(final int attachType) 1754 throws IOException { 1755 return BpfUtils.getProgramId(attachType); 1756 } 1757 1758 /** 1759 * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)} 1760 */ 1761 // TODO: when available in all active branches: 1762 // @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 1763 @RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT) makeBroadcastOptionsShim(BroadcastOptions options)1764 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 1765 return BroadcastOptionsShimImpl.newInstance(options); 1766 } 1767 1768 /** 1769 * Wrapper method for 1770 * {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}. 1771 * 1772 * @param changeId The ID of the compatibility change in question. 1773 * @param packageName The package name of the app in question. 1774 * @param user The user that the operation is done for. 1775 * @return {@code true} if the change is enabled for the specified package. 1776 */ isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)1777 public boolean isChangeEnabled(long changeId, @NonNull final String packageName, 1778 @NonNull final UserHandle user) { 1779 return CompatChanges.isChangeEnabled(changeId, packageName, user); 1780 } 1781 1782 /** 1783 * As above but with a UID. 1784 * @see CompatChanges#isChangeEnabled(long, int) 1785 */ isChangeEnabled(final long changeId, final int uid)1786 public boolean isChangeEnabled(final long changeId, final int uid) { 1787 return CompatChanges.isChangeEnabled(changeId, uid); 1788 } 1789 1790 /** 1791 * Call {@link InetDiagMessage#destroyLiveTcpSockets(Set, Set)} 1792 * 1793 * @param ranges target uid ranges 1794 * @param exemptUids uids to skip close socket 1795 */ destroyLiveTcpSockets(@onNull final Set<Range<Integer>> ranges, @NonNull final Set<Integer> exemptUids)1796 public void destroyLiveTcpSockets(@NonNull final Set<Range<Integer>> ranges, 1797 @NonNull final Set<Integer> exemptUids) 1798 throws SocketException, InterruptedIOException, ErrnoException { 1799 InetDiagMessage.destroyLiveTcpSockets(ranges, exemptUids); 1800 } 1801 1802 /** 1803 * Call {@link InetDiagMessage#destroyLiveTcpSocketsByOwnerUids(Set)} 1804 * 1805 * @param ownerUids target uids to close sockets 1806 */ destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)1807 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) 1808 throws SocketException, InterruptedIOException, ErrnoException { 1809 InetDiagMessage.destroyLiveTcpSocketsByOwnerUids(ownerUids); 1810 } 1811 1812 /** 1813 * Schedule the evaluation timeout. 1814 * 1815 * When a network connects, it's "not evaluated" yet. Detection events cause the network 1816 * to be "evaluated" (typically, validation or detection of a captive portal). If none 1817 * of these events happen, this time will run out, after which the network is considered 1818 * "evaluated" even if nothing happened to it. Notionally that means the system gave up 1819 * on this network and considers it won't provide connectivity. In particular, that means 1820 * it's when the system prefers it to cell if it's wifi and configuration says it should 1821 * prefer bad wifi to cell. 1822 */ scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)1823 public void scheduleEvaluationTimeout(@NonNull Handler handler, 1824 @NonNull final Network network, final long delayMs) { 1825 handler.sendMessageDelayed( 1826 handler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs); 1827 } 1828 } 1829 1830 public ConnectivityService(Context context) { 1831 this(context, getDnsResolver(context), new IpConnectivityLog(), 1832 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), 1833 new Dependencies(), new PermissionMonitor.Dependencies()); 1834 } 1835 1836 @VisibleForTesting 1837 protected ConnectivityService(Context context, IDnsResolver dnsresolver, 1838 IpConnectivityLog logger, INetd netd, Dependencies deps, 1839 PermissionMonitor.Dependencies mPermDeps) { 1840 if (DBG) log("ConnectivityService starting up"); 1841 1842 mDeps = Objects.requireNonNull(deps, "missing Dependencies"); 1843 mFlags = new ConnectivityFlags(); 1844 mSystemProperties = mDeps.getSystemProperties(); 1845 mNetIdManager = mDeps.makeNetIdManager(); 1846 mContext = Objects.requireNonNull(context, "missing Context"); 1847 mResources = deps.getResources(mContext); 1848 // The legacy PerUidCounter is buggy and throwing exception at count == limit. 1849 // Pass limit - 1 to maintain backward compatibility. 1850 // TODO: Remove the workaround. 1851 mNetworkRequestCounter = 1852 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_UID - 1); 1853 mSystemNetworkRequestCounter = 1854 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1); 1855 1856 mMetricsLog = logger; 1857 mNetworkRequestStateStatsMetrics = mDeps.makeNetworkRequestStateStatsMetrics(mContext); 1858 final NetworkRequest defaultInternetRequest = createDefaultRequest(); 1859 mDefaultRequest = new NetworkRequestInfo( 1860 Process.myUid(), defaultInternetRequest, null, 1861 null /* binder */, NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1862 null /* attributionTags */, DECLARED_METHODS_NONE); 1863 mNetworkRequests.put(defaultInternetRequest, mDefaultRequest); 1864 mDefaultNetworkRequests.add(mDefaultRequest); 1865 mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest); 1866 1867 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( 1868 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); 1869 1870 // The default WiFi request is a background request so that apps using WiFi are 1871 // migrated to a better network (typically ethernet) when one comes up, instead 1872 // of staying on WiFi forever. 1873 mDefaultWifiRequest = createDefaultInternetRequestForTransport( 1874 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); 1875 1876 mDefaultVehicleRequest = createAlwaysOnRequestForCapability( 1877 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL, 1878 NetworkRequest.Type.BACKGROUND_REQUEST); 1879 1880 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 1881 // TODO: Consider making the timer customizable. 1882 mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS; 1883 mCellularRadioTimesharingCapable = 1884 mResources.get().getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1885 1886 int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark); 1887 int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask); 1888 1889 if (SdkLevel.isAtLeastU()) { 1890 // U+ default value of both mark & mask, this is the top bit of the skb->mark, 1891 // see //system/netd/include/FwMark.h union Fwmark, field ingress_cpu_wakeup 1892 final int defaultUMarkMask = 0x80000000; // u32 1893 1894 if ((mark == 0) || (mask == 0)) { 1895 // simply treat unset/disabled as the default U value 1896 mark = defaultUMarkMask; 1897 mask = defaultUMarkMask; 1898 } 1899 if ((mark != defaultUMarkMask) || (mask != defaultUMarkMask)) { 1900 // invalid device overlay settings 1901 throw new IllegalArgumentException( 1902 "Bad config_networkWakeupPacketMark/Mask " + mark + "/" + mask); 1903 } 1904 } 1905 1906 mWakeUpMark = mark; 1907 mWakeUpMask = mask; 1908 1909 mNetd = netd; 1910 mInterfaceTracker = mDeps.getInterfaceTracker(mContext); 1911 mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd, mInterfaceTracker); 1912 mHandlerThread = mDeps.makeHandlerThread("ConnectivityServiceThread"); 1913 mPermissionMonitorDeps = mPermDeps; 1914 mPermissionMonitor = 1915 new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mPermissionMonitorDeps, 1916 mHandlerThread); 1917 mHandlerThread.start(); 1918 mHandler = new InternalHandler(mHandlerThread.getLooper()); 1919 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 1920 mConnectivityDiagnosticsHandler = 1921 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper()); 1922 1923 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 1924 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 1925 1926 mStatsManager = mContext.getSystemService(NetworkStatsManager.class); 1927 mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); 1928 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver"); 1929 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); 1930 1931 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1932 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 1933 mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); 1934 mRequestRestrictedWifiEnabled = mDeps.isAtLeastU() 1935 && mDeps.isFeatureEnabled(context, REQUEST_RESTRICTED_WIFI); 1936 mBackgroundFirewallChainEnabled = mDeps.isAtLeastV() && mDeps.isFeatureNotChickenedOut( 1937 context, ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN); 1938 mUseDeclaredMethodsForCallbacksEnabled = 1939 mDeps.isFeatureNotChickenedOut(context, 1940 ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS); 1941 mQueueNetworkAgentEventsInSystemServer = mDeps.isAtLeastB() 1942 && mDeps.isFeatureNotChickenedOut(context, 1943 ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER); 1944 // registerUidFrozenStateChangedCallback is only available on U+ 1945 mQueueCallbacksForFrozenApps = mDeps.isAtLeastU() 1946 && mDeps.isFeatureNotChickenedOut(context, QUEUE_CALLBACKS_FOR_FROZEN_APPS); 1947 mCarrierPrivilegeAuthenticator = mDeps.makeCarrierPrivilegeAuthenticator( 1948 mContext, mTelephonyManager, mRequestRestrictedWifiEnabled, 1949 this::handleUidCarrierPrivilegesLost, mHandler); 1950 1951 if (mDeps.isAtLeastU() 1952 && mDeps 1953 .isFeatureNotChickenedOut(mContext, ALLOW_SATALLITE_NETWORK_FALLBACK)) { 1954 mSatelliteAccessController = mDeps.makeSatelliteAccessController( 1955 mContext, this::updateSatelliteNetworkPreferenceUids, mHandler); 1956 } else { 1957 mSatelliteAccessController = null; 1958 } 1959 1960 // To ensure uid state is synchronized with Network Policy, register for 1961 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService 1962 // reading existing policy from disk. 1963 // If shouldTrackUidsForBlockedStatusCallbacks() is true (On V+), ConnectivityService 1964 // updates blocked reasons when firewall chain and data saver status is updated based on 1965 // bpf map contents instead of receiving callbacks from NPMS 1966 if (!shouldTrackUidsForBlockedStatusCallbacks()) { 1967 mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback); 1968 } 1969 1970 final PowerManager powerManager = (PowerManager) context.getSystemService( 1971 Context.POWER_SERVICE); 1972 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1973 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1974 1975 mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager); 1976 mProtectedNetworks = new ArrayList<>(); 1977 int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks); 1978 for (int p : protectedNetworks) { 1979 if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) { 1980 mProtectedNetworks.add(p); 1981 } else { 1982 if (DBG) loge("Ignoring protectedNetwork " + p); 1983 } 1984 } 1985 1986 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 1987 1988 mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */); 1989 // Listen for user add/removes to inform PermissionMonitor. 1990 // Should run on mHandler to avoid any races. 1991 final IntentFilter userIntentFilter = new IntentFilter(); 1992 userIntentFilter.addAction(Intent.ACTION_USER_ADDED); 1993 userIntentFilter.addAction(Intent.ACTION_USER_REMOVED); 1994 mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter, 1995 null /* broadcastPermission */, mHandler); 1996 1997 // Listen to package add/removes for netd 1998 final IntentFilter packageIntentFilter = new IntentFilter(); 1999 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 2000 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 2001 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 2002 packageIntentFilter.addDataScheme("package"); 2003 mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter, 2004 null /* broadcastPermission */, mHandler); 2005 2006 // This is needed for pre-V devices to propagate the data saver status 2007 // to the BPF map. This isn't supported before Android T because BPF maps are 2008 // unsupported, and it's also unnecessary on Android V and later versions, 2009 // as the platform code handles data saver bit updates. Additionally, checking 2010 // the initial data saver status here is superfluous because the intent won't 2011 // be sent until the system is ready. 2012 if (mDeps.isAtLeastT() && !mDeps.isAtLeastV()) { 2013 final IntentFilter dataSaverIntentFilter = 2014 new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED); 2015 mUserAllContext.registerReceiver(mDataSaverReceiver, dataSaverIntentFilter, 2016 null /* broadcastPermission */, mHandler); 2017 } 2018 2019 // TrackMultiNetworkActivities feature should be enabled by trunk stable flag. 2020 // But reading the trunk stable flags from mainline modules is not supported yet. 2021 // So enabling this feature on V+ release. 2022 mTrackMultiNetworkActivities = mDeps.isAtLeastV(); 2023 final int defaultCellularDataInactivityTimeout = 2024 mDeps.getDefaultCellularDataInactivityTimeout(); 2025 final int defaultWifiDataInactivityTimeout = 2026 mDeps.getDefaultWifiDataInactivityTimeout(); 2027 mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNetd, mHandler, 2028 mTrackMultiNetworkActivities, defaultCellularDataInactivityTimeout, 2029 defaultWifiDataInactivityTimeout); 2030 2031 final NetdCallback netdCallback = new NetdCallback(); 2032 try { 2033 mNetd.registerUnsolicitedEventListener(netdCallback); 2034 } catch (RemoteException | ServiceSpecificException e) { 2035 loge("Error registering event listener :" + e); 2036 } 2037 2038 mSettingsObserver = new SettingsObserver(mContext, mHandler); 2039 registerSettingsCallbacks(); 2040 2041 mKeepaliveTracker = mDeps.makeAutomaticOnOffKeepaliveTracker(mContext, mHandler); 2042 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager); 2043 mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter); 2044 2045 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 2046 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 2047 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 2048 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 2049 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 2050 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 2051 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 2052 2053 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( 2054 mContext, mHandler, () -> updateAvoidBadWifi()); 2055 mNetworkRanker = 2056 new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi())); 2057 2058 mMultinetworkPolicyTracker.start(); 2059 2060 mDnsManager = new DnsManager(mContext, mDnsResolver); 2061 registerPrivateDnsSettingsCallbacks(); 2062 2063 // This NAI is a sentinel used to offer no service to apps that are on a multi-layer 2064 // request that doesn't allow fallback to the default network. It should never be visible 2065 // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal 2066 // arguments like the handler or the DnsResolver. 2067 // TODO : remove this ; it is probably better handled with a sentinel request. 2068 mNoServiceNetwork = new NetworkAgentInfo(null, 2069 new Network(INetd.UNREACHABLE_NET_ID), 2070 new NetworkInfo(TYPE_NONE, 0, "", ""), 2071 new LinkProperties(), new NetworkCapabilities(), null /* localNetworkConfig */, 2072 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, 2073 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, 2074 mLingerDelayMs, mQosCallbackTracker, mDeps); 2075 2076 try { 2077 // DscpPolicyTracker cannot run on S because on S the tethering module can only load 2078 // BPF programs/maps into /sys/fs/tethering/bpf, which the system server cannot access. 2079 // Even if it could, running on S would at least require mocking out the BPF map, 2080 // otherwise the unit tests will fail on pre-T devices where the seccomp filter blocks 2081 // the bpf syscall. http://aosp/1907693 2082 if (mDeps.isAtLeastT()) { 2083 mDscpPolicyTracker = new DscpPolicyTracker(); 2084 } 2085 } catch (ErrnoException e) { 2086 loge("Unable to create DscpPolicyTracker"); 2087 } 2088 2089 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 2090 mContext); 2091 2092 if (mDeps.isAtLeastT()) { 2093 mCdmps = new CompanionDeviceManagerProxyService(context); 2094 } else { 2095 mCdmps = null; 2096 } 2097 2098 mRoutingCoordinatorService = 2099 new RoutingCoordinatorService(netd, this::getAllNetworks, mContext); 2100 mMulticastRoutingCoordinatorService = 2101 mDeps.makeMulticastRoutingCoordinatorService(mHandler); 2102 2103 mDestroyFrozenSockets = mDeps.isAtLeastV() || (mDeps.isAtLeastU() 2104 && mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION)); 2105 mDelayDestroySockets = mDeps.isFeatureNotChickenedOut(context, DELAY_DESTROY_SOCKETS); 2106 mAllowSysUiConnectivityReports = mDeps.isFeatureNotChickenedOut( 2107 mContext, ALLOW_SYSUI_CONNECTIVITY_REPORTS); 2108 if (mDestroyFrozenSockets || mQueueCallbacksForFrozenApps) { 2109 final UidFrozenStateChangedCallback frozenStateChangedCallback = 2110 new UidFrozenStateChangedCallback() { 2111 @Override 2112 public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) { 2113 if (uids.length != frozenStates.length) { 2114 Log.wtf(TAG, "uids has length " + uids.length 2115 + " but frozenStates has length " + frozenStates.length); 2116 return; 2117 } 2118 2119 final UidFrozenStateChangedArgs args = 2120 new UidFrozenStateChangedArgs(uids, frozenStates); 2121 2122 mHandler.sendMessage( 2123 mHandler.obtainMessage(EVENT_UID_FROZEN_STATE_CHANGED, args)); 2124 } 2125 }; 2126 2127 final ActivityManager activityManager = 2128 mContext.getSystemService(ActivityManager.class); 2129 activityManager.registerUidFrozenStateChangedCallback( 2130 (Runnable r) -> r.run(), frozenStateChangedCallback); 2131 } 2132 mIngressToVpnAddressFiltering = mDeps.isAtLeastT() 2133 && mDeps.isFeatureNotChickenedOut(mContext, INGRESS_TO_VPN_ADDRESS_FILTERING); 2134 2135 mL2capNetworkProvider = mDeps.makeL2capNetworkProvider(mContext); 2136 } 2137 2138 /** 2139 * Check whether or not the device supports Ethernet transport. 2140 */ 2141 public static boolean deviceSupportsEthernet(final Context context) { 2142 final PackageManager pm = context.getPackageManager(); 2143 return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET) 2144 || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST); 2145 } 2146 2147 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { 2148 return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton( 2149 new UidRange(uid, uid))); 2150 } 2151 2152 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet( 2153 @NonNull final Set<UidRange> uidRangeSet) { 2154 final NetworkCapabilities netCap = new NetworkCapabilities(); 2155 netCap.addCapability(NET_CAPABILITY_INTERNET); 2156 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 2157 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 2158 netCap.setUids(UidRange.toIntRanges(uidRangeSet)); 2159 return netCap; 2160 } 2161 2162 private NetworkRequest createDefaultRequest() { 2163 return createDefaultInternetRequestForTransport( 2164 TYPE_NONE, NetworkRequest.Type.REQUEST); 2165 } 2166 2167 private NetworkRequest createVpnRequest() { 2168 final NetworkCapabilities netCap = new NetworkCapabilities.Builder() 2169 .withoutDefaultCapabilities() 2170 .addTransportType(TRANSPORT_VPN) 2171 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 2172 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 2173 .build(); 2174 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2175 return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap); 2176 } 2177 2178 private NetworkRequest createDefaultInternetRequestForTransport( 2179 int transportType, NetworkRequest.Type type) { 2180 final NetworkCapabilities netCap = new NetworkCapabilities(); 2181 netCap.addCapability(NET_CAPABILITY_INTERNET); 2182 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 2183 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2184 if (transportType > TYPE_NONE) { 2185 netCap.addTransportType(transportType); 2186 } 2187 return createNetworkRequest(type, netCap); 2188 } 2189 2190 private NetworkRequest createNetworkRequest( 2191 NetworkRequest.Type type, NetworkCapabilities netCap) { 2192 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 2193 } 2194 2195 private NetworkRequest createAlwaysOnRequestForCapability(int capability, 2196 NetworkRequest.Type type) { 2197 final NetworkCapabilities netCap = new NetworkCapabilities(); 2198 netCap.clearAll(); 2199 netCap.addCapability(capability); 2200 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 2201 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 2202 } 2203 2204 // Used only for testing. 2205 // TODO: Delete this and either: 2206 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires 2207 // changing ContentResolver to make registerContentObserver non-final). 2208 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 2209 // by subclassing SettingsObserver. 2210 @VisibleForTesting 2211 void updateAlwaysOnNetworks() { 2212 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2213 } 2214 2215 // See FakeSettingsProvider comment above. 2216 @VisibleForTesting 2217 void updatePrivateDnsSettings() { 2218 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 2219 } 2220 2221 @VisibleForTesting 2222 public void updateMobileDataPreferredUids() { 2223 mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 2224 } 2225 2226 @VisibleForTesting 2227 void updateIngressRateLimit() { 2228 mHandler.sendEmptyMessage(EVENT_INGRESS_RATE_LIMIT_CHANGED); 2229 } 2230 2231 @VisibleForTesting 2232 void simulateUpdateProxyInfo(@Nullable final Network network, 2233 @NonNull final ProxyInfo proxyInfo) { 2234 Message.obtain(mHandler, EVENT_PAC_PROXY_HAS_CHANGED, 2235 new Pair<>(network, proxyInfo)).sendToTarget(); 2236 } 2237 2238 /** 2239 * Called when satellite network fallback uids at {@link SatelliteAccessController} 2240 * cache was updated based on {@link 2241 * android.app.role.OnRoleHoldersChangedListener#onRoleHoldersChanged(String, UserHandle)}, 2242 * to create multilayer request with preference order 2243 * {@link #PREFERENCE_ORDER_SATELLITE_FALLBACK} there on. 2244 * 2245 */ 2246 private void updateSatelliteNetworkPreferenceUids(Set<Integer> satelliteNetworkFallbackUids) { 2247 handleSetSatelliteNetworkPreference(satelliteNetworkFallbackUids); 2248 } 2249 2250 private void handleAlwaysOnNetworkRequest( 2251 NetworkRequest networkRequest, String settingName, boolean defaultValue) { 2252 final boolean enable = toBool(Settings.Global.getInt( 2253 mContext.getContentResolver(), settingName, encodeBool(defaultValue))); 2254 handleAlwaysOnNetworkRequest(networkRequest, enable); 2255 } 2256 2257 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) { 2258 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); 2259 if (enable == isEnabled) { 2260 return; // Nothing to do. 2261 } 2262 2263 if (enable) { 2264 handleRegisterNetworkRequest(new NetworkRequestInfo( 2265 Process.myUid(), networkRequest, null /* messenger */, null /* binder */, 2266 NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 2267 null /* attributionTags */, DECLARED_METHODS_NONE)); 2268 } else { 2269 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, 2270 /* callOnUnavailable */ false); 2271 } 2272 } 2273 2274 private void handleConfigureAlwaysOnNetworks() { 2275 handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest, 2276 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */); 2277 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, 2278 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */); 2279 final boolean vehicleAlwaysRequested = mResources.get().getBoolean( 2280 R.bool.config_vehicleInternalNetworkAlwaysRequested); 2281 handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested); 2282 } 2283 2284 // Note that registering observer for setting do not get initial callback when registering, 2285 // callers must fetch the initial value of the setting themselves if needed. 2286 private void registerSettingsCallbacks() { 2287 // Watch for global HTTP proxy changes. 2288 mSettingsObserver.observe( 2289 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 2290 EVENT_APPLY_GLOBAL_HTTP_PROXY); 2291 2292 // Watch for whether to keep mobile data always on. 2293 mSettingsObserver.observe( 2294 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON), 2295 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2296 2297 // Watch for whether to keep wifi always on. 2298 mSettingsObserver.observe( 2299 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED), 2300 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 2301 2302 // Watch for mobile data preferred uids changes. 2303 mSettingsObserver.observe( 2304 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS), 2305 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 2306 2307 // Watch for ingress rate limit changes. 2308 mSettingsObserver.observe( 2309 Settings.Global.getUriFor( 2310 ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND), 2311 EVENT_INGRESS_RATE_LIMIT_CHANGED); 2312 } 2313 2314 private void registerPrivateDnsSettingsCallbacks() { 2315 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { 2316 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 2317 } 2318 } 2319 2320 private synchronized int nextNetworkRequestId() { 2321 // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if 2322 // doing that. 2323 return mNextNetworkRequestId++; 2324 } 2325 2326 @VisibleForTesting 2327 @Nullable 2328 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 2329 if (network == null) { 2330 return null; 2331 } 2332 return getNetworkAgentInfoForNetId(network.getNetId()); 2333 } 2334 2335 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { 2336 synchronized (mNetworkForNetId) { 2337 return mNetworkForNetId.get(netId); 2338 } 2339 } 2340 2341 // TODO: determine what to do when more than one VPN applies to |uid|. 2342 @Nullable 2343 private NetworkAgentInfo getVpnForUid(int uid) { 2344 synchronized (mNetworkForNetId) { 2345 for (int i = 0; i < mNetworkForNetId.size(); i++) { 2346 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 2347 if (nai.isVPN() && nai.everConnected() 2348 && nai.networkCapabilities.appliesToUid(uid)) { 2349 return nai; 2350 } 2351 } 2352 } 2353 return null; 2354 } 2355 2356 @Nullable 2357 private Network[] getVpnUnderlyingNetworks(int uid) { 2358 if (mLockdownEnabled) return null; 2359 final NetworkAgentInfo nai = getVpnForUid(uid); 2360 if (nai != null) return nai.declaredUnderlyingNetworks; 2361 return null; 2362 } 2363 2364 private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) { 2365 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2366 2367 final Network[] networks = getVpnUnderlyingNetworks(uid); 2368 if (networks != null) { 2369 // getUnderlyingNetworks() returns: 2370 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 2371 // empty array => the VPN explicitly said "no default network". 2372 // non-empty array => the VPN specified one or more default networks; we use the 2373 // first one. 2374 if (networks.length > 0) { 2375 nai = getNetworkAgentInfoForNetwork(networks[0]); 2376 } else { 2377 nai = null; 2378 } 2379 } 2380 return nai; 2381 } 2382 2383 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 2384 private boolean hasInternetPermission(final int uid) { 2385 return (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) != 0; 2386 } 2387 2388 /** 2389 * Check if UID should be blocked from using the specified network. 2390 */ 2391 private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc, 2392 final int uid, final boolean ignoreBlocked) { 2393 // Networks aren't blocked when ignoring blocked status 2394 if (ignoreBlocked) { 2395 return false; 2396 } 2397 if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true; 2398 final long ident = Binder.clearCallingIdentity(); 2399 try { 2400 final boolean metered = nc == null ? true : nc.isMetered(); 2401 if (mDeps.isAtLeastV()) { 2402 final boolean hasInternetPermission = hasInternetPermission(uid); 2403 final boolean blockedByUidRules = mBpfNetMaps.isUidNetworkingBlocked(uid, metered); 2404 if (mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid)) { 2405 return blockedByUidRules || !hasInternetPermission; 2406 } else { 2407 return hasInternetPermission && blockedByUidRules; 2408 } 2409 } else { 2410 return mPolicyManager.isUidNetworkingBlocked(uid, metered); 2411 } 2412 } finally { 2413 Binder.restoreCallingIdentity(ident); 2414 } 2415 } 2416 2417 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 2418 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 2419 return; 2420 } 2421 final boolean blocked; 2422 synchronized (mBlockedAppUids) { 2423 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 2424 blocked = true; 2425 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 2426 blocked = false; 2427 } else { 2428 return; 2429 } 2430 } 2431 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 2432 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid)); 2433 mNetworkInfoBlockingLogs.log(action + " " + uid); 2434 } 2435 2436 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) { 2437 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { 2438 return; 2439 } 2440 final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED"; 2441 final int requestId = nri.getActiveRequest() != null 2442 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId; 2443 mNetworkInfoBlockingLogs.log(String.format( 2444 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(), 2445 Integer.toHexString(blocked))); 2446 } 2447 2448 /** 2449 * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For 2450 * example, this may mark the network as {@link DetailedState#BLOCKED} based 2451 * on {@link #isNetworkWithCapabilitiesBlocked}. 2452 */ 2453 @NonNull 2454 private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type, 2455 @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) { 2456 final NetworkInfo filtered = new NetworkInfo(networkInfo); 2457 // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network 2458 // but only exists if an app asks about them or requests them. Ensure the requesting app 2459 // gets the type it asks for. 2460 filtered.setType(type); 2461 if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) { 2462 filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */, 2463 null /* extraInfo */); 2464 } 2465 filterForLegacyLockdown(filtered); 2466 return filtered; 2467 } 2468 2469 private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, 2470 boolean ignoreBlocked) { 2471 return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), 2472 nai.networkCapabilities, uid, ignoreBlocked); 2473 } 2474 2475 /** 2476 * Return NetworkInfo for the active (i.e., connected) network interface. 2477 * It is assumed that at most one network is active at a time. If more 2478 * than one is active, it is indeterminate which will be returned. 2479 * @return the info for the active network, or {@code null} if none is 2480 * active 2481 */ 2482 @Override 2483 @Nullable 2484 public NetworkInfo getActiveNetworkInfo() { 2485 enforceAccessPermission(); 2486 final int uid = mDeps.getCallingUid(); 2487 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2488 if (nai == null) return null; 2489 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false /* ignoreBlocked */); 2490 maybeLogBlockedNetworkInfo(networkInfo, uid); 2491 return networkInfo; 2492 } 2493 2494 @Override 2495 @Nullable 2496 public Network getActiveNetwork() { 2497 enforceAccessPermission(); 2498 return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false); 2499 } 2500 2501 @Override 2502 @Nullable 2503 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 2504 enforceNetworkStackPermission(mContext); 2505 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 2506 } 2507 2508 @Nullable 2509 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 2510 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 2511 if (vpnNai != null) { 2512 final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid); 2513 if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) { 2514 return vpnNai.network; 2515 } 2516 } 2517 2518 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2519 if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, 2520 ignoreBlocked)) { 2521 return null; 2522 } 2523 return nai.network; 2524 } 2525 2526 @Override 2527 @Nullable 2528 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 2529 enforceNetworkStackPermission(mContext); 2530 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2531 if (nai == null) return null; 2532 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2533 } 2534 2535 /** Returns a NetworkInfo object for a network that doesn't exist. */ 2536 private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) { 2537 final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */, 2538 getNetworkTypeName(networkType), "" /* subtypeName */); 2539 info.setIsAvailable(true); 2540 // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when 2541 // background data is restricted. 2542 final NetworkCapabilities nc = new NetworkCapabilities(); // Metered. 2543 final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false) 2544 ? DetailedState.BLOCKED 2545 : DetailedState.DISCONNECTED; 2546 info.setDetailedState(state, null /* reason */, null /* extraInfo */); 2547 filterForLegacyLockdown(info); 2548 return info; 2549 } 2550 2551 private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) { 2552 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2553 return null; 2554 } 2555 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2556 if (nai == null) { 2557 return makeFakeNetworkInfo(networkType, uid); 2558 } 2559 return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid, 2560 false); 2561 } 2562 2563 @Override 2564 @Nullable 2565 public NetworkInfo getNetworkInfo(int networkType) { 2566 enforceAccessPermission(); 2567 final int uid = mDeps.getCallingUid(); 2568 if (getVpnUnderlyingNetworks(uid) != null) { 2569 // A VPN is active, so we may need to return one of its underlying networks. This 2570 // information is not available in LegacyTypeTracker, so we have to get it from 2571 // getNetworkAgentInfoForUid. 2572 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2573 if (nai == null) return null; 2574 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 2575 if (networkInfo.getType() == networkType) { 2576 return networkInfo; 2577 } 2578 } 2579 return getFilteredNetworkInfoForType(networkType, uid); 2580 } 2581 2582 @Override 2583 @Nullable 2584 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 2585 enforceAccessPermission(); 2586 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2587 if (nai == null) return null; 2588 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2589 } 2590 2591 @Override 2592 public NetworkInfo[] getAllNetworkInfo() { 2593 enforceAccessPermission(); 2594 final ArrayList<NetworkInfo> result = new ArrayList<>(); 2595 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 2596 networkType++) { 2597 NetworkInfo info = getNetworkInfo(networkType); 2598 if (info != null) { 2599 result.add(info); 2600 } 2601 } 2602 return result.toArray(new NetworkInfo[result.size()]); 2603 } 2604 2605 @Override 2606 @Nullable 2607 public Network getNetworkForType(int networkType) { 2608 enforceAccessPermission(); 2609 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2610 return null; 2611 } 2612 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2613 if (nai == null) { 2614 return null; 2615 } 2616 final int uid = mDeps.getCallingUid(); 2617 if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) { 2618 return null; 2619 } 2620 return nai.network; 2621 } 2622 2623 @Override 2624 @NonNull 2625 public Network[] getAllNetworks() { 2626 enforceAccessPermission(); 2627 synchronized (mNetworkForNetId) { 2628 final Network[] result = new Network[mNetworkForNetId.size()]; 2629 for (int i = 0; i < mNetworkForNetId.size(); i++) { 2630 result[i] = mNetworkForNetId.valueAt(i).network; 2631 } 2632 return result; 2633 } 2634 } 2635 2636 @Override 2637 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser( 2638 int userId, String callingPackageName, @Nullable String callingAttributionTag) { 2639 // The basic principle is: if an app's traffic could possibly go over a 2640 // network, without the app doing anything multinetwork-specific, 2641 // (hence, by "default"), then include that network's capabilities in 2642 // the array. 2643 // 2644 // In the normal case, app traffic only goes over the system's default 2645 // network connection, so that's the only network returned. 2646 // 2647 // With a VPN in force, some app traffic may go into the VPN, and thus 2648 // over whatever underlying networks the VPN specifies, while other app 2649 // traffic may go over the system default network (e.g.: a split-tunnel 2650 // VPN, or an app disallowed by the VPN), so the set of networks 2651 // returned includes the VPN's underlying networks and the system 2652 // default. 2653 enforceAccessPermission(); 2654 2655 HashMap<Network, NetworkCapabilities> result = new HashMap<>(); 2656 2657 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 2658 if (!nri.isBeingSatisfied()) { 2659 continue; 2660 } 2661 final NetworkAgentInfo nai = nri.getSatisfier(); 2662 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 2663 if (null != nc 2664 && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 2665 && !result.containsKey(nai.network)) { 2666 result.put( 2667 nai.network, 2668 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2669 nc, false /* includeLocationSensitiveInfo */, 2670 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2671 callingAttributionTag)); 2672 } 2673 } 2674 2675 // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null. 2676 final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid()); 2677 if (null != networks) { 2678 for (final Network network : networks) { 2679 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 2680 if (null != nc) { 2681 result.put( 2682 network, 2683 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2684 nc, 2685 false /* includeLocationSensitiveInfo */, 2686 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2687 callingAttributionTag)); 2688 } 2689 } 2690 } 2691 2692 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 2693 out = result.values().toArray(out); 2694 return out; 2695 } 2696 2697 // Because StatsEvent is not usable in tests (everything inside it is hidden), this 2698 // method is used to convert a ConnectivityStateSample into a StatsEvent, so that tests 2699 // can call sampleConnectivityState and make the checks on it. 2700 @NonNull 2701 private StatsEvent sampleConnectivityStateToStatsEvent() { 2702 final ConnectivityStateSample sample = sampleConnectivityState(); 2703 return ConnectivityStatsLog.buildStatsEvent( 2704 ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE, 2705 sample.getNetworkCountPerTransports().toByteArray(), 2706 sample.getConnectionDurationPerTransports().toByteArray(), 2707 sample.getNetworkRequestCount().toByteArray(), 2708 sample.getNetworks().toByteArray()); 2709 } 2710 2711 /** 2712 * Gather and return a snapshot of the current connectivity state, to be used as a sample. 2713 * 2714 * This is used for metrics. These snapshots will be sampled and constitute a base for 2715 * statistics about connectivity state of devices. 2716 */ 2717 @VisibleForTesting 2718 @NonNull 2719 public ConnectivityStateSample sampleConnectivityState() { 2720 ensureRunningOnConnectivityServiceThread(); 2721 final ConnectivityStateSample.Builder builder = ConnectivityStateSample.newBuilder(); 2722 builder.setNetworkCountPerTransports(sampleNetworkCount(mNetworkAgentInfos)); 2723 builder.setConnectionDurationPerTransports(sampleConnectionDuration(mNetworkAgentInfos)); 2724 builder.setNetworkRequestCount(sampleNetworkRequestCount(mNetworkRequests.values())); 2725 builder.setNetworks(sampleNetworks(mNetworkAgentInfos)); 2726 return builder.build(); 2727 } 2728 2729 private static NetworkCountPerTransports sampleNetworkCount( 2730 @NonNull final ArraySet<NetworkAgentInfo> nais) { 2731 final SparseIntArray countPerTransports = new SparseIntArray(); 2732 for (final NetworkAgentInfo nai : nais) { 2733 int transports = (int) nai.networkCapabilities.getTransportTypesInternal(); 2734 countPerTransports.put(transports, 1 + countPerTransports.get(transports, 0)); 2735 } 2736 final NetworkCountPerTransports.Builder builder = NetworkCountPerTransports.newBuilder(); 2737 for (int i = countPerTransports.size() - 1; i >= 0; --i) { 2738 final NetworkCountForTransports.Builder c = NetworkCountForTransports.newBuilder(); 2739 c.setTransportTypes(countPerTransports.keyAt(i)); 2740 c.setNetworkCount(countPerTransports.valueAt(i)); 2741 builder.addNetworkCountForTransports(c); 2742 } 2743 return builder.build(); 2744 } 2745 2746 private static ConnectionDurationPerTransports sampleConnectionDuration( 2747 @NonNull final ArraySet<NetworkAgentInfo> nais) { 2748 final ConnectionDurationPerTransports.Builder builder = 2749 ConnectionDurationPerTransports.newBuilder(); 2750 for (final NetworkAgentInfo nai : nais) { 2751 final ConnectionDurationForTransports.Builder c = 2752 ConnectionDurationForTransports.newBuilder(); 2753 c.setTransportTypes((int) nai.networkCapabilities.getTransportTypesInternal()); 2754 final long durationMillis = SystemClock.elapsedRealtime() - nai.getConnectedTime(); 2755 final long millisPerSecond = TimeUnit.SECONDS.toMillis(1); 2756 // Add millisPerSecond/2 to round up or down to the nearest value 2757 c.setDurationSec((int) ((durationMillis + millisPerSecond / 2) / millisPerSecond)); 2758 builder.addConnectionDurationForTransports(c); 2759 } 2760 return builder.build(); 2761 } 2762 2763 private static NetworkRequestCount sampleNetworkRequestCount( 2764 @NonNull final Collection<NetworkRequestInfo> nris) { 2765 final NetworkRequestCount.Builder builder = NetworkRequestCount.newBuilder(); 2766 final SparseIntArray countPerType = new SparseIntArray(); 2767 for (final NetworkRequestInfo nri : nris) { 2768 final int type; 2769 if (Process.SYSTEM_UID == nri.mAsUid) { 2770 // The request is filed "as" the system, so it's the system on its own behalf. 2771 type = RequestType.RT_SYSTEM.getNumber(); 2772 } else if (Process.SYSTEM_UID == nri.mUid) { 2773 // The request is filed by the system as some other app, so it's the system on 2774 // behalf of an app. 2775 type = RequestType.RT_SYSTEM_ON_BEHALF_OF_APP.getNumber(); 2776 } else { 2777 // Not the system, so it's an app requesting on its own behalf. 2778 type = RequestType.RT_APP.getNumber(); 2779 } 2780 countPerType.put(type, countPerType.get(type, 0) + 1); 2781 } 2782 for (int i = countPerType.size() - 1; i >= 0; --i) { 2783 final RequestCountForType.Builder r = RequestCountForType.newBuilder(); 2784 r.setRequestType(RequestType.forNumber(countPerType.keyAt(i))); 2785 r.setRequestCount(countPerType.valueAt(i)); 2786 builder.addRequestCountForType(r); 2787 } 2788 return builder.build(); 2789 } 2790 2791 private static NetworkList sampleNetworks(@NonNull final ArraySet<NetworkAgentInfo> nais) { 2792 final NetworkList.Builder builder = NetworkList.newBuilder(); 2793 for (final NetworkAgentInfo nai : nais) { 2794 final NetworkCapabilities nc = nai.networkCapabilities; 2795 final NetworkDescription.Builder d = NetworkDescription.newBuilder(); 2796 d.setTransportTypes((int) nc.getTransportTypesInternal()); 2797 final MeteredState meteredState; 2798 if (nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)) { 2799 meteredState = MeteredState.METERED_TEMPORARILY_UNMETERED; 2800 } else if (nc.hasCapability(NET_CAPABILITY_NOT_METERED)) { 2801 meteredState = MeteredState.METERED_NO; 2802 } else { 2803 meteredState = MeteredState.METERED_YES; 2804 } 2805 d.setMeteredState(meteredState); 2806 final ValidatedState validatedState; 2807 if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { 2808 validatedState = ValidatedState.VS_PORTAL; 2809 } else if (nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) { 2810 validatedState = ValidatedState.VS_PARTIAL; 2811 } else if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) { 2812 validatedState = ValidatedState.VS_VALID; 2813 } else { 2814 validatedState = ValidatedState.VS_INVALID; 2815 } 2816 d.setValidatedState(validatedState); 2817 d.setScorePolicies(nai.getScore().getPoliciesInternal()); 2818 d.setCapabilities(nc.getCapabilitiesInternal()); 2819 d.setEnterpriseId(nc.getEnterpriseIdsInternal()); 2820 builder.addNetworkDescription(d); 2821 } 2822 return builder.build(); 2823 } 2824 2825 @Override 2826 public boolean isNetworkSupported(int networkType) { 2827 enforceAccessPermission(); 2828 return mLegacyTypeTracker.isTypeSupported(networkType); 2829 } 2830 2831 /** 2832 * Return LinkProperties for the active (i.e., connected) default 2833 * network interface for the calling uid. 2834 * @return the ip properties for the active network, or {@code null} if 2835 * none is active 2836 */ 2837 @Override 2838 public LinkProperties getActiveLinkProperties() { 2839 enforceAccessPermission(); 2840 final int uid = mDeps.getCallingUid(); 2841 NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2842 if (nai == null) return null; 2843 return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties, 2844 Binder.getCallingPid(), uid); 2845 } 2846 2847 @Override 2848 public LinkProperties getLinkPropertiesForType(int networkType) { 2849 enforceAccessPermission(); 2850 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2851 final LinkProperties lp = getLinkProperties(nai); 2852 if (lp == null) return null; 2853 return linkPropertiesRestrictedForCallerPermissions( 2854 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2855 } 2856 2857 // TODO - this should be ALL networks 2858 @Override 2859 public LinkProperties getLinkProperties(Network network) { 2860 enforceAccessPermission(); 2861 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network)); 2862 if (lp == null) return null; 2863 return linkPropertiesRestrictedForCallerPermissions( 2864 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2865 } 2866 2867 @Nullable 2868 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) { 2869 if (nai == null) { 2870 return null; 2871 } 2872 synchronized (nai) { 2873 return nai.linkProperties; 2874 } 2875 } 2876 2877 @Override 2878 @Nullable 2879 public LinkProperties getRedactedLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid, 2880 @NonNull String packageName, @Nullable String callingAttributionTag) { 2881 Objects.requireNonNull(packageName); 2882 Objects.requireNonNull(lp); 2883 enforceNetworkStackOrSettingsPermission(); 2884 if (!hasAccessPermission(-1 /* pid */, uid)) { 2885 return null; 2886 } 2887 return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid); 2888 } 2889 2890 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) { 2891 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 2892 } 2893 2894 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 2895 if (nai == null) return null; 2896 synchronized (nai) { 2897 return networkCapabilitiesRestrictedForCallerPermissions( 2898 nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid()); 2899 } 2900 } 2901 2902 @Override 2903 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName, 2904 @Nullable String callingAttributionTag) { 2905 mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName); 2906 enforceAccessPermission(); 2907 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2908 getNetworkCapabilitiesInternal(network), 2909 false /* includeLocationSensitiveInfo */, 2910 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag); 2911 } 2912 2913 @Override 2914 public NetworkCapabilities getRedactedNetworkCapabilitiesForPackage( 2915 @NonNull NetworkCapabilities nc, int uid, @NonNull String packageName, 2916 @Nullable String callingAttributionTag) { 2917 Objects.requireNonNull(nc); 2918 Objects.requireNonNull(packageName); 2919 enforceNetworkStackOrSettingsPermission(); 2920 if (!hasAccessPermission(-1 /* pid */, uid)) { 2921 return null; 2922 } 2923 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2924 networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid), 2925 true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName, 2926 callingAttributionTag); 2927 } 2928 2929 private void redactUnderlyingNetworksForCapabilities(NetworkCapabilities nc, int pid, int uid) { 2930 if (nc.getUnderlyingNetworks() != null 2931 && !hasNetworkFactoryOrSettingsPermission(pid, uid)) { 2932 nc.setUnderlyingNetworks(null); 2933 } 2934 } 2935 2936 private boolean canSeeAllowedUids(final int pid, final int uid, final int netOwnerUid) { 2937 return Process.SYSTEM_UID == uid 2938 || netOwnerUid == uid 2939 || hasAnyPermissionOf(mContext, pid, uid, 2940 android.Manifest.permission.NETWORK_FACTORY); 2941 } 2942 2943 @VisibleForTesting 2944 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( 2945 NetworkCapabilities nc, int callerPid, int callerUid) { 2946 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 2947 // this would be expensive (one more permission check every time any NC callback is 2948 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 2949 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 2950 // send the callback) it would crash the system server with NPE. 2951 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 2952 if (!hasSettingsPermission(callerPid, callerUid)) { 2953 newNc.setUids(null); 2954 newNc.setSSID(null); 2955 } 2956 if (newNc.getNetworkSpecifier() != null) { 2957 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); 2958 } 2959 if (!hasAnyPermissionOf(mContext, callerPid, callerUid, 2960 android.Manifest.permission.NETWORK_STACK, 2961 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) { 2962 newNc.setAdministratorUids(new int[0]); 2963 } 2964 if (!canSeeAllowedUids(callerPid, callerUid, newNc.getOwnerUid())) { 2965 newNc.setAllowedUids(new ArraySet<>()); 2966 } 2967 redactUnderlyingNetworksForCapabilities(newNc, callerPid, callerUid); 2968 2969 return newNc; 2970 } 2971 2972 /** 2973 * Wrapper used to cache the permission check results performed for the corresponding 2974 * app. This avoids performing multiple permission checks for different fields in 2975 * NetworkCapabilities. 2976 * Note: This wrapper does not support any sort of invalidation and thus must not be 2977 * persistent or long-lived. It may only be used for the time necessary to 2978 * compute the redactions required by one particular NetworkCallback or 2979 * synchronous call. 2980 */ 2981 private class RedactionPermissionChecker { 2982 private final int mCallingPid; 2983 private final int mCallingUid; 2984 @NonNull private final String mCallingPackageName; 2985 @Nullable private final String mCallingAttributionTag; 2986 2987 private Boolean mHasLocationPermission = null; 2988 private Boolean mHasLocalMacAddressPermission = null; 2989 private Boolean mHasSettingsPermission = null; 2990 2991 RedactionPermissionChecker(int callingPid, int callingUid, 2992 @NonNull String callingPackageName, @Nullable String callingAttributionTag) { 2993 mCallingPid = callingPid; 2994 mCallingUid = callingUid; 2995 mCallingPackageName = callingPackageName; 2996 mCallingAttributionTag = callingAttributionTag; 2997 } 2998 2999 private boolean hasLocationPermissionInternal() { 3000 final long token = Binder.clearCallingIdentity(); 3001 try { 3002 return mLocationPermissionChecker.checkLocationPermission( 3003 mCallingPackageName, mCallingAttributionTag, mCallingUid, 3004 null /* message */); 3005 } finally { 3006 Binder.restoreCallingIdentity(token); 3007 } 3008 } 3009 3010 /** 3011 * Returns whether the app holds location permission or not (might return cached result 3012 * if the permission was already checked before). 3013 */ 3014 public boolean hasLocationPermission() { 3015 if (mHasLocationPermission == null) { 3016 // If there is no cached result, perform the check now. 3017 mHasLocationPermission = hasLocationPermissionInternal(); 3018 } 3019 return mHasLocationPermission; 3020 } 3021 3022 /** 3023 * Returns whether the app holds local mac address permission or not (might return cached 3024 * result if the permission was already checked before). 3025 */ 3026 @CheckResult 3027 public boolean hasLocalMacAddressPermission() { 3028 if (mHasLocalMacAddressPermission == null) { 3029 // If there is no cached result, perform the check now. 3030 mHasLocalMacAddressPermission = ConnectivityService.this 3031 .hasLocalMacAddressPermission(mCallingPid, mCallingUid); 3032 } 3033 return mHasLocalMacAddressPermission; 3034 } 3035 3036 /** 3037 * Returns whether the app holds settings permission or not (might return cached 3038 * result if the permission was already checked before). 3039 */ 3040 @CheckResult 3041 public boolean hasSettingsPermission() { 3042 if (mHasSettingsPermission == null) { 3043 // If there is no cached result, perform the check now. 3044 mHasSettingsPermission = 3045 ConnectivityService.this.hasSettingsPermission(mCallingPid, mCallingUid); 3046 } 3047 return mHasSettingsPermission; 3048 } 3049 } 3050 3051 private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions, 3052 @NetworkCapabilities.NetCapability long redaction) { 3053 return (redactions & redaction) != 0; 3054 } 3055 3056 /** 3057 * Use the provided |applicableRedactions| to check the receiving app's 3058 * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask 3059 * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities 3060 * before being sent to the corresponding app. 3061 */ 3062 private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions( 3063 @NetworkCapabilities.RedactionType long applicableRedactions, 3064 @NonNull RedactionPermissionChecker redactionPermissionChecker, 3065 boolean includeLocationSensitiveInfo) { 3066 long redactions = applicableRedactions; 3067 if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) { 3068 if (includeLocationSensitiveInfo 3069 && redactionPermissionChecker.hasLocationPermission()) { 3070 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION; 3071 } 3072 } 3073 if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) { 3074 if (redactionPermissionChecker.hasLocalMacAddressPermission()) { 3075 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS; 3076 } 3077 } 3078 if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) { 3079 if (redactionPermissionChecker.hasSettingsPermission()) { 3080 redactions &= ~REDACT_FOR_NETWORK_SETTINGS; 3081 } 3082 } 3083 return redactions; 3084 } 3085 3086 @VisibleForTesting 3087 @Nullable 3088 NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled( 3089 @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, 3090 int callingPid, int callingUid, @NonNull String callingPkgName, 3091 @Nullable String callingAttributionTag) { 3092 if (nc == null) { 3093 return null; 3094 } 3095 // Avoid doing location permission check if the transport info has no location sensitive 3096 // data. 3097 final RedactionPermissionChecker redactionPermissionChecker = 3098 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName, 3099 callingAttributionTag); 3100 final long redactions = retrieveRequiredRedactions( 3101 nc.getApplicableRedactions(), redactionPermissionChecker, 3102 includeLocationSensitiveInfo); 3103 final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions); 3104 // Reset owner uid if not destined for the owner app. 3105 // TODO : calling UID is redacted because apps should generally not know what UID is 3106 // bringing up the VPN, but this should not apply to some very privileged apps like settings 3107 if (callingUid != nc.getOwnerUid()) { 3108 newNc.setOwnerUid(INVALID_UID); 3109 return newNc; 3110 } 3111 // Allow VPNs to see ownership of their own VPN networks - not location sensitive. 3112 if (nc.hasTransport(TRANSPORT_VPN)) { 3113 // Owner UIDs already checked above. No need to re-check. 3114 return newNc; 3115 } 3116 // If the calling does not want location sensitive data & target SDK >= S, then mask info. 3117 // Else include the owner UID iff the calling has location permission to provide backwards 3118 // compatibility for older apps. 3119 if (!includeLocationSensitiveInfo 3120 && isTargetSdkAtleast( 3121 Build.VERSION_CODES.S, callingUid, callingPkgName)) { 3122 newNc.setOwnerUid(INVALID_UID); 3123 return newNc; 3124 } 3125 // Reset owner uid if the app has no location permission. 3126 if (!redactionPermissionChecker.hasLocationPermission()) { 3127 newNc.setOwnerUid(INVALID_UID); 3128 } 3129 return newNc; 3130 } 3131 3132 @NonNull 3133 private LinkProperties linkPropertiesRestrictedForCallerPermissions( 3134 LinkProperties lp, int callerPid, int callerUid) { 3135 if (lp == null) return new LinkProperties(); 3136 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 3137 // this would be expensive (one more permission check every time any LP callback is 3138 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 3139 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 3140 // send the callback) it would crash the system server with NPE. 3141 3142 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls. 3143 final boolean needsSanitization = 3144 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null); 3145 if (!needsSanitization) { 3146 return new LinkProperties(lp); 3147 } 3148 3149 if (hasSettingsPermission(callerPid, callerUid)) { 3150 return new LinkProperties(lp, true /* parcelSensitiveFields */); 3151 } 3152 3153 final LinkProperties newLp = new LinkProperties(lp); 3154 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the 3155 // object gets parceled. 3156 newLp.setCaptivePortalApiUrl(null); 3157 newLp.setCaptivePortalData(null); 3158 return newLp; 3159 } 3160 3161 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, 3162 int callerUid, String callerPackageName) { 3163 // There is no need to track the effective UID of the request here. If the caller 3164 // lacks the settings permission, the effective UID is the same as the calling ID. 3165 if (!hasSettingsPermission()) { 3166 // Unprivileged apps can only pass in null or their own UID. 3167 if (nc.getUids() == null) { 3168 // If the caller passes in null, the callback will also match networks that do not 3169 // apply to its UID, similarly to what it would see if it called getAllNetworks. 3170 // In this case, redact everything in the request immediately. This ensures that the 3171 // app is not able to get any redacted information by filing an unredacted request 3172 // and observing whether the request matches something. 3173 if (nc.getNetworkSpecifier() != null) { 3174 nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact()); 3175 } 3176 } else { 3177 nc.setSingleUid(callerUid); 3178 } 3179 } 3180 nc.setRequestorUidAndPackageName(callerUid, callerPackageName); 3181 nc.setAdministratorUids(new int[0]); 3182 3183 // Clear owner UID; this can never come from an app. 3184 nc.setOwnerUid(INVALID_UID); 3185 } 3186 3187 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) { 3188 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) { 3189 nc.addCapability(NET_CAPABILITY_FOREGROUND); 3190 } 3191 } 3192 3193 private void maybeDisableLocalNetworkMatching(NetworkCapabilities nc, int callingUid) { 3194 // If disabled, NetworkRequest cannot match non-thread local networks even if 3195 // specified explicitly. Compat change is enabled by default on apps targeting B+. 3196 // Agent should not be visible on U- even if it's rolled out. 3197 nc.setMatchNonThreadLocalNetworks(mDeps.isAtLeastV() && mDeps.isChangeEnabled( 3198 ENABLE_MATCH_NON_THREAD_LOCAL_NETWORKS, callingUid)); 3199 if (mDeps.isChangeEnabled(ENABLE_MATCH_LOCAL_NETWORK, callingUid)) { 3200 return; 3201 } 3202 // If NET_CAPABILITY_LOCAL_NETWORK is not added to capability, request should not be 3203 // satisfied by local networks. 3204 if (!nc.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)) { 3205 nc.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK); 3206 } 3207 } 3208 3209 private void restrictRequestNetworkCapabilitiesForCaller(NetworkCapabilities nc, 3210 int callingUid, String callerPackageName) { 3211 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callerPackageName); 3212 maybeDisableLocalNetworkMatching(nc, callingUid); 3213 } 3214 3215 @Override 3216 public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() { 3217 enforceAccessPermission(); 3218 final int callerUid = Binder.getCallingUid(); 3219 final long token = Binder.clearCallingIdentity(); 3220 try { 3221 return mPolicyManager.getRestrictBackgroundStatus(callerUid); 3222 } finally { 3223 Binder.restoreCallingIdentity(token); 3224 } 3225 } 3226 3227 // TODO: Consider delete this function or turn it into a no-op method. 3228 @Override 3229 public NetworkState[] getAllNetworkState() { 3230 // This contains IMSI details, so make sure the caller is privileged. 3231 enforceNetworkStackPermission(mContext); 3232 3233 final ArrayList<NetworkState> result = new ArrayList<>(); 3234 for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) { 3235 // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the 3236 // NetworkAgentInfo. 3237 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork()); 3238 if (nai != null && nai.networkInfo.isConnected()) { 3239 result.add(new NetworkState(new NetworkInfo(nai.networkInfo), 3240 snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(), 3241 snapshot.getNetwork(), snapshot.getSubscriberId())); 3242 } 3243 } 3244 return result.toArray(new NetworkState[0]); 3245 } 3246 3247 @Override 3248 @NonNull 3249 public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() { 3250 // This contains IMSI details, so make sure the caller is privileged. 3251 enforceNetworkStackOrSettingsPermission(); 3252 3253 final ArrayList<NetworkStateSnapshot> result = new ArrayList<>(); 3254 for (Network network : getAllNetworks()) { 3255 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3256 final boolean includeNetwork = (nai != null) && nai.isCreated(); 3257 if (includeNetwork) { 3258 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the 3259 // NetworkCapabilities, which may contain UIDs of apps to which the 3260 // network applies. Should the UIDs be cleared so as not to leak or 3261 // interfere ? 3262 result.add(nai.getNetworkStateSnapshot()); 3263 } 3264 } 3265 return result; 3266 } 3267 3268 @Override 3269 public boolean isActiveNetworkMetered() { 3270 enforceAccessPermission(); 3271 3272 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork()); 3273 if (caps != null) { 3274 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 3275 } else { 3276 // Always return the most conservative value 3277 return true; 3278 } 3279 } 3280 3281 /** 3282 * Ensures that the system cannot call a particular method. 3283 */ 3284 private boolean disallowedBecauseSystemCaller() { 3285 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling 3286 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost 3287 // for devices launched with Q and above. However, existing devices upgrading to Q and 3288 // above must continued to be supported for few more releases. 3289 if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt( 3290 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) { 3291 log("This method exists only for app backwards compatibility" 3292 + " and must not be called by system services."); 3293 return true; 3294 } 3295 return false; 3296 } 3297 3298 /** 3299 * Ensure that a network route exists to deliver traffic to the specified 3300 * host via the specified network interface. 3301 * @param networkType the type of the network over which traffic to the 3302 * specified host is to be routed 3303 * @param hostAddress the IP address of the host to which the route is 3304 * desired 3305 * @return {@code true} on success, {@code false} on failure 3306 */ 3307 @Override 3308 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, 3309 String callingPackageName, String callingAttributionTag) { 3310 if (disallowedBecauseSystemCaller()) { 3311 return false; 3312 } 3313 PermissionUtils.enforcePackageNameMatchesUid( 3314 mContext, mDeps.getCallingUid(), callingPackageName); 3315 enforceChangePermission(callingPackageName, callingAttributionTag); 3316 if (mProtectedNetworks.contains(networkType)) { 3317 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 3318 } 3319 3320 InetAddress addr; 3321 try { 3322 addr = InetAddress.getByAddress(hostAddress); 3323 } catch (UnknownHostException e) { 3324 if (DBG) log("requestRouteToHostAddress got " + e); 3325 return false; 3326 } 3327 3328 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 3329 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 3330 return false; 3331 } 3332 3333 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 3334 if (nai == null) { 3335 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 3336 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 3337 } else { 3338 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 3339 } 3340 return false; 3341 } 3342 3343 DetailedState netState; 3344 synchronized (nai) { 3345 netState = nai.networkInfo.getDetailedState(); 3346 } 3347 3348 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 3349 if (VDBG) { 3350 log("requestRouteToHostAddress on down network " 3351 + "(" + networkType + ") - dropped" 3352 + " netState=" + netState); 3353 } 3354 return false; 3355 } 3356 3357 final int uid = mDeps.getCallingUid(); 3358 final long token = Binder.clearCallingIdentity(); 3359 try { 3360 LinkProperties lp; 3361 int netId; 3362 synchronized (nai) { 3363 lp = nai.linkProperties; 3364 netId = nai.network.getNetId(); 3365 } 3366 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 3367 if (DBG) { 3368 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok); 3369 } 3370 return ok; 3371 } finally { 3372 Binder.restoreCallingIdentity(token); 3373 } 3374 } 3375 3376 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 3377 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 3378 if (bestRoute == null) { 3379 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 3380 } else { 3381 String iface = bestRoute.getInterface(); 3382 if (bestRoute.getGateway().equals(addr)) { 3383 // if there is no better route, add the implied hostroute for our gateway 3384 bestRoute = RouteInfo.makeHostRoute(addr, iface); 3385 } else { 3386 // if we will connect to this through another route, add a direct route 3387 // to it's gateway 3388 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 3389 } 3390 } 3391 if (DBG) log("Adding legacy route " + bestRoute + 3392 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 3393 3394 final String dst = bestRoute.getDestinationLinkAddress().toString(); 3395 final String nextHop = bestRoute.hasGateway() 3396 ? bestRoute.getGateway().getHostAddress() : ""; 3397 try { 3398 mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid); 3399 } catch (RemoteException | ServiceSpecificException e) { 3400 if (DBG) loge("Exception trying to add a route: " + e); 3401 return false; 3402 } 3403 return true; 3404 } 3405 3406 class DnsResolverUnsolicitedEventCallback extends 3407 IDnsResolverUnsolicitedEventListener.Stub { 3408 @Override 3409 public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { 3410 try { 3411 mHandler.sendMessage(mHandler.obtainMessage( 3412 EVENT_PRIVATE_DNS_VALIDATION_UPDATE, 3413 new PrivateDnsValidationUpdate(event.netId, 3414 InetAddresses.parseNumericAddress(event.ipAddress), 3415 event.hostname, event.validation))); 3416 } catch (IllegalArgumentException e) { 3417 loge("Error parsing ip address in validation event"); 3418 } 3419 } 3420 3421 @Override 3422 public void onDnsHealthEvent(final DnsHealthEventParcel event) { 3423 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); 3424 // Netd event only allow registrants from system. Each NetworkMonitor thread is under 3425 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd 3426 // event callback for certain nai. e.g. cellular. Register here to pass to 3427 // NetworkMonitor instead. 3428 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allows one 3429 // callback from each caller type. Need to re-factor NetdEventListenerService to allow 3430 // multiple NetworkMonitor registrants. 3431 if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { 3432 nai.networkMonitor().notifyDnsResponse(event.healthResult); 3433 } 3434 } 3435 3436 @Override 3437 public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { 3438 mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, 3439 event.prefixAddress, event.prefixLength)); 3440 } 3441 3442 @Override 3443 public int getInterfaceVersion() { 3444 return this.VERSION; 3445 } 3446 3447 @Override 3448 public String getInterfaceHash() { 3449 return this.HASH; 3450 } 3451 } 3452 3453 @VisibleForTesting 3454 protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = 3455 new DnsResolverUnsolicitedEventCallback(); 3456 3457 private void registerDnsResolverUnsolicitedEventListener() { 3458 try { 3459 mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); 3460 } catch (Exception e) { 3461 loge("Error registering DnsResolver unsolicited event callback: " + e); 3462 } 3463 } 3464 3465 private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() { 3466 @Override 3467 public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 3468 if (shouldTrackUidsForBlockedStatusCallbacks()) { 3469 Log.wtf(TAG, "Received unexpected NetworkPolicy callback"); 3470 return; 3471 } 3472 mHandler.sendMessage(mHandler.obtainMessage( 3473 EVENT_BLOCKED_REASONS_CHANGED, 3474 List.of(new Pair<>(uid, blockedReasons)))); 3475 } 3476 }; 3477 3478 private boolean shouldTrackUidsForBlockedStatusCallbacks() { 3479 return mDeps.isAtLeastV(); 3480 } 3481 3482 @VisibleForTesting 3483 public void handleBlockedReasonsChanged(List<Pair<Integer, Integer>> reasonsList) { 3484 for (Pair<Integer, Integer> reasons: reasonsList) { 3485 final int uid = reasons.first; 3486 final int blockedReasons = reasons.second; 3487 if (shouldTrackUidsForBlockedStatusCallbacks()) { 3488 synchronized (mBlockedStatusTrackingUids) { 3489 if (mBlockedStatusTrackingUids.get(uid) == 0) { 3490 // This uid is not tracked anymore. 3491 // This can happen if the network request is unregistered while 3492 // EVENT_BLOCKED_REASONS_CHANGED is posted but not processed yet. 3493 continue; 3494 } 3495 } 3496 } 3497 maybeNotifyNetworkBlockedForNewState(uid, blockedReasons); 3498 setUidBlockedReasons(uid, blockedReasons); 3499 } 3500 } 3501 3502 static final class UidFrozenStateChangedArgs { 3503 final int[] mUids; 3504 final int[] mFrozenStates; 3505 3506 UidFrozenStateChangedArgs(int[] uids, int[] frozenStates) { 3507 mUids = uids; 3508 mFrozenStates = frozenStates; 3509 } 3510 } 3511 3512 /** 3513 * Check if the cell network is idle. 3514 * @return true if the cell network state is idle 3515 * false if the cell network state is active or unknown 3516 */ 3517 private boolean isCellNetworkIdle() { 3518 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 3519 if (defaultNai == null 3520 || !defaultNai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { 3521 // mNetworkActivityTracker only tracks the activity of the default network. So if the 3522 // cell network is not the default network, cell network state is unknown. 3523 // TODO(b/279380356): Track cell network state when the cell is not the default network 3524 return false; 3525 } 3526 3527 return !mNetworkActivityTracker.isDefaultNetworkActive(); 3528 } 3529 3530 private boolean shouldTrackFirewallDestroySocketReasons() { 3531 return mDeps.isAtLeastV(); 3532 } 3533 3534 private void updateDestroySocketReasons(final int uid, final int reason, 3535 final boolean addReason) { 3536 final int destroyReasons = mDestroySocketPendingUids.get(uid, DESTROY_SOCKET_REASON_NONE); 3537 if (addReason) { 3538 mDestroySocketPendingUids.put(uid, destroyReasons | reason); 3539 } else { 3540 final int newDestroyReasons = destroyReasons & ~reason; 3541 if (newDestroyReasons == DESTROY_SOCKET_REASON_NONE) { 3542 mDestroySocketPendingUids.delete(uid); 3543 } else { 3544 mDestroySocketPendingUids.put(uid, newDestroyReasons); 3545 } 3546 } 3547 } 3548 3549 private void handleFrozenUids(int[] uids, int[] frozenStates) { 3550 ensureRunningOnConnectivityServiceThread(); 3551 handleDestroyFrozenSockets(uids, frozenStates); 3552 handleFreezeNetworkCallbacks(uids, frozenStates); 3553 } 3554 3555 private void handleDestroyFrozenSockets(int[] uids, int[] frozenStates) { 3556 if (!mDestroyFrozenSockets) { 3557 return; 3558 } 3559 for (int i = 0; i < uids.length; i++) { 3560 final int uid = uids[i]; 3561 final boolean addReason = frozenStates[i] == UID_FROZEN_STATE_FROZEN; 3562 updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FROZEN, addReason); 3563 } 3564 3565 if (!mDelayDestroySockets || !isCellNetworkIdle()) { 3566 destroyPendingSockets(); 3567 } 3568 } 3569 3570 private void handleFreezeNetworkCallbacks(int[] uids, int[] frozenStates) { 3571 if (!mQueueCallbacksForFrozenApps) { 3572 return; 3573 } 3574 for (int i = 0; i < uids.length; i++) { 3575 final int uid = uids[i]; 3576 // These counters may be modified on different threads, but using them here is fine 3577 // because this is only an optimization where wrong behavior would only happen if they 3578 // are zero even though there is a request registered. This is not possible as they are 3579 // always incremented before posting messages to register, and decremented on the 3580 // handler thread when unregistering. 3581 if (mSystemNetworkRequestCounter.get(uid) == 0 3582 && mNetworkRequestCounter.get(uid) == 0) { 3583 // Avoid iterating requests if there isn't any. The counters only track app requests 3584 // and not internal requests (for example always-on requests which do not have a 3585 // mMessenger), so it does not completely match the content of mRequests. This is OK 3586 // as only app requests need to be frozen. 3587 continue; 3588 } 3589 3590 if (frozenStates[i] == UID_FROZEN_STATE_FROZEN) { 3591 freezeNetworkCallbacksForUid(uid); 3592 } else { 3593 unfreezeNetworkCallbacksForUid(uid); 3594 } 3595 } 3596 } 3597 3598 /** 3599 * Suspend callbacks for a UID that was just frozen. 3600 * 3601 * <p>Note that it is not possible for a process to be frozen during a blocking binder call 3602 * (see CachedAppOptimizer.freezeBinder), and IConnectivityManager callback registrations are 3603 * blocking binder calls, so no callback can be registered while the UID is frozen. This means 3604 * it is not necessary to check frozen state on new callback registrations, and calling this 3605 * method when a UID is newly frozen is sufficient. 3606 * 3607 * <p>If it ever becomes possible for a process to be frozen during a blocking binder call, 3608 * ConnectivityService will need to handle freezing callbacks that reach ConnectivityService 3609 * after the app was frozen when being registered. 3610 */ 3611 private void freezeNetworkCallbacksForUid(int uid) { 3612 if (DDBG) Log.d(TAG, "Freezing callbacks for UID " + uid); 3613 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 3614 if (nri.mUid != uid) continue; 3615 // mNetworkRequests can have duplicate values for multilayer requests, but calling 3616 // onFrozen multiple times is fine. 3617 // If freezeNetworkCallbacksForUid was called multiple times in a raw for a frozen UID 3618 // (which would be incorrect), this would also handle it gracefully. 3619 nri.onFrozen(); 3620 } 3621 } 3622 3623 private void unfreezeNetworkCallbacksForUid(int uid) { 3624 // This sends all callbacks for one NetworkRequest at a time, which may not be the 3625 // same order they were queued in, but different network requests use different 3626 // binder objects, so the relative order of their callbacks is not guaranteed. 3627 // If callbacks are not queued, callbacks from different binder objects may be 3628 // posted on different threads when the process is unfrozen, so even if they were 3629 // called a long time apart while the process was frozen, they may still appear in 3630 // different order when unfreezing it. 3631 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 3632 if (nri.mUid != uid) continue; 3633 nri.sendQueuedCallbacks(); 3634 } 3635 } 3636 3637 private void handleUpdateFirewallDestroySocketReasons( 3638 List<Pair<Integer, Integer>> reasonsList) { 3639 if (!shouldTrackFirewallDestroySocketReasons()) { 3640 Log.wtf(TAG, "handleUpdateFirewallDestroySocketReasons is called unexpectedly"); 3641 return; 3642 } 3643 ensureRunningOnConnectivityServiceThread(); 3644 3645 for (Pair<Integer, Integer> uidSocketDestroyReasons: reasonsList) { 3646 final int uid = uidSocketDestroyReasons.first; 3647 final int reasons = uidSocketDestroyReasons.second; 3648 final boolean destroyByFirewallBackground = 3649 (reasons & DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND) 3650 != DESTROY_SOCKET_REASON_NONE; 3651 updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND, 3652 destroyByFirewallBackground); 3653 } 3654 3655 if (!mDelayDestroySockets || !isCellNetworkIdle()) { 3656 destroyPendingSockets(); 3657 } 3658 } 3659 3660 private void handleClearFirewallDestroySocketReasons(final int reason) { 3661 if (!shouldTrackFirewallDestroySocketReasons()) { 3662 Log.wtf(TAG, "handleClearFirewallDestroySocketReasons is called uexpectedly"); 3663 return; 3664 } 3665 ensureRunningOnConnectivityServiceThread(); 3666 3667 // Unset reason from all pending uids 3668 for (int i = mDestroySocketPendingUids.size() - 1; i >= 0; i--) { 3669 final int uid = mDestroySocketPendingUids.keyAt(i); 3670 updateDestroySocketReasons(uid, reason, false /* addReason */); 3671 } 3672 } 3673 3674 private void destroyPendingSockets() { 3675 ensureRunningOnConnectivityServiceThread(); 3676 if (mDestroySocketPendingUids.size() == 0) { 3677 return; 3678 } 3679 3680 Set<Integer> uids = new ArraySet<>(); 3681 for (int i = 0; i < mDestroySocketPendingUids.size(); i++) { 3682 uids.add(mDestroySocketPendingUids.keyAt(i)); 3683 } 3684 3685 try { 3686 mDeps.destroyLiveTcpSocketsByOwnerUids(uids); 3687 } catch (SocketException | InterruptedIOException | ErrnoException e) { 3688 loge("Failed to destroy sockets: " + e); 3689 } 3690 mDestroySocketPendingUids.clear(); 3691 } 3692 3693 private void handleReportNetworkActivity(final NetworkActivityParams params) { 3694 mNetworkActivityTracker.handleReportNetworkActivity(params); 3695 3696 final boolean isCellNetworkActivity; 3697 if (mTrackMultiNetworkActivities) { 3698 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(params.label); 3699 // nai could be null if netd receives a netlink message and calls the network 3700 // activity change callback after the network is unregistered from ConnectivityService. 3701 isCellNetworkActivity = nai != null 3702 && nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3703 } else { 3704 isCellNetworkActivity = params.label == TRANSPORT_CELLULAR; 3705 } 3706 3707 if (mDelayDestroySockets && params.isActive && isCellNetworkActivity) { 3708 destroyPendingSockets(); 3709 } 3710 } 3711 3712 /** 3713 * If the cellular network is no longer the default network, destroy pending sockets. 3714 * 3715 * @param newNetwork new default network 3716 * @param oldNetwork old default network 3717 */ 3718 private void maybeDestroyPendingSockets(NetworkAgentInfo newNetwork, 3719 NetworkAgentInfo oldNetwork) { 3720 final boolean isOldNetworkCellular = oldNetwork != null 3721 && oldNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3722 final boolean isNewNetworkCellular = newNetwork != null 3723 && newNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR); 3724 3725 if (isOldNetworkCellular && !isNewNetworkCellular) { 3726 destroyPendingSockets(); 3727 } 3728 } 3729 3730 private void dumpDestroySockets(IndentingPrintWriter pw) { 3731 pw.println("DestroySockets:"); 3732 pw.increaseIndent(); 3733 pw.print("mDestroyFrozenSockets="); pw.println(mDestroyFrozenSockets); 3734 pw.print("mDelayDestroySockets="); pw.println(mDelayDestroySockets); 3735 pw.print("mDestroySocketPendingUids:"); 3736 pw.increaseIndent(); 3737 for (int i = 0; i < mDestroySocketPendingUids.size(); i++) { 3738 final int uid = mDestroySocketPendingUids.keyAt(i); 3739 final int reasons = mDestroySocketPendingUids.valueAt(i); 3740 pw.print(uid + ": reasons=" + reasons); 3741 } 3742 pw.decreaseIndent(); 3743 pw.decreaseIndent(); 3744 } 3745 3746 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 3747 private void dumpBpfProgramStatus(IndentingPrintWriter pw) { 3748 pw.println("Bpf Program Status:"); 3749 pw.increaseIndent(); 3750 try { 3751 pw.print("CGROUP_INET_INGRESS: "); 3752 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS)); 3753 pw.print("CGROUP_INET_EGRESS: "); 3754 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS)); 3755 3756 pw.print("CGROUP_INET_SOCK_CREATE: "); 3757 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE)); 3758 3759 pw.print("CGROUP_INET4_BIND: "); 3760 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND)); 3761 pw.print("CGROUP_INET6_BIND: "); 3762 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND)); 3763 3764 pw.print("CGROUP_INET4_CONNECT: "); 3765 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_CONNECT)); 3766 pw.print("CGROUP_INET6_CONNECT: "); 3767 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_CONNECT)); 3768 3769 pw.print("CGROUP_UDP4_SENDMSG: "); 3770 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_SENDMSG)); 3771 pw.print("CGROUP_UDP6_SENDMSG: "); 3772 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_SENDMSG)); 3773 3774 pw.print("CGROUP_UDP4_RECVMSG: "); 3775 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_RECVMSG)); 3776 pw.print("CGROUP_UDP6_RECVMSG: "); 3777 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_RECVMSG)); 3778 3779 pw.print("CGROUP_GETSOCKOPT: "); 3780 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_GETSOCKOPT)); 3781 pw.print("CGROUP_SETSOCKOPT: "); 3782 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_SETSOCKOPT)); 3783 3784 pw.print("CGROUP_INET_SOCK_RELEASE: "); 3785 pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_RELEASE)); 3786 } catch (IOException e) { 3787 pw.println(" IOException"); 3788 } 3789 pw.decreaseIndent(); 3790 } 3791 3792 @VisibleForTesting 3793 static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version"; 3794 3795 @VisibleForTesting 3796 public static final String ALLOW_SYSUI_CONNECTIVITY_REPORTS = 3797 "allow_sysui_connectivity_reports"; 3798 3799 public static final String ALLOW_SATALLITE_NETWORK_FALLBACK = 3800 "allow_satallite_network_fallback"; 3801 3802 private void enforceInternetPermission() { 3803 mContext.enforceCallingOrSelfPermission( 3804 android.Manifest.permission.INTERNET, 3805 "ConnectivityService"); 3806 } 3807 3808 private void enforceAccessPermission() { 3809 mContext.enforceCallingOrSelfPermission( 3810 android.Manifest.permission.ACCESS_NETWORK_STATE, 3811 "ConnectivityService"); 3812 } 3813 3814 @CheckResult 3815 private boolean hasAccessPermission(int pid, int uid) { 3816 return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid) 3817 == PERMISSION_GRANTED; 3818 } 3819 3820 /** 3821 * Performs a strict and comprehensive check of whether a calling package is allowed to 3822 * change the state of network, as the condition differs for pre-M, M+, and 3823 * privileged/preinstalled apps. The caller is expected to have either the 3824 * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these 3825 * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and 3826 * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal 3827 * permission and cannot be revoked. See http://b/23597341 3828 * 3829 * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation 3830 * of this app will be updated to the current time. 3831 */ 3832 private void enforceChangePermission(String callingPkg, String callingAttributionTag) { 3833 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) 3834 == PackageManager.PERMISSION_GRANTED) { 3835 return; 3836 } 3837 3838 if (callingPkg == null) { 3839 throw new SecurityException("Calling package name is null."); 3840 } 3841 3842 final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class); 3843 final int uid = mDeps.getCallingUid(); 3844 final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid, 3845 callingPkg, callingAttributionTag, null /* message */); 3846 3847 if (mode == AppOpsManager.MODE_ALLOWED) { 3848 return; 3849 } 3850 3851 if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission( 3852 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) { 3853 return; 3854 } 3855 3856 throw new SecurityException(callingPkg + " was not granted either of these permissions:" 3857 + android.Manifest.permission.CHANGE_NETWORK_STATE + "," 3858 + android.Manifest.permission.WRITE_SETTINGS + "."); 3859 } 3860 3861 private void enforceSettingsPermission() { 3862 enforceAnyPermissionOf(mContext, 3863 android.Manifest.permission.NETWORK_SETTINGS, 3864 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3865 } 3866 3867 private void enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission() { 3868 enforceAnyPermissionOf(mContext, 3869 android.Manifest.permission.NETWORK_SETTINGS, 3870 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3871 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3872 Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS); 3873 } 3874 3875 private void enforceNetworkFactoryPermission() { 3876 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3877 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3878 enforceAnyPermissionOf(mContext, 3879 android.Manifest.permission.NETWORK_FACTORY, 3880 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3881 } 3882 3883 private void enforceNetworkFactoryOrSettingsPermission() { 3884 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3885 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3886 enforceAnyPermissionOf(mContext, 3887 android.Manifest.permission.NETWORK_SETTINGS, 3888 android.Manifest.permission.NETWORK_FACTORY, 3889 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3890 } 3891 3892 private void enforceNetworkFactoryOrTestNetworksPermission() { 3893 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3894 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3895 enforceAnyPermissionOf(mContext, 3896 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3897 android.Manifest.permission.NETWORK_FACTORY, 3898 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3899 } 3900 3901 @CheckResult 3902 private boolean hasNetworkFactoryOrSettingsPermission(int pid, int uid) { 3903 return PERMISSION_GRANTED == mContext.checkPermission( 3904 android.Manifest.permission.NETWORK_FACTORY, pid, uid) 3905 || PERMISSION_GRANTED == mContext.checkPermission( 3906 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3907 || PERMISSION_GRANTED == mContext.checkPermission( 3908 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid) 3909 || UserHandle.getAppId(uid) == Process.BLUETOOTH_UID; 3910 } 3911 3912 @CheckResult 3913 private boolean hasSettingsPermission() { 3914 return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS, 3915 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3916 } 3917 3918 @CheckResult 3919 private boolean hasSettingsPermission(int pid, int uid) { 3920 return PERMISSION_GRANTED == mContext.checkPermission( 3921 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3922 || PERMISSION_GRANTED == mContext.checkPermission( 3923 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid); 3924 } 3925 3926 private void enforceNetworkStackOrSettingsPermission() { 3927 enforceNetworkStackPermissionOr(mContext, 3928 android.Manifest.permission.NETWORK_SETTINGS); 3929 } 3930 3931 private void enforceNetworkStackSettingsOrSetup() { 3932 enforceNetworkStackPermissionOr(mContext, 3933 android.Manifest.permission.NETWORK_SETTINGS, 3934 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3935 } 3936 3937 private void enforceAirplaneModePermission() { 3938 enforceNetworkStackPermissionOr(mContext, 3939 android.Manifest.permission.NETWORK_AIRPLANE_MODE, 3940 android.Manifest.permission.NETWORK_SETTINGS, 3941 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3942 } 3943 3944 private void enforceOemNetworkPreferencesPermission() { 3945 mContext.enforceCallingOrSelfPermission( 3946 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, 3947 "ConnectivityService"); 3948 } 3949 3950 private void enforceManageTestNetworksPermission() { 3951 mContext.enforceCallingOrSelfPermission( 3952 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3953 "ConnectivityService"); 3954 } 3955 3956 @CheckResult 3957 private boolean hasNetworkStackPermission() { 3958 return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_STACK, 3959 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3960 } 3961 3962 @CheckResult 3963 private boolean hasNetworkStackPermission(int pid, int uid) { 3964 return hasAnyPermissionOf(mContext, pid, uid, android.Manifest.permission.NETWORK_STACK, 3965 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3966 } 3967 3968 @CheckResult 3969 private boolean hasSystemBarServicePermission(int pid, int uid) { 3970 return hasAnyPermissionOf(mContext, pid, uid, 3971 android.Manifest.permission.STATUS_BAR_SERVICE); 3972 } 3973 3974 @CheckResult 3975 private boolean hasNetworkSignalStrengthWakeupPermission(int pid, int uid) { 3976 return hasAnyPermissionOf(mContext, pid, uid, 3977 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, 3978 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3979 android.Manifest.permission.NETWORK_SETTINGS); 3980 } 3981 3982 @CheckResult 3983 private boolean hasConnectivityRestrictedNetworksPermission(int callingUid, 3984 boolean checkUidsAllowedList) { 3985 if (hasAnyPermissionOf(mContext, 3986 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)) { 3987 return true; 3988 } 3989 3990 // fallback to ConnectivityInternalPermission 3991 // TODO: Remove this fallback check after all apps have declared 3992 // CONNECTIVITY_USE_RESTRICTED_NETWORKS. 3993 if (hasAnyPermissionOf(mContext, android.Manifest.permission.CONNECTIVITY_INTERNAL)) { 3994 return true; 3995 } 3996 3997 // Check whether uid is in allowed on restricted networks list. 3998 if (checkUidsAllowedList 3999 && mPermissionMonitor.isUidAllowedOnRestrictedNetworks(callingUid)) { 4000 return true; 4001 } 4002 return false; 4003 } 4004 4005 private void enforceConnectivityRestrictedNetworksPermission(boolean checkUidsAllowedList) { 4006 final int callingUid = mDeps.getCallingUid(); 4007 if (!hasConnectivityRestrictedNetworksPermission(callingUid, checkUidsAllowedList)) { 4008 throw new SecurityException("ConnectivityService: user " + callingUid 4009 + " has no permission to access restricted network."); 4010 } 4011 } 4012 4013 private void enforceKeepalivePermission() { 4014 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 4015 } 4016 4017 @CheckResult 4018 private boolean hasLocalMacAddressPermission(int pid, int uid) { 4019 return PERMISSION_GRANTED == mContext.checkPermission( 4020 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid); 4021 } 4022 4023 private void sendConnectedBroadcast(NetworkInfo info) { 4024 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 4025 } 4026 4027 private void sendInetConditionBroadcast(NetworkInfo info) { 4028 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 4029 } 4030 4031 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 4032 Intent intent = new Intent(bcastType); 4033 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 4034 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 4035 if (info.isFailover()) { 4036 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 4037 info.setFailover(false); 4038 } 4039 if (info.getReason() != null) { 4040 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 4041 } 4042 if (info.getExtraInfo() != null) { 4043 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 4044 info.getExtraInfo()); 4045 } 4046 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 4047 return intent; 4048 } 4049 4050 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 4051 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 4052 } 4053 4054 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 4055 @SuppressLint("NewApi") 4056 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 4057 @TargetApi(Build.VERSION_CODES.S) 4058 private void sendStickyBroadcast(Intent intent) { 4059 synchronized (this) { 4060 if (!mSystemReady 4061 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 4062 mInitialBroadcast = new Intent(intent); 4063 } 4064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4065 if (VDBG) { 4066 log("sendStickyBroadcast: action=" + intent.getAction()); 4067 } 4068 4069 Bundle options = null; 4070 final long ident = Binder.clearCallingIdentity(); 4071 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 4072 final NetworkInfo ni = intent.getParcelableExtra( 4073 ConnectivityManager.EXTRA_NETWORK_INFO); 4074 final BroadcastOptions opts = BroadcastOptions.makeBasic(); 4075 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 4076 applyMostRecentPolicyForConnectivityAction(opts, ni); 4077 options = opts.toBundle(); 4078 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 4079 } 4080 try { 4081 mUserAllContext.sendStickyBroadcast(intent, options); 4082 } finally { 4083 Binder.restoreCallingIdentity(ident); 4084 } 4085 } 4086 } 4087 4088 private void applyMostRecentPolicyForConnectivityAction(BroadcastOptions options, 4089 NetworkInfo info) { 4090 // Delivery group policy APIs are only available on U+. 4091 if (!mDeps.isAtLeastU()) return; 4092 4093 final BroadcastOptionsShim optsShim = mDeps.makeBroadcastOptionsShim(options); 4094 try { 4095 // This allows us to discard older broadcasts still waiting to be delivered 4096 // which have the same namespace and key. 4097 optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT); 4098 optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION, 4099 createDeliveryGroupKeyForConnectivityAction(info)); 4100 optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE); 4101 } catch (UnsupportedApiLevelException e) { 4102 Log.wtf(TAG, "Using unsupported API" + e); 4103 } 4104 } 4105 4106 @VisibleForTesting 4107 static String createDeliveryGroupKeyForConnectivityAction(NetworkInfo info) { 4108 final StringBuilder sb = new StringBuilder(); 4109 sb.append(info.getType()).append(DELIVERY_GROUP_KEY_DELIMITER); 4110 sb.append(info.getSubtype()).append(DELIVERY_GROUP_KEY_DELIMITER); 4111 sb.append(info.getExtraInfo()); 4112 return sb.toString(); 4113 } 4114 4115 /** 4116 * Called by SystemServer through ConnectivityManager when the system is ready. 4117 */ 4118 @Override 4119 public void systemReady() { 4120 if (mDeps.getCallingUid() != Process.SYSTEM_UID) { 4121 throw new SecurityException("Calling Uid is not system uid."); 4122 } 4123 systemReadyInternal(); 4124 } 4125 4126 /** 4127 * Called when ConnectivityService can initialize remaining components. 4128 */ 4129 @VisibleForTesting 4130 public void systemReadyInternal() { 4131 // Load flags after PackageManager is ready to query module version 4132 mFlags.loadFlags(mDeps, mContext); 4133 4134 // Since mApps in PermissionMonitor needs to be populated first to ensure that 4135 // listening network request which is sent by MultipathPolicyTracker won't be added 4136 // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must 4137 // be called after PermissionMonitor#startMonitoring(). 4138 // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the 4139 // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady() 4140 // to ensure the tracking will be initialized correctly. 4141 final ConditionVariable startMonitoringDone = new ConditionVariable(); 4142 mHandler.post(() -> { 4143 mPermissionMonitor.startMonitoring(); 4144 startMonitoringDone.open(); 4145 }); 4146 mProxyTracker.loadGlobalProxy(); 4147 registerDnsResolverUnsolicitedEventListener(); 4148 4149 synchronized (this) { 4150 mSystemReady = true; 4151 if (mInitialBroadcast != null) { 4152 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 4153 mInitialBroadcast = null; 4154 } 4155 } 4156 4157 // Create network requests for always-on networks. 4158 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); 4159 4160 // Update mobile data preference if necessary. 4161 // Note that updating can be skipped here if the list is empty only because no uid 4162 // rules are applied before system ready. Normally, the empty uid list means to clear 4163 // the uids rules on netd. 4164 if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) { 4165 updateMobileDataPreferredUids(); 4166 } 4167 4168 if (mSatelliteAccessController != null) { 4169 mSatelliteAccessController.start(); 4170 } 4171 4172 if (mCarrierPrivilegeAuthenticator != null) { 4173 mCarrierPrivilegeAuthenticator.start(); 4174 } 4175 4176 if (mL2capNetworkProvider != null) { 4177 mL2capNetworkProvider.start(); 4178 } 4179 4180 // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom 4181 if (mDeps.isAtLeastT()) { 4182 mBpfNetMaps.setPullAtomCallback(mContext); 4183 } 4184 ConnectivitySampleMetricsHelper.start(mContext, mHandler, 4185 CONNECTIVITY_STATE_SAMPLE, this::sampleConnectivityStateToStatsEvent); 4186 // Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't 4187 // have permission problem. While CV#block() is unbounded in time and can in principle block 4188 // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which 4189 // could have blocked forever too. 4190 startMonitoringDone.block(); 4191 } 4192 4193 /** 4194 * Start listening for default data network activity state changes. 4195 */ 4196 @Override 4197 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 4198 mNetworkActivityTracker.registerNetworkActivityListener(l); 4199 } 4200 4201 /** 4202 * Stop listening for default data network activity state changes. 4203 */ 4204 @Override 4205 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 4206 mNetworkActivityTracker.unregisterNetworkActivityListener(l); 4207 } 4208 4209 /** 4210 * Check whether the default network radio is currently active. 4211 */ 4212 @Override 4213 public boolean isDefaultNetworkActive() { 4214 return mNetworkActivityTracker.isDefaultNetworkActive(); 4215 } 4216 4217 /** 4218 * Reads the network specific MTU size from resources. 4219 * and set it on it's iface. 4220 */ 4221 private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 4222 final String iface = newLp.getInterfaceName(); 4223 final int mtu = newLp.getMtu(); 4224 if (mtu == 0) { 4225 // Silently ignore unset MTU value. 4226 return; 4227 } 4228 if (oldLp != null && newLp.isIdenticalMtu(oldLp) 4229 && TextUtils.equals(oldLp.getInterfaceName(), iface)) { 4230 if (VDBG) log("identical MTU and iface - not setting"); 4231 return; 4232 } 4233 // Cannot set MTU without interface name 4234 if (TextUtils.isEmpty(iface)) { 4235 if (VDBG) log("Setting MTU size with null iface."); 4236 return; 4237 } 4238 4239 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) { 4240 loge("Unexpected mtu value: " + mtu + ", " + iface); 4241 return; 4242 } 4243 4244 try { 4245 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); 4246 mNetd.interfaceSetMtu(iface, mtu); 4247 } catch (RemoteException | ServiceSpecificException e) { 4248 loge("exception in interfaceSetMtu()" + e); 4249 } 4250 } 4251 4252 @VisibleForTesting 4253 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 4254 4255 private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) { 4256 String[] values = null; 4257 if (tcpBufferSizes != null) { 4258 values = tcpBufferSizes.split(","); 4259 } 4260 4261 if (values == null || values.length != 6) { 4262 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 4263 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 4264 values = tcpBufferSizes.split(","); 4265 } 4266 4267 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 4268 4269 try { 4270 if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes); 4271 4272 String rmemValues = String.join(" ", values[0], values[1], values[2]); 4273 String wmemValues = String.join(" ", values[3], values[4], values[5]); 4274 mNetd.setTcpRWmemorySize(rmemValues, wmemValues); 4275 mCurrentTcpBufferSizes = tcpBufferSizes; 4276 } catch (RemoteException | ServiceSpecificException e) { 4277 loge("Can't set TCP buffer sizes:" + e); 4278 } 4279 } 4280 4281 @Override 4282 public int getRestoreDefaultNetworkDelay(int networkType) { 4283 String restoreDefaultNetworkDelayStr = mSystemProperties.get( 4284 NETWORK_RESTORE_DELAY_PROP_NAME); 4285 if(restoreDefaultNetworkDelayStr != null && 4286 restoreDefaultNetworkDelayStr.length() != 0) { 4287 try { 4288 return Integer.parseInt(restoreDefaultNetworkDelayStr); 4289 } catch (NumberFormatException e) { 4290 } 4291 } 4292 // if the system property isn't set, use the value for the apn type 4293 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 4294 4295 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 4296 ret = mLegacyTypeTracker.getRestoreTimerForType(networkType); 4297 } 4298 return ret; 4299 } 4300 4301 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 4302 final List<NetworkDiagnostics> netDiags = new ArrayList<>(); 4303 final long DIAG_TIME_MS = 5000; 4304 for (NetworkAgentInfo nai : networksSortedById()) { 4305 PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network); 4306 // Start gathering diagnostic information. 4307 netDiags.add(new NetworkDiagnostics( 4308 nai.network, 4309 new LinkProperties(nai.linkProperties), // Must be a copy. 4310 privateDnsCfg, 4311 DIAG_TIME_MS)); 4312 } 4313 4314 for (NetworkDiagnostics netDiag : netDiags) { 4315 pw.println(); 4316 netDiag.waitForMeasurements(); 4317 netDiag.dump(pw); 4318 } 4319 } 4320 4321 @Override 4322 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, 4323 @Nullable String[] args) { 4324 if (!hasDumpPermission(mContext, TAG, writer)) return; 4325 4326 mPriorityDumper.dump(fd, writer, args); 4327 } 4328 4329 @CheckResult 4330 private boolean hasDumpPermission(Context context, String tag, PrintWriter pw) { 4331 if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4332 != PackageManager.PERMISSION_GRANTED) { 4333 pw.println("Permission Denial: can't dump " + tag + " from from pid=" 4334 + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid() 4335 + " due to missing android.permission.DUMP permission"); 4336 return false; 4337 } else { 4338 return true; 4339 } 4340 } 4341 4342 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) { 4343 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 4344 4345 if (CollectionUtils.contains(args, DIAG_ARG)) { 4346 dumpNetworkDiagnostics(pw); 4347 return; 4348 } else if (CollectionUtils.contains(args, NETWORK_ARG)) { 4349 dumpNetworks(pw); 4350 return; 4351 } else if (CollectionUtils.contains(args, REQUEST_ARG)) { 4352 dumpNetworkRequests(pw); 4353 return; 4354 } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) { 4355 boolean verbose = !CollectionUtils.contains(args, SHORT_ARG); 4356 dumpTrafficController(pw, fd, verbose); 4357 return; 4358 } else if (CollectionUtils.contains(args, CLATEGRESS4RAWBPFMAP_ARG)) { 4359 dumpClatBpfRawMap(pw, true /* isEgress4Map */); 4360 return; 4361 } else if (CollectionUtils.contains(args, CLATINGRESS6RAWBPFMAP_ARG)) { 4362 dumpClatBpfRawMap(pw, false /* isEgress4Map */); 4363 return; 4364 } 4365 4366 pw.println("NetworkProviders for:"); 4367 pw.increaseIndent(); 4368 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 4369 pw.println(npi.providerId + ": " + npi.name); 4370 } 4371 pw.decreaseIndent(); 4372 pw.println(); 4373 4374 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 4375 pw.print("Active default network: "); 4376 if (defaultNai == null) { 4377 pw.println("none"); 4378 } else { 4379 pw.println(defaultNai.network.getNetId()); 4380 } 4381 pw.println(); 4382 4383 pw.println("Current network preferences: "); 4384 pw.increaseIndent(); 4385 dumpNetworkPreferences(pw); 4386 pw.decreaseIndent(); 4387 pw.println(); 4388 4389 pw.println("Current Networks:"); 4390 pw.increaseIndent(); 4391 dumpNetworks(pw); 4392 pw.decreaseIndent(); 4393 pw.println(); 4394 4395 pw.println("Status for known UIDs:"); 4396 pw.increaseIndent(); 4397 final int size = mUidBlockedReasons.size(); 4398 for (int i = 0; i < size; i++) { 4399 // Don't crash if the array is modified while dumping in bugreports. 4400 try { 4401 final int uid = mUidBlockedReasons.keyAt(i); 4402 final int blockedReasons = mUidBlockedReasons.valueAt(i); 4403 pw.println("UID=" + uid + " blockedReasons=" 4404 + Integer.toHexString(blockedReasons)); 4405 } catch (ArrayIndexOutOfBoundsException e) { 4406 pw.println(" ArrayIndexOutOfBoundsException"); 4407 } catch (ConcurrentModificationException e) { 4408 pw.println(" ConcurrentModificationException"); 4409 } 4410 } 4411 pw.println(); 4412 pw.decreaseIndent(); 4413 4414 pw.println("Network Requests:"); 4415 pw.increaseIndent(); 4416 dumpNetworkRequests(pw); 4417 pw.decreaseIndent(); 4418 pw.println(); 4419 4420 pw.println("Network Offers:"); 4421 pw.increaseIndent(); 4422 for (final NetworkOfferInfo offerInfo : mNetworkOffers) { 4423 pw.println(offerInfo.offer); 4424 } 4425 pw.decreaseIndent(); 4426 pw.println(); 4427 4428 mLegacyTypeTracker.dump(pw); 4429 4430 pw.println(); 4431 mKeepaliveTracker.dump(pw); 4432 4433 pw.println(); 4434 dumpAvoidBadWifiSettings(pw); 4435 4436 pw.println(); 4437 dumpDestroySockets(pw); 4438 4439 if (mDeps.isAtLeastT()) { 4440 // R: https://android.googlesource.com/platform/system/core/+/refs/heads/android11-release/rootdir/init.rc 4441 // shows /dev/cg2_bpf 4442 // S: https://android.googlesource.com/platform/system/core/+/refs/heads/android12-release/rootdir/init.rc 4443 // does not 4444 // Thus cgroups are mounted at /dev/cg2_bpf on R and not on /sys/fs/cgroup 4445 // so the following won't work (on R) anyway. 4446 // The /sys/fs/cgroup path is only actually enforced/required starting with U, 4447 // but it is very likely to already be the case (though not guaranteed) on T. 4448 // I'm not at all sure about S - let's just skip it to get rid of lint warnings. 4449 pw.println(); 4450 dumpBpfProgramStatus(pw); 4451 } 4452 4453 if (null != mCarrierPrivilegeAuthenticator) { 4454 pw.println(); 4455 mCarrierPrivilegeAuthenticator.dump(pw); 4456 } 4457 4458 pw.println(); 4459 4460 if (!CollectionUtils.contains(args, SHORT_ARG)) { 4461 pw.println(); 4462 pw.println("mNetworkRequestInfoLogs (most recent first):"); 4463 pw.increaseIndent(); 4464 mNetworkRequestInfoLogs.reverseDump(pw); 4465 pw.decreaseIndent(); 4466 4467 pw.println(); 4468 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 4469 pw.increaseIndent(); 4470 mNetworkInfoBlockingLogs.reverseDump(pw); 4471 pw.decreaseIndent(); 4472 4473 pw.println(); 4474 pw.println("NetTransition WakeLock activity (most recent first):"); 4475 pw.increaseIndent(); 4476 pw.println("total acquisitions: " + mTotalWakelockAcquisitions); 4477 pw.println("total releases: " + mTotalWakelockReleases); 4478 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s"); 4479 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s"); 4480 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) { 4481 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 4482 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); 4483 } 4484 mWakelockLogs.reverseDump(pw); 4485 4486 pw.println(); 4487 pw.println("bandwidth update requests (by uid):"); 4488 pw.increaseIndent(); 4489 synchronized (mBandwidthRequests) { 4490 for (int i = 0; i < mBandwidthRequests.size(); i++) { 4491 pw.println("[" + mBandwidthRequests.keyAt(i) 4492 + "]: " + mBandwidthRequests.valueAt(i)); 4493 } 4494 } 4495 pw.decreaseIndent(); 4496 pw.decreaseIndent(); 4497 4498 pw.println(); 4499 pw.println("mOemNetworkPreferencesLogs (most recent first):"); 4500 pw.increaseIndent(); 4501 mOemNetworkPreferencesLogs.reverseDump(pw); 4502 pw.decreaseIndent(); 4503 } 4504 4505 pw.println(); 4506 4507 pw.println(); 4508 pw.println("Permission Monitor:"); 4509 pw.increaseIndent(); 4510 mPermissionMonitor.dump(pw); 4511 pw.decreaseIndent(); 4512 4513 pw.println(); 4514 pw.println("Legacy network activity:"); 4515 pw.increaseIndent(); 4516 mNetworkActivityTracker.dump(pw); 4517 pw.decreaseIndent(); 4518 4519 pw.println(); 4520 pw.println("Multicast routing supported: " + 4521 (mMulticastRoutingCoordinatorService != null)); 4522 pw.println("Background firewall chain enabled: " + mBackgroundFirewallChainEnabled); 4523 pw.println("IngressToVpnAddressFiltering: " + mIngressToVpnAddressFiltering); 4524 } 4525 4526 private void dumpNetworks(IndentingPrintWriter pw) { 4527 for (NetworkAgentInfo nai : networksSortedById()) { 4528 pw.println(nai.toString()); 4529 pw.increaseIndent(); 4530 pw.println("Nat464Xlat:"); 4531 pw.increaseIndent(); 4532 nai.dumpNat464Xlat(pw); 4533 pw.decreaseIndent(); 4534 pw.println(String.format( 4535 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d", 4536 nai.numForegroundNetworkRequests(), 4537 nai.numNetworkRequests() - nai.numRequestNetworkRequests(), 4538 nai.numBackgroundNetworkRequests(), 4539 nai.numNetworkRequests())); 4540 pw.increaseIndent(); 4541 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4542 pw.println(nai.requestAt(i).toString()); 4543 } 4544 pw.decreaseIndent(); 4545 pw.println("Inactivity Timers:"); 4546 pw.increaseIndent(); 4547 nai.dumpInactivityTimers(pw); 4548 pw.decreaseIndent(); 4549 pw.decreaseIndent(); 4550 } 4551 } 4552 4553 private void dumpNetworkPreferences(IndentingPrintWriter pw) { 4554 if (!mProfileNetworkPreferences.isEmpty()) { 4555 pw.println("Profile preferences:"); 4556 pw.increaseIndent(); 4557 pw.println(mProfileNetworkPreferences); 4558 pw.decreaseIndent(); 4559 } 4560 if (!mOemNetworkPreferences.isEmpty()) { 4561 pw.println("OEM preferences:"); 4562 pw.increaseIndent(); 4563 pw.println(mOemNetworkPreferences); 4564 pw.decreaseIndent(); 4565 } 4566 if (!mMobileDataPreferredUids.isEmpty()) { 4567 pw.println("Mobile data preferred UIDs:"); 4568 pw.increaseIndent(); 4569 pw.println(mMobileDataPreferredUids); 4570 pw.decreaseIndent(); 4571 } 4572 4573 pw.println("Default requests:"); 4574 pw.increaseIndent(); 4575 dumpPerAppDefaultRequests(pw); 4576 pw.decreaseIndent(); 4577 } 4578 4579 private void dumpPerAppDefaultRequests(IndentingPrintWriter pw) { 4580 for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) { 4581 if (mDefaultRequest == defaultRequest) { 4582 continue; 4583 } 4584 4585 final NetworkAgentInfo satisfier = defaultRequest.getSatisfier(); 4586 final String networkOutput; 4587 if (null == satisfier) { 4588 networkOutput = "null"; 4589 } else if (mNoServiceNetwork.equals(satisfier)) { 4590 networkOutput = "no service network"; 4591 } else { 4592 networkOutput = String.valueOf(satisfier.network.netId); 4593 } 4594 final String asUidString = (defaultRequest.mAsUid == defaultRequest.mUid) 4595 ? "" : " asUid: " + defaultRequest.mAsUid; 4596 final String requestInfo = "Request: [uid/pid:" + defaultRequest.mUid + "/" 4597 + defaultRequest.mPid + asUidString + "]"; 4598 final String satisfierOutput = "Satisfier: [" + networkOutput + "]" 4599 + " Preference order: " + defaultRequest.mPreferenceOrder 4600 + " Tracked UIDs: " + defaultRequest.getUids(); 4601 pw.println(requestInfo + " - " + satisfierOutput); 4602 } 4603 } 4604 4605 private void dumpNetworkRequests(IndentingPrintWriter pw) { 4606 NetworkRequestInfo[] infos = null; 4607 while (infos == null) { 4608 try { 4609 infos = requestsSortedById(); 4610 } catch (ConcurrentModificationException e) { 4611 // mNetworkRequests should only be accessed from handler thread, except dump(). 4612 // As dump() is never called in normal usage, it would be needlessly expensive 4613 // to lock the collection only for its benefit. Instead, retry getting the 4614 // requests if ConcurrentModificationException is thrown during dump(). 4615 } 4616 } 4617 for (NetworkRequestInfo nri : infos) { 4618 pw.println(nri.toString()); 4619 } 4620 } 4621 4622 private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd, 4623 boolean verbose) { 4624 try { 4625 mBpfNetMaps.dump(pw, fd, verbose); 4626 } catch (ServiceSpecificException e) { 4627 pw.println(e.getMessage()); 4628 } catch (IOException e) { 4629 loge("Dump BPF maps failed, " + e); 4630 } 4631 } 4632 4633 private void dumpClatBpfRawMap(IndentingPrintWriter pw, boolean isEgress4Map) { 4634 for (NetworkAgentInfo nai : networksSortedById()) { 4635 if (nai.clatd != null) { 4636 nai.clatd.dumpRawBpfMap(pw, isEgress4Map); 4637 break; 4638 } 4639 } 4640 } 4641 4642 private void dumpAllRequestInfoLogsToLogcat() { 4643 try (PrintWriter logPw = new PrintWriter(new Writer() { 4644 @Override 4645 public void write(final char[] cbuf, final int off, final int len) { 4646 // This method is called with 0-length and 1-length arrays for empty strings 4647 // or strings containing only the DEL character. 4648 if (len <= 1) return; 4649 Log.e(TAG, new String(cbuf, off, len)); 4650 } 4651 @Override public void flush() {} 4652 @Override public void close() {} 4653 })) { 4654 mNetworkRequestInfoLogs.dump(logPw); 4655 } 4656 } 4657 4658 /** 4659 * Return an array of all current NetworkAgentInfos sorted by network id. 4660 */ 4661 private NetworkAgentInfo[] networksSortedById() { 4662 NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; 4663 networks = mNetworkAgentInfos.toArray(networks); 4664 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId())); 4665 return networks; 4666 } 4667 4668 /** 4669 * Return an array of all current NetworkRequest sorted by request id. 4670 */ 4671 @VisibleForTesting 4672 NetworkRequestInfo[] requestsSortedById() { 4673 NetworkRequestInfo[] requests = new NetworkRequestInfo[0]; 4674 requests = getNrisFromGlobalRequests().toArray(requests); 4675 // Sort the array based off the NRI containing the min requestId in its requests. 4676 Arrays.sort(requests, 4677 Comparator.comparingInt(nri -> Collections.min(nri.mRequests, 4678 Comparator.comparingInt(req -> req.requestId)).requestId 4679 ) 4680 ); 4681 return requests; 4682 } 4683 4684 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 4685 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 4686 if (officialNai != null && officialNai.equals(nai)) return true; 4687 if (officialNai != null || VDBG) { 4688 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 4689 " - " + nai); 4690 } 4691 return false; 4692 } 4693 4694 private boolean isDisconnectRequest(Message msg) { 4695 if (msg.what != NetworkAgent.EVENT_NETWORK_INFO_CHANGED) return false; 4696 final NetworkInfo info = (NetworkInfo) ((Pair) msg.obj).second; 4697 return info.getState() == NetworkInfo.State.DISCONNECTED; 4698 } 4699 4700 // must be stateless - things change under us. 4701 private class NetworkStateTrackerHandler extends Handler { 4702 public NetworkStateTrackerHandler(Looper looper) { 4703 super(looper); 4704 } 4705 4706 private void maybeHandleNetworkAgentMessage(Message msg) { 4707 final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj; 4708 final NetworkAgentInfo nai = arg.first; 4709 4710 // If the network has been destroyed, the only thing that it can do is disconnect. 4711 if (nai.isDestroyed() && !isDisconnectRequest(msg)) { 4712 if (DBG) { 4713 log("Message " + eventName(msg.what) + " from destroyed agent with netId " 4714 + nai.network.netId); 4715 } 4716 return; 4717 } 4718 4719 if (mQueueNetworkAgentEventsInSystemServer && nai.maybeEnqueueMessage(msg)) { 4720 // If the message is enqueued, the NAI will replay it immediately 4721 // when registration is complete. It does this by sending all the 4722 // messages in the order received immediately after the 4723 // EVENT_AGENT_REGISTERED message. 4724 if (DBG) { 4725 log("Message " + eventName(msg.what) + " enqueued for agent with netId " 4726 + nai.network.netId); 4727 } 4728 return; 4729 } 4730 4731 // If the nai has been registered (and doesn't enqueue), it should now be 4732 // in the list of NAIs. 4733 if (!mNetworkAgentInfos.contains(nai)) { 4734 // TODO : this is supposed to be impossible 4735 if (VDBG) { 4736 log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); 4737 } 4738 return; 4739 } 4740 4741 switch (msg.what) { 4742 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 4743 final NetworkCapabilities proposed = (NetworkCapabilities) arg.second; 4744 if (!nai.respectsNcStructuralConstraints(proposed)) { 4745 Log.wtf(TAG, "Agent " + nai + " violates nc structural constraints : " 4746 + nai.networkCapabilities + " -> " + proposed); 4747 disconnectAndDestroyNetwork(nai); 4748 return; 4749 } 4750 nai.setDeclaredCapabilities(proposed); 4751 final NetworkCapabilities sanitized = 4752 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator); 4753 maybeUpdateWifiRoamTimestamp(nai, sanitized); 4754 updateCapabilities(nai.getScore(), nai, sanitized); 4755 break; 4756 } 4757 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 4758 LinkProperties newLp = (LinkProperties) arg.second; 4759 processLinkPropertiesFromAgent(nai, newLp); 4760 handleUpdateLinkProperties(nai, newLp); 4761 break; 4762 } 4763 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 4764 NetworkInfo info = (NetworkInfo) arg.second; 4765 updateNetworkInfo(nai, info); 4766 break; 4767 } 4768 case NetworkAgent.EVENT_LOCAL_NETWORK_CONFIG_CHANGED: { 4769 final LocalNetworkConfig config = (LocalNetworkConfig) arg.second; 4770 handleUpdateLocalNetworkConfig(nai, nai.localNetworkConfig, config); 4771 break; 4772 } 4773 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 4774 updateNetworkScore(nai, (NetworkScore) arg.second); 4775 break; 4776 } 4777 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 4778 if (nai.everConnected()) { 4779 loge("ERROR: cannot call explicitlySelected on already-connected network"); 4780 // Note that if the NAI had been connected, this would affect the 4781 // score, and therefore would require re-mixing the score and performing 4782 // a rematch. 4783 } 4784 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1); 4785 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2); 4786 // Mark the network as temporarily accepting partial connectivity so that it 4787 // will be validated (and possibly become default) even if it only provides 4788 // partial internet access. Note that if user connects to partial connectivity 4789 // and choose "don't ask again", then wifi disconnected by some reasons(maybe 4790 // out of wifi coverage) and if the same wifi is available again, the device 4791 // will auto connect to this wifi even though the wifi has "no internet". 4792 // TODO: Evaluate using a separate setting in IpMemoryStore. 4793 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2); 4794 break; 4795 } 4796 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { 4797 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2); 4798 break; 4799 } 4800 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { 4801 // TODO: prevent loops, e.g., if a network declares itself as underlying. 4802 final List<Network> underlying = (List<Network>) arg.second; 4803 4804 if (isLegacyLockdownNai(nai) 4805 && (underlying == null || underlying.size() != 1)) { 4806 Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString() 4807 + " must have exactly one underlying network: " + underlying); 4808 } 4809 4810 final Network[] oldUnderlying = nai.declaredUnderlyingNetworks; 4811 nai.declaredUnderlyingNetworks = (underlying != null) 4812 ? underlying.toArray(new Network[0]) : null; 4813 4814 if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) { 4815 if (DBG) { 4816 log(nai.toShortString() + " changed underlying networks to " 4817 + Arrays.toString(nai.declaredUnderlyingNetworks)); 4818 } 4819 updateCapabilitiesForNetwork(nai); 4820 notifyIfacesChangedForNetworkStats(); 4821 } 4822 break; 4823 } 4824 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: { 4825 if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 4826 nai.teardownDelayMs = msg.arg1; 4827 } else { 4828 logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1); 4829 } 4830 break; 4831 } 4832 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: { 4833 nai.setLingerDuration((int) arg.second); 4834 break; 4835 } 4836 case NetworkAgent.EVENT_ADD_DSCP_POLICY: { 4837 DscpPolicy policy = (DscpPolicy) arg.second; 4838 if (mDscpPolicyTracker != null) { 4839 mDscpPolicyTracker.addDscpPolicy(nai, policy); 4840 } 4841 break; 4842 } 4843 case NetworkAgent.EVENT_REMOVE_DSCP_POLICY: { 4844 if (mDscpPolicyTracker != null) { 4845 mDscpPolicyTracker.removeDscpPolicy(nai, (int) arg.second); 4846 } 4847 break; 4848 } 4849 case NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES: { 4850 if (mDscpPolicyTracker != null) { 4851 mDscpPolicyTracker.removeAllDscpPolicies(nai, true); 4852 } 4853 break; 4854 } 4855 case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: { 4856 if (!nai.everConnected()) { 4857 Log.d(TAG, "unregisterAfterReplacement on never-connected " 4858 + nai.toShortString() + ", tearing down instead"); 4859 teardownUnneededNetwork(nai); 4860 break; 4861 } 4862 4863 if (nai.isDestroyed()) { 4864 Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString() 4865 + ", ignoring"); 4866 break; 4867 } 4868 4869 final int timeoutMs = (int) arg.second; 4870 if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 4871 Log.e(TAG, "Invalid network replacement timer " + timeoutMs 4872 + ", must be between 0 and " + NetworkAgent.MAX_TEARDOWN_DELAY_MS); 4873 } 4874 4875 // Marking a network awaiting replacement is used to ensure that any requests 4876 // satisfied by the network do not switch to another network until a 4877 // replacement is available or the wait for a replacement times out. 4878 // If the network is inactive (i.e., nascent or lingering), then there are no 4879 // such requests, and there is no point keeping it. Just tear it down. 4880 // Note that setLingerDuration(0) cannot be used to do this because the network 4881 // could be nascent. 4882 nai.clearInactivityState(); 4883 if (unneeded(nai, UnneededFor.TEARDOWN)) { 4884 Log.d(TAG, nai.toShortString() 4885 + " marked awaiting replacement is unneeded, tearing down instead"); 4886 teardownUnneededNetwork(nai); 4887 break; 4888 } 4889 4890 Log.d(TAG, "Marking " + nai.toShortString() 4891 + " destroyed, awaiting replacement within " + timeoutMs + "ms"); 4892 destroyNativeNetwork(nai); 4893 4894 // TODO: deduplicate this call with the one in disconnectAndDestroyNetwork. 4895 // This is not trivial because KeepaliveTracker#handleStartKeepalive does not 4896 // consider the fact that the network could already have disconnected or been 4897 // destroyed. Fix the code to send ERROR_INVALID_NETWORK when this happens 4898 // (taking care to ensure no dup'd FD leaks), then remove the code duplication 4899 // and move this code to a sensible location (destroyNativeNetwork perhaps?). 4900 mKeepaliveTracker.handleStopAllKeepalives(nai, 4901 SocketKeepalive.ERROR_INVALID_NETWORK); 4902 4903 nai.updateScoreForNetworkAgentUpdate(); 4904 // This rematch is almost certainly not going to result in any changes, because 4905 // the destroyed flag is only just above the "current satisfier wins" 4906 // tie-breaker. But technically anything that affects scoring should rematch. 4907 rematchAllNetworksAndRequests(); 4908 if (mQueueNetworkAgentEventsInSystemServer) { 4909 mHandler.postDelayed(() -> disconnectAndDestroyNetwork(nai), timeoutMs); 4910 } else { 4911 mHandler.postDelayed(() -> nai.disconnect(), timeoutMs); 4912 } 4913 break; 4914 } 4915 } 4916 } 4917 4918 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 4919 final int netId = msg.arg2; 4920 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 4921 // If a network has already been destroyed, all NetworkMonitor updates are ignored. 4922 if (nai != null && nai.isDestroyed()) return true; 4923 switch (msg.what) { 4924 default: 4925 return false; 4926 case EVENT_PROBE_STATUS_CHANGED: { 4927 if (nai == null) { 4928 break; 4929 } 4930 final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first; 4931 final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second; 4932 final boolean probePrivateDnsCompleted = 4933 ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0); 4934 final boolean privateDnsBroken = 4935 ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0); 4936 if (probePrivateDnsCompleted) { 4937 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) { 4938 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken); 4939 updateCapabilitiesForNetwork(nai); 4940 } 4941 // Only show the notification when the private DNS is broken and the 4942 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid. 4943 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) { 4944 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN); 4945 } 4946 nai.networkAgentConfig.hasShownBroken = privateDnsBroken; 4947 } else if (nai.networkCapabilities.isPrivateDnsBroken()) { 4948 // If probePrivateDnsCompleted is false but nai.networkCapabilities says 4949 // private DNS is broken, it means this network is being reevaluated. 4950 // Either probing private DNS is not necessary any more or it hasn't been 4951 // done yet. In either case, the networkCapabilities should be updated to 4952 // reflect the new status. 4953 nai.networkCapabilities.setPrivateDnsBroken(false); 4954 updateCapabilitiesForNetwork(nai); 4955 nai.networkAgentConfig.hasShownBroken = false; 4956 } 4957 break; 4958 } 4959 case EVENT_NETWORK_TESTED: { 4960 final NetworkTestedResults results = (NetworkTestedResults) msg.obj; 4961 4962 if (nai == null) break; 4963 4964 handleNetworkTested(nai, results.mTestResult, 4965 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl); 4966 break; 4967 } 4968 case EVENT_PROVISIONING_NOTIFICATION: { 4969 final boolean visible = toBool(msg.arg1); 4970 // If captive portal status has changed, update capabilities or disconnect. 4971 if (!visible) { 4972 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other 4973 // notifications belong to the same network may be cleared unexpectedly. 4974 mNotifier.clearNotification(netId, NotificationType.SIGN_IN); 4975 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH); 4976 } else { 4977 if (nai == null) { 4978 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 4979 break; 4980 } 4981 if (!nai.networkAgentConfig.provisioningNotificationDisabled) { 4982 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 4983 (PendingIntent) msg.obj, 4984 nai.networkAgentConfig.explicitlySelected); 4985 } 4986 } 4987 break; 4988 } 4989 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { 4990 if (nai == null) break; 4991 4992 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); 4993 break; 4994 } 4995 case EVENT_CAPPORT_DATA_CHANGED: { 4996 if (nai == null) break; 4997 handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj); 4998 break; 4999 } 5000 } 5001 return true; 5002 } 5003 5004 private void handleNetworkTested( 5005 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) { 5006 final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0; 5007 final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0; 5008 final boolean portal = !TextUtils.isEmpty(redirectUrl); 5009 5010 // If there is any kind of working networking, then the NAI has been evaluated 5011 // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is 5012 // the first time this ever happened. 5013 final boolean someConnectivity = (valid || partial || portal); 5014 final boolean becameEvaluated = someConnectivity && nai.setEvaluated(); 5015 // Because of b/245893397, if the score is updated when updateCapabilities is called, 5016 // any callback that receives onAvailable for that rematch receives an extra caps 5017 // callback. To prevent that, update the score in the agent so the updates below won't 5018 // see an update to both caps and score at the same time. 5019 // TODO : fix b/245893397 and remove this. 5020 if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate(); 5021 5022 if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) { 5023 // Assume the validation failure is due to a temporary failure after roaming 5024 // and ignore it. NetworkMonitor will continue to retry validation. If it 5025 // continues to fail after the block timeout expires, the network will be 5026 // marked unvalidated. If it succeeds, then validation state will not change. 5027 return; 5028 } 5029 5030 final boolean wasValidated = nai.isValidated(); 5031 final boolean wasPartial = nai.partialConnectivity(); 5032 final boolean wasPortal = nai.captivePortalDetected(); 5033 nai.setPartialConnectivity(partial); 5034 nai.setCaptivePortalDetected(portal); 5035 nai.updateScoreForNetworkAgentUpdate(); 5036 final boolean partialConnectivityChanged = (wasPartial != partial); 5037 final boolean portalChanged = (wasPortal != portal); 5038 5039 if (DBG) { 5040 final String logMsg = !TextUtils.isEmpty(redirectUrl) 5041 ? " with redirect to " + redirectUrl 5042 : ""; 5043 final String statusMsg; 5044 if (valid) { 5045 statusMsg = "passed"; 5046 } else if (!TextUtils.isEmpty(redirectUrl)) { 5047 statusMsg = "detected a portal"; 5048 } else { 5049 statusMsg = "failed"; 5050 } 5051 log(nai.toShortString() + " validation " + statusMsg + logMsg); 5052 } 5053 if (valid != wasValidated) { 5054 final FullScore oldScore = nai.getScore(); 5055 nai.setValidated(valid); 5056 updateCapabilities(oldScore, nai, nai.networkCapabilities); 5057 if (valid) { 5058 handleFreshlyValidatedNetwork(nai); 5059 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and 5060 // LOST_INTERNET notifications if network becomes valid. 5061 mNotifier.clearNotification(nai.network.getNetId(), 5062 NotificationType.NO_INTERNET); 5063 mNotifier.clearNotification(nai.network.getNetId(), 5064 NotificationType.LOST_INTERNET); 5065 mNotifier.clearNotification(nai.network.getNetId(), 5066 NotificationType.PARTIAL_CONNECTIVITY); 5067 mNotifier.clearNotification(nai.network.getNetId(), 5068 NotificationType.PRIVATE_DNS_BROKEN); 5069 // If network becomes valid, the hasShownBroken should be reset for 5070 // that network so that the notification will be fired when the private 5071 // DNS is broken again. 5072 nai.networkAgentConfig.hasShownBroken = false; 5073 } 5074 } else if (partialConnectivityChanged) { 5075 updateCapabilitiesForNetwork(nai); 5076 } else if (portalChanged) { 5077 if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID 5078 == getCaptivePortalMode(nai)) { 5079 if (DBG) log("Avoiding captive portal network: " + nai.toShortString()); 5080 nai.onPreventAutomaticReconnect(); 5081 teardownUnneededNetwork(nai); 5082 return; 5083 } else { 5084 updateCapabilitiesForNetwork(nai); 5085 } 5086 } else if (becameEvaluated) { 5087 // If valid or partial connectivity changed, updateCapabilities* has 5088 // done the rematch. 5089 rematchAllNetworksAndRequests(); 5090 } 5091 updateInetCondition(nai); 5092 5093 // Let the NetworkAgent know the state of its network 5094 // TODO: Evaluate to update partial connectivity to status to NetworkAgent. 5095 nai.onValidationStatusChanged( 5096 valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK, 5097 redirectUrl); 5098 5099 // If NetworkMonitor detects partial connectivity before 5100 // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification 5101 // immediately. Re-notify partial connectivity silently if no internet 5102 // notification already there. 5103 if (!wasPartial && nai.partialConnectivity()) { 5104 // Remove delayed message if there is a pending message. 5105 mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network); 5106 handleInitialEvaluationTimeout(nai.network); 5107 } 5108 5109 if (wasValidated && !nai.isValidated()) { 5110 handleNetworkUnvalidated(nai); 5111 } 5112 } 5113 5114 private int getCaptivePortalMode(@NonNull NetworkAgentInfo nai) { 5115 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) && 5116 mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)) { 5117 // Do not avoid captive portal when network is wear proxy. 5118 return ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT; 5119 } 5120 5121 return Settings.Global.getInt(mContext.getContentResolver(), 5122 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, 5123 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 5124 } 5125 5126 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 5127 switch (msg.what) { 5128 default: 5129 return false; 5130 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 5131 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 5132 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 5133 handleLingerComplete(nai); 5134 } 5135 break; 5136 } 5137 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: { 5138 handleNetworkAgentRegistered(msg); 5139 break; 5140 } 5141 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: { 5142 handleNetworkAgentDisconnected(msg); 5143 break; 5144 } 5145 } 5146 return true; 5147 } 5148 5149 @Override 5150 public void handleMessage(@NonNull Message msg) { 5151 if (!maybeHandleNetworkMonitorMessage(msg) 5152 && !maybeHandleNetworkAgentInfoMessage(msg)) { 5153 maybeHandleNetworkAgentMessage(msg); 5154 } 5155 } 5156 } 5157 5158 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub { 5159 private final int mNetId; 5160 private final AutodestructReference<NetworkAgentInfo> mNai; 5161 5162 private NetworkMonitorCallbacks(NetworkAgentInfo nai) { 5163 mNetId = nai.network.getNetId(); 5164 mNai = new AutodestructReference<>(nai); 5165 } 5166 5167 @Override 5168 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 5169 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, 5170 new Pair<>(mNai.getAndDestroy(), networkMonitor))); 5171 } 5172 5173 @Override 5174 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { 5175 // Legacy version of notifyNetworkTestedWithExtras. 5176 // Would only be called if the system has a NetworkStack module older than the 5177 // framework, which does not happen in practice. 5178 Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken"); 5179 } 5180 5181 @Override 5182 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) { 5183 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use 5184 // the same looper so messages will be processed in sequence. 5185 final Message msg = mTrackerHandler.obtainMessage( 5186 EVENT_NETWORK_TESTED, 5187 0, mNetId, 5188 new NetworkTestedResults( 5189 mNetId, p.result, p.timestampMillis, p.redirectUrl)); 5190 mTrackerHandler.sendMessage(msg); 5191 5192 // Invoke ConnectivityReport generation for this Network test event. 5193 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId); 5194 if (nai == null) return; 5195 5196 // NetworkMonitor reports the network validation result as a bitmask while 5197 // ConnectivityDiagnostics treats this value as an int. Convert the result to a single 5198 // logical value for ConnectivityDiagnostics. 5199 final int validationResult = networkMonitorValidationResultToConnDiagsValidationResult( 5200 p.result); 5201 5202 final PersistableBundle extras = new PersistableBundle(); 5203 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, validationResult); 5204 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded); 5205 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted); 5206 5207 ConnectivityReportEvent reportEvent = 5208 new ConnectivityReportEvent(p.timestampMillis, nai, extras); 5209 final Message m = mConnectivityDiagnosticsHandler.obtainMessage( 5210 ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent); 5211 mConnectivityDiagnosticsHandler.sendMessage(m); 5212 } 5213 5214 @Override 5215 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) { 5216 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5217 EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 5218 0, mNetId, PrivateDnsConfig.fromParcel(config))); 5219 } 5220 5221 @Override 5222 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) { 5223 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5224 EVENT_PROBE_STATUS_CHANGED, 5225 0, mNetId, new Pair<>(probesCompleted, probesSucceeded))); 5226 } 5227 5228 @Override 5229 public void notifyCaptivePortalDataChanged(CaptivePortalData data) { 5230 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5231 EVENT_CAPPORT_DATA_CHANGED, 5232 0, mNetId, data)); 5233 } 5234 5235 @Override 5236 public void showProvisioningNotification(String action, String packageName) { 5237 final Intent intent = new Intent(action); 5238 intent.setPackage(packageName); 5239 5240 final PendingIntent pendingIntent; 5241 // Only the system server can register notifications with package "android" 5242 final long token = Binder.clearCallingIdentity(); 5243 try { 5244 pendingIntent = PendingIntent.getBroadcast( 5245 mContext, 5246 0 /* requestCode */, 5247 intent, 5248 PendingIntent.FLAG_IMMUTABLE); 5249 } finally { 5250 Binder.restoreCallingIdentity(token); 5251 } 5252 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5253 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW, 5254 mNetId, pendingIntent)); 5255 } 5256 5257 @Override 5258 public void hideProvisioningNotification() { 5259 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 5260 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); 5261 } 5262 5263 @Override 5264 public void notifyDataStallSuspected(DataStallReportParcelable p) { 5265 ConnectivityService.this.notifyDataStallSuspected(p, mNetId); 5266 } 5267 5268 @Override 5269 public int getInterfaceVersion() { 5270 return this.VERSION; 5271 } 5272 5273 @Override 5274 public String getInterfaceHash() { 5275 return this.HASH; 5276 } 5277 } 5278 5279 /** 5280 * Converts the given NetworkMonitor-specific validation result bitmask to a 5281 * ConnectivityDiagnostics-specific validation result int. 5282 */ 5283 private int networkMonitorValidationResultToConnDiagsValidationResult(int validationResult) { 5284 if ((validationResult & NETWORK_VALIDATION_RESULT_SKIPPED) != 0) { 5285 return ConnectivityReport.NETWORK_VALIDATION_RESULT_SKIPPED; 5286 } 5287 if ((validationResult & NETWORK_VALIDATION_RESULT_VALID) == 0) { 5288 return ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID; 5289 } 5290 return (validationResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0 5291 ? ConnectivityReport.NETWORK_VALIDATION_RESULT_PARTIALLY_VALID 5292 : ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID; 5293 } 5294 5295 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) { 5296 log("Data stall detected with methods: " + p.detectionMethod); 5297 5298 final PersistableBundle extras = new PersistableBundle(); 5299 int detectionMethod = 0; 5300 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 5301 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); 5302 detectionMethod |= DETECTION_METHOD_DNS_EVENTS; 5303 } 5304 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 5305 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); 5306 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, 5307 p.tcpMetricsCollectionPeriodMillis); 5308 detectionMethod |= DETECTION_METHOD_TCP_METRICS; 5309 } 5310 5311 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( 5312 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId, 5313 new Pair<>(p.timestampMillis, extras)); 5314 5315 // NetworkStateTrackerHandler currently doesn't take any actions based on data 5316 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid 5317 // the cost of going through two handlers. 5318 mConnectivityDiagnosticsHandler.sendMessage(msg); 5319 } 5320 5321 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) { 5322 return (p.detectionMethod & detectionMethod) != 0; 5323 } 5324 5325 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { 5326 return isPrivateDnsValidationRequired(nai.networkCapabilities); 5327 } 5328 5329 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { 5330 if (nai == null) return; 5331 // If the Private DNS mode is opportunistic, reprogram the DNS servers 5332 // in order to restart a validation pass from within netd. 5333 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 5334 if (cfg.inOpportunisticMode()) { 5335 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 5336 } 5337 } 5338 5339 private void handlePrivateDnsSettingsChanged() { 5340 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 5341 5342 forEachNetworkAgentInfo(nai -> { 5343 handlePerNetworkPrivateDnsConfig(nai, cfg); 5344 if (networkRequiresPrivateDnsValidation(nai)) { 5345 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5346 } 5347 }); 5348 } 5349 5350 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 5351 // Private DNS only ever applies to networks that might provide 5352 // Internet access and therefore also require validation. 5353 if (!networkRequiresPrivateDnsValidation(nai)) return; 5354 5355 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or 5356 // schedule DNS resolutions. If a DNS resolution is required the 5357 // result will be sent back to us. 5358 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel()); 5359 5360 // With Private DNS bypass support, we can proceed to update the 5361 // Private DNS config immediately, even if we're in strict mode 5362 // and have not yet resolved the provider name into a set of IPs. 5363 updatePrivateDns(nai, cfg); 5364 } 5365 5366 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 5367 mDnsManager.updatePrivateDns(nai.network, newCfg); 5368 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 5369 } 5370 5371 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 5372 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 5373 if (nai == null) { 5374 return; 5375 } 5376 mDnsManager.updatePrivateDnsValidation(update); 5377 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5378 } 5379 5380 private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, 5381 int prefixLength) { 5382 NetworkAgentInfo nai = mNetworkForNetId.get(netId); 5383 if (nai == null) return; 5384 5385 log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", 5386 netId, operation, prefixAddress, prefixLength)); 5387 5388 IpPrefix prefix = null; 5389 if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { 5390 try { 5391 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), 5392 prefixLength); 5393 } catch (IllegalArgumentException e) { 5394 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); 5395 return; 5396 } 5397 } 5398 5399 nai.clatd.setNat64PrefixFromDns(prefix); 5400 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5401 } 5402 5403 private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai, 5404 @Nullable final CaptivePortalData data) { 5405 nai.capportApiData = data; 5406 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo 5407 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 5408 } 5409 5410 /** 5411 * Updates the inactivity state from the network requests inside the NAI. 5412 * @param nai the agent info to update 5413 * @param now the timestamp of the event causing this update 5414 * @return whether the network was inactive as a result of this update 5415 */ 5416 private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) { 5417 // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm. 5418 // 2. If the network was inactive and there are now requests, unset inactive. 5419 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 5420 // one lingered request, set inactive. 5421 nai.updateInactivityTimer(); 5422 if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) { 5423 if (DBG) log("Unsetting inactive " + nai.toShortString()); 5424 nai.unsetInactive(); 5425 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 5426 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) { 5427 if (DBG) { 5428 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 5429 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms"); 5430 } 5431 nai.setInactive(); 5432 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 5433 return true; 5434 } 5435 return false; 5436 } 5437 5438 private void handleNetworkAgentRegistered(Message msg) { 5439 final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 5440 if (!mNetworkAgentInfos.contains(nai)) { 5441 return; 5442 } 5443 5444 if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) { 5445 if (VDBG) log("NetworkAgent registered"); 5446 } else { 5447 loge("Error connecting NetworkAgent"); 5448 mNetworkAgentInfos.remove(nai); 5449 if (nai != null) { 5450 final boolean wasDefault = isDefaultNetwork(nai); 5451 synchronized (mNetworkForNetId) { 5452 mNetworkForNetId.remove(nai.network.getNetId()); 5453 } 5454 mNetIdManager.releaseNetId(nai.network.getNetId()); 5455 // Just in case. 5456 mLegacyTypeTracker.remove(nai, wasDefault); 5457 } 5458 } 5459 } 5460 5461 @VisibleForTesting 5462 protected boolean shouldCreateNetworksImmediately(@NonNull NetworkCapabilities caps) { 5463 // The feature of creating the networks immediately was slated for U, but race conditions 5464 // detected late required this was flagged off. 5465 // TODO : remove when it's determined that the code is stable 5466 return mQueueNetworkAgentEventsInSystemServer 5467 // Local network agents for Thread used to not create networks immediately, 5468 // but other local agents (tethering, P2P) require this to function. 5469 || (caps.hasCapability(NET_CAPABILITY_LOCAL_NETWORK) 5470 && !caps.hasTransport(TRANSPORT_THREAD)); 5471 } 5472 5473 private boolean shouldCreateNativeNetwork(@NonNull NetworkAgentInfo nai, 5474 @NonNull NetworkInfo.State state) { 5475 if (nai.isCreated()) return false; 5476 if (state == NetworkInfo.State.CONNECTED) return true; 5477 if (state != NetworkInfo.State.CONNECTING) { 5478 // TODO: throw if no WTFs are observed in the field. 5479 if (shouldCreateNetworksImmediately(nai.getCapsNoCopy())) { 5480 Log.wtf(TAG, "Uncreated network in invalid state: " + state); 5481 } 5482 return false; 5483 } 5484 return nai.isVPN() || shouldCreateNetworksImmediately(nai.getCapsNoCopy()); 5485 } 5486 5487 private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 5488 return nai.isCreated() && !nai.isDestroyed(); 5489 } 5490 5491 @VisibleForTesting 5492 boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) { 5493 // T+ devices should use unregisterAfterReplacement. 5494 if (mDeps.isAtLeastT()) return false; 5495 5496 // If the network never roamed, return false. The check below is not sufficient if time 5497 // since boot is less than blockTimeOut, though that's extremely unlikely to happen. 5498 if (nai.lastRoamTime == 0) return false; 5499 5500 final long blockTimeOut = Long.valueOf(mResources.get().getInteger( 5501 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis)); 5502 if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS 5503 && blockTimeOut >= 0) { 5504 final long currentTimeMs = SystemClock.elapsedRealtime(); 5505 long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime; 5506 if (timeSinceLastRoam <= blockTimeOut) { 5507 log ("blocked because only " + timeSinceLastRoam + "ms after roam"); 5508 return true; 5509 } 5510 } 5511 return false; 5512 } 5513 5514 private void handleNetworkAgentDisconnected(Message msg) { 5515 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 5516 disconnectAndDestroyNetwork(nai); 5517 } 5518 5519 // Destroys a network, remove references to it from the internal state managed by 5520 // ConnectivityService, free its interfaces and clean up. 5521 // Must be called on the Handler thread. 5522 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 5523 ensureRunningOnConnectivityServiceThread(); 5524 5525 if (!mNetworkAgentInfos.contains(nai)) return; 5526 5527 if (DBG) { 5528 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests()); 5529 } 5530 5531 if (mQueueNetworkAgentEventsInSystemServer) { 5532 nai.disconnect(); 5533 } 5534 5535 // Clear all notifications of this network. 5536 mNotifier.clearNotification(nai.network.getNetId()); 5537 // A network agent has disconnected. 5538 // TODO - if we move the logic to the network agent (have them disconnect 5539 // because they lost all their requests or because their score isn't good) 5540 // then they would disconnect organically, report their new state and then 5541 // disconnect the channel. 5542 if (nai.networkInfo.isConnected() || nai.networkInfo.isSuspended()) { 5543 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 5544 null, null); 5545 } 5546 final boolean wasDefault = isDefaultNetwork(nai); 5547 if (wasDefault) { 5548 mDefaultInetConditionPublished = 0; 5549 } 5550 if (mTrackMultiNetworkActivities) { 5551 // If trackMultiNetworkActivities is disabled, ActivityTracker removes idleTimer when 5552 // the network becomes no longer the default network. 5553 mNetworkActivityTracker.removeDataActivityTracking(nai); 5554 } 5555 notifyIfacesChangedForNetworkStats(); 5556 // If this was a local network forwarded to some upstream, or if some local network was 5557 // forwarded to this nai, then disable forwarding rules now. 5558 maybeDisableForwardRulesForDisconnectingNai(nai, true /* sendCallbacks */); 5559 // If this is a local network with an upstream selector, remove the associated network 5560 // request. 5561 if (nai.isLocalNetwork()) { 5562 final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector(); 5563 if (null != selector) { 5564 handleRemoveNetworkRequest(mNetworkRequests.get(selector)); 5565 } 5566 } 5567 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 5568 // by other networks that are already connected. Perhaps that can be done by 5569 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 5570 // of rematchAllNetworksAndRequests 5571 notifyNetworkCallbacks(nai, CALLBACK_LOST); 5572 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK); 5573 5574 mQosCallbackTracker.handleNetworkReleased(nai.network); 5575 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 5576 // Disable wakeup packet monitoring for each interface. 5577 wakeupModifyInterface(iface, nai, false); 5578 } 5579 nai.networkMonitor().notifyNetworkDisconnected(); 5580 mNetworkAgentInfos.remove(nai); 5581 nai.clatd.update(); 5582 synchronized (mNetworkForNetId) { 5583 // Remove the NetworkAgent, but don't mark the netId as 5584 // available until we've told netd to delete it below. 5585 mNetworkForNetId.remove(nai.network.getNetId()); 5586 } 5587 propagateUnderlyingNetworkCapabilities(nai.network); 5588 // Update allowed network lists in netd. This should be called after removing nai 5589 // from mNetworkAgentInfos. 5590 updateProfileAllowedNetworks(); 5591 // Remove all previously satisfied requests. 5592 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5593 final NetworkRequest request = nai.requestAt(i); 5594 final NetworkRequestInfo nri = mNetworkRequests.get(request); 5595 final NetworkAgentInfo currentNetwork = nri.getSatisfier(); 5596 if (currentNetwork != null 5597 && currentNetwork.network.getNetId() == nai.network.getNetId()) { 5598 // uid rules for this network will be removed in destroyNativeNetwork(nai). 5599 // TODO : setting the satisfier is in fact the job of the rematch. Teach the 5600 // rematch not to keep disconnected agents instead of setting it here ; this 5601 // will also allow removing updating the offers below. 5602 nri.setSatisfier(null, null); 5603 for (final NetworkOfferInfo noi : mNetworkOffers) { 5604 informOffer(nri, noi.offer, mNetworkRanker); 5605 } 5606 5607 if (mDefaultRequest == nri) { 5608 mNetworkActivityTracker.updateDefaultNetwork(null /* newNetwork */, nai); 5609 maybeDestroyPendingSockets(null /* newNetwork */, nai); 5610 ensureNetworkTransitionWakelock(nai.toShortString()); 5611 } 5612 } 5613 } 5614 nai.clearInactivityState(); 5615 // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after. 5616 // Currently, deleting it breaks tests that check for the default network disconnecting. 5617 // Find out why, fix the rematch code, and delete this. 5618 mLegacyTypeTracker.remove(nai, wasDefault); 5619 rematchAllNetworksAndRequests(); 5620 mLingerMonitor.noteDisconnect(nai); 5621 5622 if (null == getDefaultNetwork() && nai.linkProperties.getHttpProxy() != null) { 5623 // The obvious place to do this would be in makeDefault(), however makeDefault() is 5624 // not called by the rematch in this case. This is because the code above unset 5625 // this network from the default request's satisfier, and that is what the rematch 5626 // is using as its source data to know what the old satisfier was. So as far as the 5627 // rematch above is concerned, the old default network was null. 5628 // Therefore if there is no new default, the default network was null and is still 5629 // null, thus there was no change so makeDefault() is not called. So if the old 5630 // network had a proxy and there is no new default, the proxy tracker should be told 5631 // that there is no longer a default proxy. 5632 // Strictly speaking this is not essential because having a proxy setting when 5633 // there is no network is harmless, but it's still counter-intuitive so reset to null. 5634 mProxyTracker.setDefaultProxy(null); 5635 } 5636 5637 // Immediate teardown. 5638 if (nai.teardownDelayMs == 0) { 5639 destroyNetwork(nai); 5640 return; 5641 } 5642 5643 // Delayed teardown. 5644 if (nai.isCreated() && !nai.isDestroyed()) { 5645 try { 5646 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM); 5647 } catch (RemoteException e) { 5648 Log.d(TAG, "Error marking network restricted during teardown: ", e); 5649 } 5650 } 5651 mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs); 5652 } 5653 5654 private void destroyNetwork(NetworkAgentInfo nai) { 5655 if (shouldDestroyNativeNetwork(nai)) { 5656 // Tell netd to clean up the configuration for this network 5657 // (routing rules, DNS, etc). 5658 // This may be slow as it requires a lot of netd shelling out to ip and 5659 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 5660 // after we've rematched networks with requests (which might change the default 5661 // network or service a new request from an app), so network traffic isn't interrupted 5662 // for an unnecessarily long time. 5663 destroyNativeNetwork(nai); 5664 } 5665 if (!nai.isCreated() && !mDeps.isAtLeastT()) { 5666 // Backwards compatibility: send onNetworkDestroyed even if network was never created. 5667 // This can never run if the code above runs because shouldDestroyNativeNetwork is 5668 // false if the network was never created. 5669 // TODO: delete when S is no longer supported. 5670 nai.onNetworkDestroyed(); 5671 } 5672 mNetIdManager.releaseNetId(nai.network.getNetId()); 5673 } 5674 5675 private void maybeDisableForwardRulesForDisconnectingNai( 5676 @NonNull final NetworkAgentInfo disconnecting, final boolean sendCallbacks) { 5677 // Step 1 : maybe this network was the upstream for one or more local networks. 5678 forEachNetworkAgentInfo(local -> { 5679 if (!local.isLocalNetwork()) return; // return@forEach 5680 final NetworkRequest selector = local.localNetworkConfig.getUpstreamSelector(); 5681 if (null == selector) return; // return@forEach 5682 final NetworkRequestInfo nri = mNetworkRequests.get(selector); 5683 // null == nri can happen while disconnecting a network, because destroyNetwork() is 5684 // called after removing all associated NRIs from mNetworkRequests. 5685 if (null == nri) return; // return@forEach 5686 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5687 if (disconnecting != satisfier) return; // return@forEach 5688 removeLocalNetworkUpstream(local, disconnecting); 5689 // Set the satisfier to null immediately so that the LOCAL_NETWORK_CHANGED callback 5690 // correctly contains null as an upstream. 5691 if (sendCallbacks) { 5692 nri.setSatisfier(null, null); 5693 notifyNetworkCallbacks(local, CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 5694 } 5695 }); 5696 5697 // Step 2 : maybe this is a local network that had an upstream. 5698 if (!disconnecting.isLocalNetwork()) return; 5699 final NetworkRequest selector = disconnecting.localNetworkConfig.getUpstreamSelector(); 5700 if (null == selector) return; 5701 final NetworkRequestInfo nri = mNetworkRequests.get(selector); 5702 // As above null == nri can happen while disconnecting a network, because destroyNetwork() 5703 // is called after removing all associated NRIs from mNetworkRequests. 5704 if (null == nri) return; 5705 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5706 if (null == satisfier) return; 5707 removeLocalNetworkUpstream(disconnecting, satisfier); 5708 } 5709 5710 private void removeLocalNetworkUpstream(@NonNull final NetworkAgentInfo localAgent, 5711 @NonNull final NetworkAgentInfo upstream) { 5712 try { 5713 final String localNetworkInterfaceName = localAgent.linkProperties.getInterfaceName(); 5714 final String upstreamNetworkInterfaceName = upstream.linkProperties.getInterfaceName(); 5715 mRoutingCoordinatorService.removeInterfaceForward( 5716 localNetworkInterfaceName, 5717 upstreamNetworkInterfaceName); 5718 disableMulticastRouting(localNetworkInterfaceName, upstreamNetworkInterfaceName); 5719 } catch (RemoteException e) { 5720 loge("Couldn't remove interface forward for " 5721 + localAgent.linkProperties.getInterfaceName() + " to " 5722 + upstream.linkProperties.getInterfaceName() + " while disconnecting"); 5723 } 5724 } 5725 5726 private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) { 5727 try { 5728 // This should never fail. Specifying an already in use NetID will cause failure. 5729 final NativeNetworkConfig config; 5730 if (nai.isVPN()) { 5731 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) { 5732 Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString()); 5733 return false; 5734 } 5735 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL, 5736 INetd.PERMISSION_NONE, 5737 !nai.networkAgentConfig.allowBypass /* secure */, 5738 getVpnType(nai), nai.networkAgentConfig.excludeLocalRouteVpn); 5739 } else { 5740 config = new NativeNetworkConfig(nai.network.getNetId(), 5741 nai.isLocalNetwork() ? NativeNetworkType.PHYSICAL_LOCAL 5742 : NativeNetworkType.PHYSICAL, 5743 getNetworkPermission(nai.networkCapabilities), 5744 false /* secure */, 5745 VpnManager.TYPE_VPN_NONE, 5746 false /* excludeLocalRoutes */); 5747 } 5748 mNetd.networkCreate(config); 5749 mDnsResolver.createNetworkCache(nai.network.getNetId()); 5750 mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), 5751 nai.networkCapabilities); 5752 return true; 5753 } catch (RemoteException | ServiceSpecificException e) { 5754 loge("Error creating network " + nai.toShortString() + ": " + e.getMessage()); 5755 return false; 5756 } 5757 } 5758 5759 private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 5760 if (mDscpPolicyTracker != null) { 5761 mDscpPolicyTracker.removeAllDscpPolicies(nai, false); 5762 } 5763 // Remove any forwarding rules to and from the interface for this network, since 5764 // the interface is going to go away. Don't send the callbacks however ; if the network 5765 // was is being disconnected the callbacks have already been sent, and if it is being 5766 // destroyed pending replacement they will be sent when it is disconnected. 5767 maybeDisableForwardRulesForDisconnectingNai(nai, false /* sendCallbacks */); 5768 updateIngressToVpnAddressFiltering(null, nai.linkProperties, nai); 5769 updateLocalNetworkAddresses(null, nai.linkProperties); 5770 try { 5771 mNetd.networkDestroy(nai.network.getNetId()); 5772 } catch (RemoteException | ServiceSpecificException e) { 5773 loge("Exception destroying network(networkDestroy): " + e); 5774 } 5775 try { 5776 mDnsResolver.destroyNetworkCache(nai.network.getNetId()); 5777 } catch (RemoteException | ServiceSpecificException e) { 5778 loge("Exception destroying network: " + e); 5779 } 5780 // TODO: defer calling this until the network is removed from mNetworkAgentInfos. 5781 // Otherwise, a private DNS configuration update for a destroyed network, or one that never 5782 // gets created, could add data to DnsManager data structures that will never get deleted. 5783 mDnsManager.removeNetwork(nai.network); 5784 5785 // clean up tc police filters on interface. 5786 if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) { 5787 mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName()); 5788 } 5789 5790 nai.setDestroyed(); 5791 nai.onNetworkDestroyed(); 5792 } 5793 5794 // If this method proves to be too slow then we can maintain a separate 5795 // pendingIntent => NetworkRequestInfo map. 5796 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. 5797 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 5798 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 5799 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 5800 if (existingPendingIntent != null && 5801 mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) { 5802 return entry.getValue(); 5803 } 5804 } 5805 return null; 5806 } 5807 5808 private void checkNrisConsistency(final NetworkRequestInfo nri) { 5809 if (mDeps.isAtLeastT()) { 5810 for (final NetworkRequestInfo n : mNetworkRequests.values()) { 5811 if (n.mBinder != null && n.mBinder == nri.mBinder) { 5812 // Temporary help to debug b/194394697 ; TODO : remove this function when the 5813 // bug is fixed. 5814 dumpAllRequestInfoLogsToLogcat(); 5815 throw new IllegalStateException("This NRI is already registered. New : " + nri 5816 + ", existing : " + n); 5817 } 5818 } 5819 } 5820 } 5821 5822 private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid, 5823 @NonNull final NetworkCapabilities caps) { 5824 if (mCarrierPrivilegeAuthenticator != null) { 5825 return mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities( 5826 callingUid, caps); 5827 } 5828 return false; 5829 } 5830 5831 private int getSubscriptionIdFromNetworkCaps(@NonNull final NetworkCapabilities caps) { 5832 if (mCarrierPrivilegeAuthenticator != null) { 5833 return mCarrierPrivilegeAuthenticator.getSubIdFromNetworkCapabilities(caps); 5834 } 5835 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 5836 } 5837 5838 private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) { 5839 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 5840 // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests. 5841 ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent"); 5842 final NetworkRequestInfo existingRequest = 5843 findExistingNetworkRequestInfo(nri.mPendingIntent); 5844 if (existingRequest != null) { // remove the existing request. 5845 if (DBG) { 5846 log("Replacing " + existingRequest.mRequests.get(0) + " with " 5847 + nri.mRequests.get(0) + " because their intents matched."); 5848 } 5849 handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(), 5850 /* callOnUnavailable */ false); 5851 } 5852 handleRegisterNetworkRequest(nri); 5853 } 5854 5855 private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5856 handleRegisterNetworkRequests(Collections.singleton(nri)); 5857 } 5858 5859 private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 5860 ensureRunningOnConnectivityServiceThread(); 5861 for (final NetworkRequestInfo nri : nris) { 5862 mNetworkRequestInfoLogs.log("REGISTER " + nri); 5863 checkNrisConsistency(nri); 5864 for (final NetworkRequest req : nri.mRequests) { 5865 mNetworkRequests.put(req, nri); 5866 // TODO: Consider update signal strength for other types. 5867 if (req.isListen()) { 5868 forEachNetworkAgentInfo(network -> { 5869 if (req.networkCapabilities.hasSignalStrength() 5870 && network.satisfiesImmutableCapabilitiesOf(req)) { 5871 updateSignalStrengthThresholds(network, "REGISTER", req); 5872 } 5873 }); 5874 } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) { 5875 mNetworkRequestStateStatsMetrics.onNetworkRequestReceived(req); 5876 } 5877 } 5878 5879 // If this NRI has a satisfier already, it is replacing an older request that 5880 // has been removed. Track it. 5881 final NetworkRequest activeRequest = nri.getActiveRequest(); 5882 if (null != activeRequest) { 5883 // If there is an active request, then for sure there is a satisfier. 5884 nri.getSatisfier().addRequest(activeRequest); 5885 } 5886 5887 if (shouldTrackUidsForBlockedStatusCallbacks() 5888 && nri.mMessenger != null 5889 && !nri.mUidTrackedForBlockedStatus) { 5890 Log.wtf(TAG, "Registered nri is not tracked for sending blocked status: " + nri); 5891 } 5892 } 5893 5894 if (mFlags.noRematchAllRequestsOnRegister()) { 5895 rematchNetworksAndRequests(nris); 5896 } else { 5897 rematchAllNetworksAndRequests(); 5898 } 5899 5900 // Requests that have not been matched to a network will not have been sent to the 5901 // providers, because the old satisfier and the new satisfier are the same (null in this 5902 // case). Send these requests to the providers. 5903 for (final NetworkRequestInfo nri : nris) { 5904 for (final NetworkOfferInfo noi : mNetworkOffers) { 5905 informOffer(nri, noi.offer, mNetworkRanker); 5906 } 5907 } 5908 } 5909 5910 private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent, 5911 final int callingUid) { 5912 final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 5913 if (nri != null) { 5914 // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests. 5915 ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent"); 5916 handleReleaseNetworkRequest( 5917 nri.mRequests.get(0), 5918 callingUid, 5919 /* callOnUnavailable */ false); 5920 } 5921 } 5922 5923 // Determines whether the network is the best (or could become the best, if it validated), for 5924 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 5925 // on the value of reason: 5926 // 5927 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 5928 // then it should be torn down. 5929 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 5930 // then it should be lingered. 5931 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 5932 ensureRunningOnConnectivityServiceThread(); 5933 5934 if (!nai.everConnected() || nai.isVPN() || nai.isInactive() 5935 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) { 5936 return false; 5937 } 5938 5939 final int numRequests; 5940 switch (reason) { 5941 case TEARDOWN: 5942 numRequests = nai.numRequestNetworkRequests(); 5943 break; 5944 case LINGER: 5945 numRequests = nai.numForegroundNetworkRequests(); 5946 break; 5947 default: 5948 Log.wtf(TAG, "Invalid reason. Cannot happen."); 5949 return true; 5950 } 5951 5952 if (numRequests > 0) return false; 5953 5954 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5955 if (reason == UnneededFor.LINGER 5956 && !nri.isMultilayerRequest() 5957 && nri.mRequests.get(0).isBackgroundRequest()) { 5958 // Background requests don't affect lingering. 5959 continue; 5960 } 5961 5962 if (isNetworkPotentialSatisfier(nai, nri)) { 5963 return false; 5964 } 5965 } 5966 return true; 5967 } 5968 5969 private boolean isNetworkPotentialSatisfier( 5970 @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) { 5971 // While destroyed network sometimes satisfy requests (including occasionally newly 5972 // satisfying requests), *potential* satisfiers are networks that might beat a current 5973 // champion if they validate. As such, a destroyed network is never a potential satisfier, 5974 // because it's never a good idea to keep a destroyed network in case it validates. 5975 // For example, declaring it a potential satisfier would keep an unvalidated destroyed 5976 // candidate after it's been replaced by another unvalidated network. 5977 if (candidate.isDestroyed()) return false; 5978 // Listen requests won't keep up a network satisfying it. If this is not a multilayer 5979 // request, return immediately. For multilayer requests, check to see if any of the 5980 // multilayer requests may have a potential satisfier. 5981 if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen() 5982 || nri.mRequests.get(0).isListenForBest())) { 5983 return false; 5984 } 5985 for (final NetworkRequest req : nri.mRequests) { 5986 // This multilayer listen request is satisfied therefore no further requests need to be 5987 // evaluated deeming this network not a potential satisfier. 5988 if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) { 5989 return false; 5990 } 5991 // As non-multilayer listen requests have already returned, the below would only happen 5992 // for a multilayer request therefore continue to the next request if available. 5993 if (req.isListen() || req.isListenForBest()) { 5994 continue; 5995 } 5996 // If there is hope for this network might validate and subsequently become the best 5997 // network for that request, then it is needed. Note that this network can't already 5998 // be the best for this request, or it would be the current satisfier, and therefore 5999 // there would be no need to call this method to find out if it is a *potential* 6000 // satisfier ("unneeded", the only caller, only calls this if this network currently 6001 // satisfies no request). 6002 if (candidate.satisfies(req)) { 6003 // As soon as a network is found that satisfies a request, return. Specifically for 6004 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request 6005 // is important so as to not evaluate lower priority requests further in 6006 // nri.mRequests. 6007 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest()) 6008 ? nri.getSatisfier() : null; 6009 // Note that this catches two important cases: 6010 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 6011 // is currently satisfying the request. This is desirable when 6012 // cellular ends up validating but WiFi does not. 6013 // 2. Unvalidated WiFi will not be reaped when validated cellular 6014 // is currently satisfying the request. This is desirable when 6015 // WiFi ends up validating and out scoring cellular. 6016 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable()); 6017 } 6018 } 6019 6020 return false; 6021 } 6022 6023 private NetworkRequestInfo getNriForAppRequest( 6024 NetworkRequest request, int callingUid, String requestedOperation) { 6025 // Looking up the app passed param request in mRequests isn't possible since it may return 6026 // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to 6027 // do the lookup since that will also find per-app default managed requests. 6028 // Additionally, this lookup needs to be relatively fast (hence the lookup optimization) 6029 // to avoid potential race conditions when validating a package->uid mapping when sending 6030 // the callback on the very low-chance that an application shuts down prior to the callback 6031 // being sent. 6032 final NetworkRequestInfo nri = mNetworkRequests.get(request) != null 6033 ? mNetworkRequests.get(request) : getNriForAppRequest(request); 6034 6035 if (nri != null) { 6036 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 6037 log(String.format("UID %d attempted to %s for unowned request %s", 6038 callingUid, requestedOperation, nri)); 6039 return null; 6040 } 6041 } 6042 6043 return nri; 6044 } 6045 6046 private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri, 6047 final String callingMethod) { 6048 if (nri.isMultilayerRequest()) { 6049 throw new IllegalStateException( 6050 callingMethod + " does not support multilayer requests."); 6051 } 6052 } 6053 6054 private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) { 6055 ensureRunningOnConnectivityServiceThread(); 6056 // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a 6057 // single NetworkRequest and thus does not apply to multilayer requests. 6058 ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest"); 6059 if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { 6060 return; 6061 } 6062 if (nri.isBeingSatisfied()) { 6063 return; 6064 } 6065 if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) { 6066 log("releasing " + nri.mRequests.get(0) + " (timeout)"); 6067 } 6068 handleRemoveNetworkRequest(nri); 6069 callCallbackForRequest(nri, null, CALLBACK_UNAVAIL, 0); 6070 } 6071 6072 private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request, 6073 final int callingUid, 6074 final boolean callOnUnavailable) { 6075 final NetworkRequestInfo nri = 6076 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 6077 if (nri == null) { 6078 return; 6079 } 6080 if (VDBG || (DBG && request.isRequest())) { 6081 log("releasing " + request + " (release request)"); 6082 } 6083 handleRemoveNetworkRequest(nri); 6084 if (callOnUnavailable) { 6085 callCallbackForRequest(nri, null, CALLBACK_UNAVAIL, 0); 6086 } 6087 } 6088 6089 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) { 6090 handleRemoveNetworkRequest(nri, true /* untrackUids */); 6091 } 6092 6093 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri, 6094 final boolean untrackUids) { 6095 ensureRunningOnConnectivityServiceThread(); 6096 for (final NetworkRequest req : nri.mRequests) { 6097 if (null == mNetworkRequests.remove(req)) { 6098 logw("Attempted removal of untracked request " + req + " for nri " + nri); 6099 continue; 6100 } 6101 if (req.isListen()) { 6102 removeListenRequestFromNetworks(req); 6103 } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) { 6104 mNetworkRequestStateStatsMetrics.onNetworkRequestRemoved(req); 6105 } 6106 } 6107 nri.unlinkDeathRecipient(); 6108 if (mDefaultNetworkRequests.remove(nri)) { 6109 // If this request was one of the defaults, then the UID rules need to be updated 6110 // WARNING : if the app(s) for which this network request is the default are doing 6111 // traffic, this will kill their connected sockets, even if an equivalent request 6112 // is going to be reinstated right away ; unconnected traffic will go on the default 6113 // until the new default is set, which will happen very soon. 6114 // TODO : The only way out of this is to diff old defaults and new defaults, and only 6115 // remove ranges for those requests that won't have a replacement 6116 final NetworkAgentInfo satisfier = nri.getSatisfier(); 6117 if (null != satisfier) { 6118 try { 6119 modifyNetworkUidRanges(false /* add */, satisfier, nri.getUids(), 6120 nri.getPreferenceOrderForNetd()); 6121 } catch (RemoteException e) { 6122 loge("Exception setting network preference default network", e); 6123 } 6124 } 6125 } 6126 6127 if (untrackUids) { 6128 maybeUntrackUidAndClearBlockedReasons(nri); 6129 } 6130 mNetworkRequestInfoLogs.log("RELEASE " + nri); 6131 checkNrisConsistency(nri); 6132 6133 if (null != nri.getActiveRequest()) { 6134 if (!nri.getActiveRequest().isListen()) { 6135 removeSatisfiedNetworkRequestFromNetwork(nri); 6136 } 6137 } 6138 6139 // For all outstanding offers, cancel any of the layers of this NRI that used to be 6140 // needed for this offer. 6141 for (final NetworkOfferInfo noi : mNetworkOffers) { 6142 for (final NetworkRequest req : nri.mRequests) { 6143 if (req.isRequest() && noi.offer.neededFor(req)) { 6144 noi.offer.onNetworkUnneeded(req); 6145 } 6146 } 6147 } 6148 } 6149 6150 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 6151 handleRemoveNetworkRequests(nris, true /* untrackUids */); 6152 } 6153 6154 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris, 6155 final boolean untrackUids) { 6156 for (final NetworkRequestInfo nri : nris) { 6157 if (mDefaultRequest == nri) { 6158 // Make sure we never remove the default request. 6159 continue; 6160 } 6161 handleRemoveNetworkRequest(nri, untrackUids); 6162 } 6163 } 6164 6165 private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) { 6166 // listens don't have a singular affected Network. Check all networks to see 6167 // if this listen request applies and remove it. 6168 forEachNetworkAgentInfo(nai -> { 6169 nai.removeRequest(req.requestId); 6170 if (req.networkCapabilities.hasSignalStrength() 6171 && nai.satisfiesImmutableCapabilitiesOf(req)) { 6172 updateSignalStrengthThresholds(nai, "RELEASE", req); 6173 } 6174 }); 6175 } 6176 6177 /** 6178 * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and 6179 * manage the necessary upkeep (linger, teardown networks, etc.) when doing so. 6180 * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo 6181 */ 6182 private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) { 6183 boolean wasKept = false; 6184 final NetworkAgentInfo nai = nri.getSatisfier(); 6185 if (nai != null) { 6186 final int requestLegacyType = nri.getActiveRequest().legacyType; 6187 final boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 6188 nai.removeRequest(nri.getActiveRequest().requestId); 6189 if (VDBG || DDBG) { 6190 log(" Removing from current network " + nai.toShortString() 6191 + ", leaving " + nai.numNetworkRequests() + " requests."); 6192 } 6193 // If there are still lingered requests on this network, don't tear it down, 6194 // but resume lingering instead. 6195 final long now = SystemClock.elapsedRealtime(); 6196 if (updateInactivityState(nai, now)) { 6197 notifyNetworkLosing(nai, now); 6198 } 6199 if (unneeded(nai, UnneededFor.TEARDOWN)) { 6200 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting"); 6201 teardownUnneededNetwork(nai); 6202 } else { 6203 wasKept = true; 6204 } 6205 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 6206 // Went from foreground to background. 6207 updateCapabilitiesForNetwork(nai); 6208 } 6209 6210 // Maintain the illusion. When this request arrived, we might have pretended 6211 // that a network connected to serve it, even though the network was already 6212 // connected. Now that this request has gone away, we might have to pretend 6213 // that the network disconnected. LegacyTypeTracker will generate that 6214 // phantom disconnect for this type. 6215 if (requestLegacyType != TYPE_NONE) { 6216 boolean doRemove = true; 6217 if (wasKept) { 6218 // check if any of the remaining requests for this network are for the 6219 // same legacy type - if so, don't remove the nai 6220 for (int i = 0; i < nai.numNetworkRequests(); i++) { 6221 NetworkRequest otherRequest = nai.requestAt(i); 6222 if (otherRequest.legacyType == requestLegacyType 6223 && otherRequest.isRequest()) { 6224 if (DBG) log(" still have other legacy request - leaving"); 6225 doRemove = false; 6226 } 6227 } 6228 } 6229 6230 if (doRemove) { 6231 mLegacyTypeTracker.remove(requestLegacyType, nai, false); 6232 } 6233 } 6234 } 6235 } 6236 6237 /** 6238 * Perform the specified operation on all networks. 6239 * 6240 * This method will run |op| exactly once for each network currently registered at the 6241 * time it is called, even if |op| adds or removes networks. 6242 * 6243 * @param op the operation to perform. The operation is allowed to disconnect any number of 6244 * networks. 6245 */ 6246 private void forEachNetworkAgentInfo(final Consumer<NetworkAgentInfo> op) { 6247 // Create a copy instead of iterating over the set so |op| is allowed to disconnect any 6248 // number of networks (which removes it from mNetworkAgentInfos). The copy is cheap 6249 // because there are at most a handful of NetworkAgents connected at any given time. 6250 final NetworkAgentInfo[] nais = new NetworkAgentInfo[mNetworkAgentInfos.size()]; 6251 mNetworkAgentInfos.toArray(nais); 6252 for (NetworkAgentInfo nai : nais) { 6253 op.accept(nai); 6254 } 6255 } 6256 6257 /** 6258 * Check whether the specified condition is true for any network. 6259 * 6260 * This method will stop evaluating as soon as the condition returns true for any network. 6261 * The order of iteration is not contractual. 6262 * 6263 * @param condition the condition to verify. This method must not modify the set of networks in 6264 * any way. 6265 * @return whether {@code condition} returned true for any network 6266 */ 6267 private boolean anyNetworkAgentInfo(final Predicate<NetworkAgentInfo> condition) { 6268 for (int i = mNetworkAgentInfos.size() - 1; i >= 0; i--) { 6269 if (condition.test(mNetworkAgentInfos.valueAt(i))) return true; 6270 } 6271 return false; 6272 } 6273 6274 private RequestInfoPerUidCounter getRequestCounter(NetworkRequestInfo nri) { 6275 return hasAnyPermissionOf(mContext, 6276 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) 6277 ? mSystemNetworkRequestCounter : mNetworkRequestCounter; 6278 } 6279 6280 @Override 6281 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 6282 enforceNetworkStackSettingsOrSetup(); 6283 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 6284 encodeBool(accept), encodeBool(always), network)); 6285 } 6286 6287 @Override 6288 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { 6289 enforceNetworkStackSettingsOrSetup(); 6290 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY, 6291 encodeBool(accept), encodeBool(always), network)); 6292 } 6293 6294 @Override 6295 public void setAvoidUnvalidated(Network network) { 6296 enforceNetworkStackSettingsOrSetup(); 6297 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 6298 } 6299 6300 @Override 6301 public void setTestAllowBadWifiUntil(long timeMs) { 6302 enforceSettingsPermission(); 6303 if (!Build.isDebuggable()) { 6304 throw new IllegalStateException("Does not support in non-debuggable build"); 6305 } 6306 6307 if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) { 6308 throw new IllegalArgumentException("It should not exceed " 6309 + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now"); 6310 } 6311 6312 mHandler.sendMessage( 6313 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs)); 6314 } 6315 6316 @Override 6317 public void setTestLowTcpPollingTimerForKeepalive(long timeMs) { 6318 enforceSettingsPermission(); 6319 6320 if (timeMs > System.currentTimeMillis() + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS) { 6321 throw new IllegalArgumentException("Argument should not exceed " 6322 + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS + "ms from now"); 6323 } 6324 6325 mHandler.sendMessage( 6326 mHandler.obtainMessage(EVENT_SET_LOW_TCP_POLLING_UNTIL, timeMs)); 6327 } 6328 6329 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 6330 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 6331 " accept=" + accept + " always=" + always); 6332 6333 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6334 if (nai == null) { 6335 // Nothing to do. 6336 return; 6337 } 6338 6339 if (nai.everValidated()) { 6340 // The network validated while the dialog box was up. Take no action. 6341 return; 6342 } 6343 6344 if (!nai.networkAgentConfig.explicitlySelected) { 6345 Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 6346 } 6347 6348 if (accept != nai.networkAgentConfig.acceptUnvalidated) { 6349 nai.networkAgentConfig.acceptUnvalidated = accept; 6350 // If network becomes partial connectivity and user already accepted to use this 6351 // network, we should respect the user's option and don't need to popup the 6352 // PARTIAL_CONNECTIVITY notification to user again. 6353 nai.networkAgentConfig.acceptPartialConnectivity = accept; 6354 nai.updateScoreForNetworkAgentUpdate(); 6355 rematchAllNetworksAndRequests(); 6356 } 6357 6358 if (always) { 6359 nai.onSaveAcceptUnvalidated(accept); 6360 } 6361 6362 if (!accept) { 6363 // Tell the NetworkAgent to not automatically reconnect to the network. 6364 nai.onPreventAutomaticReconnect(); 6365 // Teardown the network. 6366 teardownUnneededNetwork(nai); 6367 } 6368 6369 } 6370 6371 private void handleSetAcceptPartialConnectivity(Network network, boolean accept, 6372 boolean always) { 6373 if (DBG) { 6374 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept 6375 + " always=" + always); 6376 } 6377 6378 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6379 if (nai == null) { 6380 // Nothing to do. 6381 return; 6382 } 6383 6384 if (nai.isValidated()) { 6385 // The network validated while the dialog box was up. Take no action. 6386 return; 6387 } 6388 6389 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) { 6390 nai.networkAgentConfig.acceptPartialConnectivity = accept; 6391 } 6392 6393 // TODO: Use the current design or save the user choice into IpMemoryStore. 6394 if (always) { 6395 nai.onSaveAcceptUnvalidated(accept); 6396 } 6397 6398 if (!accept) { 6399 // Tell the NetworkAgent to not automatically reconnect to the network. 6400 nai.onPreventAutomaticReconnect(); 6401 // Tear down the network. 6402 teardownUnneededNetwork(nai); 6403 } else { 6404 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely 6405 // result in a partial connectivity result which will be processed by 6406 // maybeHandleNetworkMonitorMessage. 6407 // 6408 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored 6409 // per network. Therefore, NetworkMonitor may still do https probe. 6410 nai.networkMonitor().setAcceptPartialConnectivity(); 6411 } 6412 } 6413 6414 private void handleSetAvoidUnvalidated(Network network) { 6415 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6416 if (nai == null || nai.isValidated()) { 6417 // Nothing to do. The network either disconnected or revalidated. 6418 return; 6419 } 6420 if (0L == nai.getAvoidUnvalidated()) { 6421 nai.setAvoidUnvalidated(); 6422 nai.updateScoreForNetworkAgentUpdate(); 6423 rematchAllNetworksAndRequests(); 6424 } 6425 } 6426 6427 /** Schedule evaluation timeout */ 6428 @VisibleForTesting 6429 public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) { 6430 mDeps.scheduleEvaluationTimeout(mHandler, network, delayMs); 6431 } 6432 6433 @Override 6434 public void startCaptivePortalApp(Network network) { 6435 enforceNetworkStackOrSettingsPermission(); 6436 mHandler.post(() -> { 6437 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6438 if (nai == null) return; 6439 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 6440 nai.networkMonitor().launchCaptivePortalApp(); 6441 }); 6442 } 6443 6444 /** 6445 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this 6446 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. 6447 * @param network Network on which the captive portal was detected. 6448 * @param appExtras Bundle to use as intent extras for the captive portal application. 6449 * Must be treated as opaque to avoid preventing the captive portal app to 6450 * update its arguments. 6451 */ 6452 @Override 6453 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { 6454 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 6455 "ConnectivityService"); 6456 6457 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); 6458 appIntent.putExtras(appExtras); 6459 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, 6460 new CaptivePortal(new CaptivePortalImpl(network).asBinder())); 6461 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); 6462 6463 final long token = Binder.clearCallingIdentity(); 6464 try { 6465 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT); 6466 } finally { 6467 Binder.restoreCallingIdentity(token); 6468 } 6469 } 6470 6471 public class CaptivePortalImpl extends ICaptivePortal.Stub implements IBinder.DeathRecipient { 6472 private final Network mNetwork; 6473 // Binder object to track the lifetime of the setDelegateUid caller for cleanup purposes. 6474 // 6475 // Note that in theory it can happen that there are multiple callers for a given 6476 // object. For example, the app that receives the CaptivePortal object from the Intent 6477 // fired by startCaptivePortalAppInternal could send the object to another process, or 6478 // clone it. Only the first of these objects that calls setDelegateUid will properly 6479 // register a death recipient. Calls from the other objects will work, but only the 6480 // first object's death will cause the death recipient to fire. 6481 // TODO: track all callers by callerBinder instead of CaptivePortalImpl, store callerBinder 6482 // in a Set. When the death recipient fires, we can remove the callingBinder from the set, 6483 // and when the set is empty, we can clear the delegated UID. 6484 private IBinder mDelegateUidCaller; 6485 6486 private CaptivePortalImpl(Network network) { 6487 mNetwork = network; 6488 } 6489 6490 @Override 6491 public void appResponse(final int response) { 6492 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { 6493 enforceSettingsPermission(); 6494 } else if (response == CaptivePortal.APP_RETURN_UNWANTED) { 6495 mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork)); 6496 // Since the network will be disconnected, skip notifying NetworkMonitor 6497 return; 6498 } 6499 6500 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 6501 if (nm == null) return; 6502 nm.notifyCaptivePortalAppFinished(response); 6503 } 6504 6505 @Override 6506 public void appRequest(final int request) { 6507 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 6508 if (nm == null) return; 6509 6510 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) { 6511 // This enforceNetworkStackPermission() should be adopted to check 6512 // the required permission but this may be break OEM captive portal 6513 // apps. Simply ignore the request if the caller does not have 6514 // permission. 6515 if (!hasNetworkStackPermission()) { 6516 Log.e(TAG, "Calling appRequest() without proper permission. Skip"); 6517 return; 6518 } 6519 6520 nm.forceReevaluation(mDeps.getCallingUid()); 6521 } 6522 } 6523 6524 private int handleSetDelegateUid(int uid, @NonNull final IBinder callerBinder) { 6525 if (mDelegateUidCaller == null) { 6526 mDelegateUidCaller = callerBinder; 6527 try { 6528 // While technically unnecessary, it is safe to register a DeathRecipient for 6529 // a cleanup operation (where uid = INVALID_UID). 6530 mDelegateUidCaller.linkToDeath(this, 0); 6531 } catch (RemoteException e) { 6532 // remote has died, return early. 6533 return ENOTCONN; 6534 } 6535 } 6536 6537 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork); 6538 if (nai == null) return ENOENT; // network does not exist anymore. 6539 if (nai.isDestroyed()) return ENOENT; // network has already been destroyed. 6540 6541 // TODO: consider allowing the uid to bypass VPN on all networks before V. 6542 if (!mDeps.isAtLeastV()) return EOPNOTSUPP; 6543 6544 // Check whether there has already been a delegate UID configured, if so, perform 6545 // cleanup and disallow bypassing VPN for that UID if no other caller is delegating 6546 // this UID. 6547 // TODO: consider using exceptions instead of errnos. 6548 final int errno = nai.removeCaptivePortalDelegateUid(this); 6549 if (errno != 0) return errno; 6550 6551 // If uid == INVALID_UID, we are done. 6552 if (uid == INVALID_UID) return 0; 6553 return nai.setCaptivePortalDelegateUid(this, uid); 6554 } 6555 6556 @Override 6557 public void setDelegateUid(int uid, @NonNull final IBinder callerBinder, 6558 @NonNull final IIntResultListener listener) { 6559 Objects.requireNonNull(callerBinder); 6560 Objects.requireNonNull(listener); 6561 enforceAnyPermissionOf(mContext, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 6562 6563 mHandler.post(() -> { 6564 final int errno = handleSetDelegateUid(uid, callerBinder); 6565 try { 6566 listener.onResult(errno); 6567 } catch (RemoteException e) { 6568 // remote has died, nothing to do. 6569 } 6570 }); 6571 } 6572 6573 @Nullable 6574 private NetworkMonitorManager getNetworkMonitorManager(final Network network) { 6575 // getNetworkAgentInfoForNetwork is thread-safe 6576 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6577 if (nai == null) return null; 6578 6579 // nai.networkMonitor() is thread-safe 6580 return nai.networkMonitor(); 6581 } 6582 6583 @Override 6584 public void binderDied() { 6585 // Cleanup invalid UID and restore the VPN bypass rule. Because mDelegateUidCaller is 6586 // never reset, it cannot be null in this context. 6587 mHandler.post(() -> handleSetDelegateUid(INVALID_UID, mDelegateUidCaller)); 6588 } 6589 } 6590 6591 public boolean avoidBadWifi() { 6592 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 6593 } 6594 6595 private boolean activelyPreferBadWifi() { 6596 return mMultinetworkPolicyTracker.getActivelyPreferBadWifi(); 6597 } 6598 6599 /** 6600 * Return whether the device should maintain continuous, working connectivity by switching away 6601 * from WiFi networks having no connectivity. 6602 * @see MultinetworkPolicyTracker#getAvoidBadWifi() 6603 */ 6604 public boolean shouldAvoidBadWifi() { 6605 if (!hasNetworkStackPermission()) { 6606 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); 6607 } 6608 return avoidBadWifi(); 6609 } 6610 6611 private void updateAvoidBadWifi() { 6612 ensureRunningOnConnectivityServiceThread(); 6613 // Agent info scores and offer scores depend on whether cells yields to bad wifi. 6614 final boolean avoidBadWifi = avoidBadWifi(); 6615 forEachNetworkAgentInfo(nai -> { 6616 nai.updateScoreForNetworkAgentUpdate(); 6617 if (avoidBadWifi) { 6618 // If the device is now avoiding bad wifi, remove notifications that might have 6619 // been put up when the device didn't. 6620 mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET); 6621 } 6622 }); 6623 // UpdateOfferScore will update mNetworkOffers inline, so make a copy first. 6624 final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers); 6625 for (final NetworkOfferInfo noi : offersToUpdate) { 6626 updateOfferScore(noi.offer); 6627 } 6628 mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi())); 6629 rematchAllNetworksAndRequests(); 6630 } 6631 6632 // TODO: Evaluate whether this is of interest to other consumers of 6633 // MultinetworkPolicyTracker and worth moving out of here. 6634 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 6635 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 6636 if (!configRestrict) { 6637 pw.println("Bad Wi-Fi avoidance: unrestricted"); 6638 return; 6639 } 6640 6641 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 6642 pw.increaseIndent(); 6643 pw.println("Config restrict: " + configRestrict); 6644 pw.println("Actively prefer bad wifi: " + activelyPreferBadWifi()); 6645 6646 final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 6647 String description; 6648 // Can't use a switch statement because strings are legal case labels, but null is not. 6649 if ("0".equals(settingValue)) { 6650 description = "get stuck"; 6651 } else if (settingValue == null) { 6652 description = "prompt"; 6653 } else if ("1".equals(settingValue)) { 6654 description = "avoid"; 6655 } else { 6656 description = settingValue + " (?)"; 6657 } 6658 pw.println("Avoid bad wifi setting: " + description); 6659 6660 final Boolean configValue = BinderUtils.withCleanCallingIdentity( 6661 () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi()); 6662 if (null == configValue) { 6663 description = "unset"; 6664 } else if (configValue) { 6665 description = "force true"; 6666 } else { 6667 description = "force false"; 6668 } 6669 pw.println("Actively prefer bad wifi conf: " + description); 6670 pw.println(); 6671 pw.println("Network overrides:"); 6672 pw.increaseIndent(); 6673 for (NetworkAgentInfo nai : networksSortedById()) { 6674 if (0L != nai.getAvoidUnvalidated()) { 6675 pw.println(nai.toShortString()); 6676 } 6677 } 6678 pw.decreaseIndent(); 6679 pw.decreaseIndent(); 6680 } 6681 6682 // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to 6683 // unify the method. 6684 private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) { 6685 final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS); 6686 final ComponentName settingsComponent = settingsIntent.resolveActivity(pm); 6687 return settingsComponent != null 6688 ? settingsComponent.getPackageName() : "com.android.settings"; 6689 } 6690 6691 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) { 6692 final String action; 6693 final boolean highPriority; 6694 switch (type) { 6695 case NO_INTERNET: 6696 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 6697 // High priority because it is only displayed for explicitly selected networks. 6698 highPriority = true; 6699 break; 6700 case PRIVATE_DNS_BROKEN: 6701 action = Settings.ACTION_WIRELESS_SETTINGS; 6702 // High priority because we should let user know why there is no internet. 6703 highPriority = true; 6704 break; 6705 case LOST_INTERNET: 6706 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 6707 // High priority because it could help the user avoid unexpected data usage. 6708 highPriority = true; 6709 break; 6710 case PARTIAL_CONNECTIVITY: 6711 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY; 6712 // Don't bother the user with a high-priority notification if the network was not 6713 // explicitly selected by the user. 6714 highPriority = nai.networkAgentConfig.explicitlySelected; 6715 break; 6716 default: 6717 Log.wtf(TAG, "Unknown notification type " + type); 6718 return; 6719 } 6720 6721 Intent intent = new Intent(action); 6722 if (type != NotificationType.PRIVATE_DNS_BROKEN) { 6723 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network); 6724 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 6725 // Some OEMs have their own Settings package. Thus, need to get the current using 6726 // Settings package name instead of just use default name "com.android.settings". 6727 final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager()); 6728 intent.setClassName(settingsPkgName, 6729 settingsPkgName + ".wifi.WifiNoInternetDialog"); 6730 } 6731 6732 PendingIntent pendingIntent = PendingIntent.getActivity( 6733 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 6734 0 /* requestCode */, 6735 intent, 6736 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 6737 6738 mNotifier.showNotification( 6739 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority); 6740 } 6741 6742 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) { 6743 // Don't prompt if the network is validated, and don't prompt on captive portals 6744 // because we're already prompting the user to sign in. 6745 if (nai.everValidated() || nai.everCaptivePortalDetected()) { 6746 return false; 6747 } 6748 6749 // If a network has partial connectivity, always prompt unless the user has already accepted 6750 // partial connectivity and selected don't ask again. This ensures that if the device 6751 // automatically connects to a network that has partial Internet access, the user will 6752 // always be able to use it, either because they've already chosen "don't ask again" or 6753 // because we have prompted them. 6754 if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) { 6755 return true; 6756 } 6757 6758 // If a network has no Internet access, only prompt if the network was explicitly selected 6759 // and if the user has not already told us to use the network regardless of whether it 6760 // validated or not. 6761 if (nai.networkAgentConfig.explicitlySelected 6762 && !nai.networkAgentConfig.acceptUnvalidated) { 6763 return true; 6764 } 6765 6766 return false; 6767 } 6768 6769 private void handleInitialEvaluationTimeout(@NonNull final Network network) { 6770 if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network); 6771 6772 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6773 if (null == nai) return; 6774 6775 if (nai.setEvaluated()) { 6776 // If setEvaluated() returned true, the network never had any form of connectivity. 6777 // This may have an impact on request matching if bad WiFi avoidance is off and the 6778 // network was found not to have Internet access. 6779 nai.updateScoreForNetworkAgentUpdate(); 6780 rematchAllNetworksAndRequests(); 6781 6782 // Also, if this is WiFi and it should be preferred actively, now is the time to 6783 // prompt the user that they walked past and connected to a bad WiFi. 6784 if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI) 6785 && !avoidBadWifi() 6786 && activelyPreferBadWifi()) { 6787 // The notification will be removed if the network validates or disconnects. 6788 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 6789 return; 6790 } 6791 } 6792 6793 if (!shouldPromptUnvalidated(nai)) return; 6794 6795 // Stop automatically reconnecting to this network in the future. Automatically connecting 6796 // to a network that provides no or limited connectivity is not useful, because the user 6797 // cannot use that network except through the notification shown by this method, and the 6798 // notification is only shown if the network is explicitly selected by the user. 6799 nai.onPreventAutomaticReconnect(); 6800 6801 if (nai.partialConnectivity()) { 6802 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); 6803 } else { 6804 showNetworkNotification(nai, NotificationType.NO_INTERNET); 6805 } 6806 } 6807 6808 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 6809 NetworkCapabilities nc = nai.networkCapabilities; 6810 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc); 6811 6812 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 6813 return; 6814 } 6815 6816 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 6817 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 6818 } 6819 } 6820 6821 @Override 6822 public int getMultipathPreference(Network network) { 6823 enforceAccessPermission(); 6824 6825 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6826 if (nai != null && nai.networkCapabilities 6827 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 6828 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 6829 } 6830 6831 final NetworkPolicyManager netPolicyManager = 6832 mContext.getSystemService(NetworkPolicyManager.class); 6833 6834 final long token = Binder.clearCallingIdentity(); 6835 final int networkPreference; 6836 try { 6837 networkPreference = netPolicyManager.getMultipathPreference(network); 6838 } finally { 6839 Binder.restoreCallingIdentity(token); 6840 } 6841 if (networkPreference != 0) { 6842 return networkPreference; 6843 } 6844 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 6845 } 6846 6847 @Override 6848 public NetworkRequest getDefaultRequest() { 6849 return mDefaultRequest.mRequests.get(0); 6850 } 6851 6852 private class InternalHandler extends Handler { 6853 public InternalHandler(Looper looper) { 6854 super(looper); 6855 } 6856 6857 @Override 6858 public void handleMessage(Message msg) { 6859 switch (msg.what) { 6860 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 6861 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 6862 handleReleaseNetworkTransitionWakelock(msg.what); 6863 break; 6864 } 6865 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 6866 mProxyTracker.loadDeprecatedGlobalHttpProxy(); 6867 break; 6868 } 6869 case EVENT_PAC_PROXY_HAS_CHANGED: { 6870 final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj; 6871 handlePacProxyServiceStarted(arg.first, arg.second); 6872 break; 6873 } 6874 case EVENT_REGISTER_NETWORK_PROVIDER: { 6875 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); 6876 break; 6877 } 6878 case EVENT_UNREGISTER_NETWORK_PROVIDER: { 6879 handleUnregisterNetworkProvider((Messenger) msg.obj); 6880 break; 6881 } 6882 case EVENT_REGISTER_NETWORK_OFFER: { 6883 handleRegisterNetworkOffer((NetworkOffer) msg.obj); 6884 break; 6885 } 6886 case EVENT_UNREGISTER_NETWORK_OFFER: { 6887 final NetworkOfferInfo offer = 6888 findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj); 6889 if (null != offer) { 6890 handleUnregisterNetworkOffer(offer, true /* releaseReservations */); 6891 } 6892 break; 6893 } 6894 case EVENT_REGISTER_NETWORK_AGENT: { 6895 final Pair<NetworkAgentInfo, INetworkMonitor> arg = 6896 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; 6897 handleRegisterNetworkAgent(arg.first, arg.second); 6898 break; 6899 } 6900 case EVENT_REGISTER_NETWORK_REQUEST: 6901 case EVENT_REGISTER_NETWORK_LISTENER: { 6902 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 6903 break; 6904 } 6905 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 6906 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 6907 handleRegisterNetworkRequestWithIntent(msg); 6908 break; 6909 } 6910 case EVENT_TIMEOUT_NETWORK_REQUEST: { 6911 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 6912 handleTimedOutNetworkRequest(nri); 6913 break; 6914 } 6915 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 6916 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 6917 break; 6918 } 6919 case EVENT_RELEASE_NETWORK_REQUEST: { 6920 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1, 6921 /* callOnUnavailable */ false); 6922 break; 6923 } 6924 case EVENT_SET_ACCEPT_UNVALIDATED: { 6925 Network network = (Network) msg.obj; 6926 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 6927 break; 6928 } 6929 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: { 6930 Network network = (Network) msg.obj; 6931 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1), 6932 toBool(msg.arg2)); 6933 break; 6934 } 6935 case EVENT_SET_AVOID_UNVALIDATED: { 6936 handleSetAvoidUnvalidated((Network) msg.obj); 6937 break; 6938 } 6939 case EVENT_INITIAL_EVALUATION_TIMEOUT: { 6940 handleInitialEvaluationTimeout((Network) msg.obj); 6941 break; 6942 } 6943 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { 6944 handleConfigureAlwaysOnNetworks(); 6945 break; 6946 } 6947 // Sent by AutomaticOnOffKeepaliveTracker to process an app request on the 6948 // handler thread. 6949 case AutomaticOnOffKeepaliveTracker.CMD_REQUEST_START_KEEPALIVE: { 6950 mKeepaliveTracker.handleStartKeepalive(msg); 6951 break; 6952 } 6953 case AutomaticOnOffKeepaliveTracker.CMD_MONITOR_AUTOMATIC_KEEPALIVE: { 6954 final AutomaticOnOffKeepalive ki = 6955 mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj); 6956 if (null == ki) return; // The callback was unregistered before the alarm fired 6957 6958 final Network underpinnedNetwork = ki.getUnderpinnedNetwork(); 6959 final Network network = ki.getNetwork(); 6960 final boolean networkFound = 6961 anyNetworkAgentInfo(n -> n.network.equals(network)); 6962 6963 // If the network no longer exists, then the keepalive should have been 6964 // cleaned up already. There is no point trying to resume keepalives. 6965 if (!networkFound) return; 6966 6967 final boolean underpinnedNetworkFound = anyNetworkAgentInfo( 6968 n -> n.everConnected() && n.network.equals(underpinnedNetwork)); 6969 if (underpinnedNetworkFound) { 6970 mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki, 6971 underpinnedNetwork.netId); 6972 } else { 6973 // If no underpinned network, then make sure the keepalive is running. 6974 mKeepaliveTracker.handleMaybeResumeKeepalive(ki); 6975 } 6976 break; 6977 } 6978 // Sent by KeepaliveTracker to process an app request on the state machine thread. 6979 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: { 6980 final AutomaticOnOffKeepalive ki = mKeepaliveTracker.getKeepaliveForBinder( 6981 (IBinder) msg.obj); 6982 if (ki == null) { 6983 Log.e(TAG, "Attempt to stop an already stopped keepalive"); 6984 return; 6985 } 6986 final int reason = msg.arg2; 6987 mKeepaliveTracker.handleStopKeepalive(ki, reason); 6988 break; 6989 } 6990 case EVENT_REPORT_NETWORK_CONNECTIVITY: { 6991 handleReportNetworkConnectivity((NetworkAgentInfo) msg.obj, msg.arg1, 6992 toBool(msg.arg2)); 6993 break; 6994 } 6995 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 6996 handlePrivateDnsSettingsChanged(); 6997 break; 6998 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 6999 handlePrivateDnsValidationUpdate( 7000 (PrivateDnsValidationUpdate) msg.obj); 7001 break; 7002 case EVENT_BLOCKED_REASONS_CHANGED: 7003 handleBlockedReasonsChanged((List) msg.obj); 7004 break; 7005 case EVENT_SET_REQUIRE_VPN_FOR_UIDS: 7006 handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); 7007 break; 7008 case EVENT_SET_OEM_NETWORK_PREFERENCE: { 7009 final Pair<OemNetworkPreferences, IOnCompleteListener> arg = 7010 (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj; 7011 handleSetOemNetworkPreference(arg.first, arg.second); 7012 break; 7013 } 7014 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: { 7015 final Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener> arg = 7016 (Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener>) msg.obj; 7017 handleSetProfileNetworkPreference(arg.first, arg.second); 7018 break; 7019 } 7020 case EVENT_REPORT_NETWORK_ACTIVITY: 7021 final NetworkActivityParams arg = (NetworkActivityParams) msg.obj; 7022 handleReportNetworkActivity(arg); 7023 break; 7024 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED: 7025 handleMobileDataPreferredUidsChanged(); 7026 break; 7027 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL: 7028 final long timeMs = ((Long) msg.obj).longValue(); 7029 mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs); 7030 break; 7031 case EVENT_INGRESS_RATE_LIMIT_CHANGED: 7032 handleIngressRateLimitChanged(); 7033 break; 7034 case EVENT_USER_DOES_NOT_WANT: 7035 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 7036 if (nai == null) break; 7037 nai.onPreventAutomaticReconnect(); 7038 if (mQueueNetworkAgentEventsInSystemServer) { 7039 disconnectAndDestroyNetwork(nai); 7040 } else { 7041 nai.disconnect(); 7042 } 7043 break; 7044 case EVENT_SET_VPN_NETWORK_PREFERENCE: 7045 handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj); 7046 break; 7047 case EVENT_SET_LOW_TCP_POLLING_UNTIL: { 7048 final long time = ((Long) msg.obj).longValue(); 7049 mKeepaliveTracker.handleSetTestLowTcpPollingTimer(time); 7050 break; 7051 } 7052 case EVENT_UID_FROZEN_STATE_CHANGED: 7053 UidFrozenStateChangedArgs args = (UidFrozenStateChangedArgs) msg.obj; 7054 handleFrozenUids(args.mUids, args.mFrozenStates); 7055 break; 7056 case EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS: 7057 handleUpdateFirewallDestroySocketReasons((List) msg.obj); 7058 break; 7059 case EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS: 7060 handleClearFirewallDestroySocketReasons(msg.arg1); 7061 break; 7062 } 7063 } 7064 } 7065 7066 @Override 7067 @Deprecated 7068 public int getLastTetherError(String iface) { 7069 enforceAccessPermission(); 7070 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7071 Context.TETHERING_SERVICE); 7072 return tm.getLastTetherError(iface); 7073 } 7074 7075 @Override 7076 @Deprecated 7077 public String[] getTetherableIfaces() { 7078 enforceAccessPermission(); 7079 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7080 Context.TETHERING_SERVICE); 7081 return tm.getTetherableIfaces(); 7082 } 7083 7084 @Override 7085 @Deprecated 7086 public String[] getTetheredIfaces() { 7087 enforceAccessPermission(); 7088 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7089 Context.TETHERING_SERVICE); 7090 return tm.getTetheredIfaces(); 7091 } 7092 7093 7094 @Override 7095 @Deprecated 7096 public String[] getTetheringErroredIfaces() { 7097 enforceAccessPermission(); 7098 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7099 Context.TETHERING_SERVICE); 7100 7101 return tm.getTetheringErroredIfaces(); 7102 } 7103 7104 @Override 7105 @Deprecated 7106 public String[] getTetherableUsbRegexs() { 7107 enforceAccessPermission(); 7108 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7109 Context.TETHERING_SERVICE); 7110 7111 return tm.getTetherableUsbRegexs(); 7112 } 7113 7114 @Override 7115 @Deprecated 7116 public String[] getTetherableWifiRegexs() { 7117 enforceAccessPermission(); 7118 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 7119 Context.TETHERING_SERVICE); 7120 return tm.getTetherableWifiRegexs(); 7121 } 7122 7123 // Called when we lose the default network and have no replacement yet. 7124 // This will automatically be cleared after X seconds or a new default network 7125 // becomes CONNECTED, whichever happens first. The timer is started by the 7126 // first caller and not restarted by subsequent callers. 7127 private void ensureNetworkTransitionWakelock(String forWhom) { 7128 synchronized (this) { 7129 if (mNetTransitionWakeLock.isHeld()) { 7130 return; 7131 } 7132 mNetTransitionWakeLock.acquire(); 7133 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 7134 mTotalWakelockAcquisitions++; 7135 } 7136 mWakelockLogs.log("ACQUIRE for " + forWhom); 7137 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 7138 final int lockTimeout = mResources.get().getInteger( 7139 R.integer.config_networkTransitionTimeout); 7140 mHandler.sendMessageDelayed(msg, lockTimeout); 7141 } 7142 7143 // Called when we gain a new default network to release the network transition wakelock in a 7144 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 7145 // message is cancelled. 7146 private void scheduleReleaseNetworkTransitionWakelock() { 7147 synchronized (this) { 7148 if (!mNetTransitionWakeLock.isHeld()) { 7149 return; // expiry message released the lock first. 7150 } 7151 } 7152 // Cancel self timeout on wakelock hold. 7153 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 7154 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 7155 mHandler.sendMessageDelayed(msg, 1000); 7156 } 7157 7158 // Called when either message of ensureNetworkTransitionWakelock or 7159 // scheduleReleaseNetworkTransitionWakelock is processed. 7160 private void handleReleaseNetworkTransitionWakelock(int eventId) { 7161 String event = eventName(eventId); 7162 synchronized (this) { 7163 if (!mNetTransitionWakeLock.isHeld()) { 7164 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 7165 Log.w(TAG, "expected Net Transition WakeLock to be held"); 7166 return; 7167 } 7168 mNetTransitionWakeLock.release(); 7169 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 7170 mTotalWakelockDurationMs += lockDuration; 7171 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 7172 mTotalWakelockReleases++; 7173 } 7174 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 7175 } 7176 7177 // 100 percent is full good, 0 is full bad. 7178 @Override 7179 public void reportInetCondition(int networkType, int percentage) { 7180 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 7181 if (nai == null) return; 7182 reportNetworkConnectivity(nai.network, percentage > 50); 7183 } 7184 7185 @Override 7186 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 7187 enforceAccessPermission(); 7188 enforceInternetPermission(); 7189 final int uid = mDeps.getCallingUid(); 7190 final int connectivityInfo = encodeBool(hasConnectivity); 7191 7192 final NetworkAgentInfo nai; 7193 if (network == null) { 7194 nai = getDefaultNetwork(); 7195 } else { 7196 nai = getNetworkAgentInfoForNetwork(network); 7197 } 7198 7199 mHandler.sendMessage( 7200 mHandler.obtainMessage( 7201 EVENT_REPORT_NETWORK_CONNECTIVITY, uid, connectivityInfo, nai)); 7202 } 7203 7204 private void handleReportNetworkConnectivity( 7205 @Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) { 7206 if (nai == null 7207 || nai != getNetworkAgentInfoForNetwork(nai.network) 7208 || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 7209 return; 7210 } 7211 // Revalidate if the app report does not match our current validated state. 7212 if (hasConnectivity == nai.isValidated()) { 7213 mConnectivityDiagnosticsHandler.sendMessage( 7214 mConnectivityDiagnosticsHandler.obtainMessage( 7215 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 7216 new ReportedNetworkConnectivityInfo( 7217 hasConnectivity, false /* isNetworkRevalidating */, uid, nai))); 7218 return; 7219 } 7220 if (DBG) { 7221 int netid = nai.network.getNetId(); 7222 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 7223 } 7224 // Validating a network that has not yet connected could result in a call to 7225 // rematchNetworkAndRequests() which is not meant to work on such networks. 7226 if (!nai.everConnected()) { 7227 return; 7228 } 7229 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 7230 if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) { 7231 return; 7232 } 7233 7234 // Send CONNECTIVITY_REPORTED event before re-validating the Network to force an ordering of 7235 // ConnDiags events. This ensures that #onNetworkConnectivityReported() will be called 7236 // before #onConnectivityReportAvailable(), which is called once Network evaluation is 7237 // completed. 7238 mConnectivityDiagnosticsHandler.sendMessage( 7239 mConnectivityDiagnosticsHandler.obtainMessage( 7240 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 7241 new ReportedNetworkConnectivityInfo( 7242 hasConnectivity, true /* isNetworkRevalidating */, uid, nai))); 7243 nai.networkMonitor().forceReevaluation(uid); 7244 } 7245 7246 // TODO: call into netd. 7247 private boolean queryUserAccess(int uid, Network network) { 7248 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 7249 if (nai == null) return false; 7250 7251 // Any UID can use its default network. 7252 if (nai == getDefaultNetworkForUid(uid)) return true; 7253 7254 // Privileged apps can use any network. 7255 if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) { 7256 return true; 7257 } 7258 7259 // An unprivileged UID can use a VPN iff the VPN applies to it. 7260 if (nai.isVPN()) { 7261 return nai.networkCapabilities.appliesToUid(uid); 7262 } 7263 7264 // An unprivileged UID can bypass the VPN that applies to it only if it can protect its 7265 // sockets, i.e., if it is the owner. 7266 final NetworkAgentInfo vpn = getVpnForUid(uid); 7267 if (vpn != null && !vpn.networkAgentConfig.allowBypass 7268 && uid != vpn.networkCapabilities.getOwnerUid()) { 7269 return false; 7270 } 7271 7272 // The UID's permission must be at least sufficient for the network. Since the restricted 7273 // permission was already checked above, that just leaves background networks. 7274 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { 7275 return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid); 7276 } 7277 7278 // Unrestricted network. Anyone gets to use it. 7279 return true; 7280 } 7281 7282 /** 7283 * Returns information about the proxy a certain network is using. If given a null network, it 7284 * it will return the proxy for the bound network for the caller app or the default proxy if 7285 * none. 7286 * 7287 * @param network the network we want to get the proxy information for. 7288 * @return Proxy information if a network has a proxy configured, or otherwise null. 7289 */ 7290 @Override 7291 public ProxyInfo getProxyForNetwork(Network network) { 7292 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy(); 7293 if (globalProxy != null) return globalProxy; 7294 if (network == null) { 7295 // Get the network associated with the calling UID. 7296 final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(), 7297 true); 7298 if (activeNetwork == null) { 7299 return null; 7300 } 7301 return getLinkPropertiesProxyInfo(activeNetwork); 7302 } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) { 7303 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 7304 // caller may not have. 7305 return getLinkPropertiesProxyInfo(network); 7306 } 7307 // No proxy info available if the calling UID does not have network access. 7308 return null; 7309 } 7310 7311 7312 private ProxyInfo getLinkPropertiesProxyInfo(Network network) { 7313 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 7314 if (nai == null) return null; 7315 synchronized (nai) { 7316 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy(); 7317 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy); 7318 } 7319 } 7320 7321 @Override 7322 public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) { 7323 enforceNetworkStackPermission(mContext); 7324 mProxyTracker.setGlobalProxy(proxyProperties); 7325 } 7326 7327 @Override 7328 @Nullable 7329 public ProxyInfo getGlobalProxy() { 7330 return mProxyTracker.getGlobalProxy(); 7331 } 7332 7333 private void handlePacProxyServiceStarted(@Nullable Network net, @Nullable ProxyInfo proxy) { 7334 mProxyTracker.setDefaultProxy(proxy); 7335 final NetworkAgentInfo nai = getDefaultNetwork(); 7336 // TODO : this method should check that net == nai.network, unfortunately at this point 7337 // 'net' is always null in practice (see PacProxyService#sendPacBroadcast). PAC proxy 7338 // is only ever installed on the default network so in practice this is okay. 7339 if (null == nai) return; 7340 // PAC proxies only work on the default network. Therefore, only the default network 7341 // should have its link properties fixed up for PAC proxies. 7342 mProxyTracker.updateDefaultNetworkProxyPortForPAC(nai.linkProperties, nai.network); 7343 if (nai.everConnected()) { 7344 notifyNetworkCallbacks(nai, CALLBACK_IP_CHANGED); 7345 } 7346 } 7347 7348 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called 7349 // when any network changes proxy. 7350 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a 7351 // multi-network world where an app might be bound to a non-default network. 7352 private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 7353 ProxyInfo newProxyInfo = newLp.getHttpProxy(); 7354 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 7355 7356 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 7357 mProxyTracker.sendProxyBroadcast(); 7358 } 7359 } 7360 7361 private static class SettingsObserver extends ContentObserver { 7362 final private HashMap<Uri, Integer> mUriEventMap; 7363 final private Context mContext; 7364 final private Handler mHandler; 7365 7366 SettingsObserver(Context context, Handler handler) { 7367 super(null); 7368 mUriEventMap = new HashMap<>(); 7369 mContext = context; 7370 mHandler = handler; 7371 } 7372 7373 void observe(Uri uri, int what) { 7374 mUriEventMap.put(uri, what); 7375 final ContentResolver resolver = mContext.getContentResolver(); 7376 resolver.registerContentObserver(uri, false, this); 7377 } 7378 7379 @Override 7380 public void onChange(boolean selfChange) { 7381 Log.wtf(TAG, "Should never be reached."); 7382 } 7383 7384 @Override 7385 public void onChange(boolean selfChange, Uri uri) { 7386 final Integer what = mUriEventMap.get(uri); 7387 if (what != null) { 7388 mHandler.obtainMessage(what).sendToTarget(); 7389 } else { 7390 loge("No matching event to send for URI=" + uri); 7391 } 7392 } 7393 } 7394 7395 private static void log(String s) { 7396 Log.d(TAG, s); 7397 } 7398 7399 private static void logw(String s) { 7400 Log.w(TAG, s); 7401 } 7402 7403 private static void logwtf(String s) { 7404 Log.wtf(TAG, s); 7405 } 7406 7407 private static void logwtf(String s, Throwable t) { 7408 Log.wtf(TAG, s, t); 7409 } 7410 7411 private static void loge(String s) { 7412 Log.e(TAG, s); 7413 } 7414 7415 private static void loge(String s, Throwable t) { 7416 Log.e(TAG, s, t); 7417 } 7418 7419 /** 7420 * Return the information of all ongoing VPNs. 7421 * 7422 * <p>This method is used to update NetworkStatsService. 7423 * 7424 * <p>Must be called on the handler thread. 7425 */ 7426 private UnderlyingNetworkInfo[] getAllVpnInfo() { 7427 ensureRunningOnConnectivityServiceThread(); 7428 if (mLockdownEnabled) { 7429 return new UnderlyingNetworkInfo[0]; 7430 } 7431 List<UnderlyingNetworkInfo> infoList = new ArrayList<>(); 7432 forEachNetworkAgentInfo(nai -> { 7433 UnderlyingNetworkInfo info = createVpnInfo(nai); 7434 if (info != null) { 7435 infoList.add(info); 7436 } 7437 }); 7438 return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]); 7439 } 7440 7441 /** 7442 * @return VPN information for accounting, or null if we can't retrieve all required 7443 * information, e.g underlying ifaces. 7444 */ 7445 private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) { 7446 Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; 7447 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 7448 // the underlyingNetworks list. 7449 // TODO: stop using propagateUnderlyingCapabilities here, for example, by always 7450 // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array. 7451 if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) { 7452 final NetworkAgentInfo defaultNai = getDefaultNetworkForUid( 7453 nai.networkCapabilities.getOwnerUid()); 7454 if (defaultNai != null) { 7455 underlyingNetworks = new Network[] { defaultNai.network }; 7456 } 7457 } 7458 7459 if (CollectionUtils.isEmpty(underlyingNetworks)) return null; 7460 7461 List<String> interfaces = new ArrayList<>(); 7462 for (Network network : underlyingNetworks) { 7463 NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network); 7464 if (underlyingNai == null) continue; 7465 LinkProperties lp = underlyingNai.linkProperties; 7466 for (String iface : lp.getAllInterfaceNames()) { 7467 if (!TextUtils.isEmpty(iface)) { 7468 interfaces.add(iface); 7469 } 7470 } 7471 } 7472 7473 if (interfaces.isEmpty()) return null; 7474 7475 // Must be non-null or NetworkStatsService will crash. 7476 // Cannot happen in production code because Vpn only registers the NetworkAgent after the 7477 // tun or ipsec interface is created. 7478 // TODO: Remove this check. 7479 if (nai.linkProperties.getInterfaceName() == null) return null; 7480 7481 return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(), 7482 nai.linkProperties.getInterfaceName(), interfaces); 7483 } 7484 7485 // TODO This needs to be the default network that applies to the NAI. 7486 private Network[] underlyingNetworksOrDefault(final int ownerUid, 7487 Network[] underlyingNetworks) { 7488 final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid)); 7489 if (underlyingNetworks == null && defaultNetwork != null) { 7490 // null underlying networks means to track the default. 7491 underlyingNetworks = new Network[] { defaultNetwork }; 7492 } 7493 return underlyingNetworks; 7494 } 7495 7496 // Returns true iff |network| is an underlying network of |nai|. 7497 private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) { 7498 // TODO: support more than one level of underlying networks, either via a fixed-depth search 7499 // (e.g., 2 levels of underlying networks), or via loop detection, or.... 7500 if (!nai.propagateUnderlyingCapabilities()) return false; 7501 final Network[] underlying = underlyingNetworksOrDefault( 7502 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks); 7503 return CollectionUtils.contains(underlying, network); 7504 } 7505 7506 /** 7507 * Recompute the capabilities for any networks that had a specific network as underlying. 7508 * 7509 * When underlying networks change, such networks may have to update capabilities to reflect 7510 * things like the metered bit, their transports, and so on. The capabilities are calculated 7511 * immediately. This method runs on the ConnectivityService thread. 7512 */ 7513 private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) { 7514 ensureRunningOnConnectivityServiceThread(); 7515 forEachNetworkAgentInfo(nai -> { 7516 if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) { 7517 updateCapabilitiesForNetwork(nai); 7518 } 7519 }); 7520 } 7521 7522 private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) { 7523 // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies 7524 // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when 7525 // a VPN is not up. 7526 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 7527 if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false; 7528 for (UidRange range : blockedUidRanges) { 7529 if (range.contains(uid)) return true; 7530 } 7531 return false; 7532 } 7533 7534 @Override 7535 public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 7536 enforceNetworkStackOrSettingsPermission(); 7537 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS, 7538 encodeBool(requireVpn), 0 /* arg2 */, ranges)); 7539 } 7540 7541 private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 7542 if (DBG) { 7543 Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: " 7544 + Arrays.toString(ranges)); 7545 } 7546 // Cannot use a Set since the list of UID ranges might contain duplicates. 7547 final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges); 7548 for (int i = 0; i < ranges.length; i++) { 7549 if (requireVpn) { 7550 newVpnBlockedUidRanges.add(ranges[i]); 7551 } else { 7552 newVpnBlockedUidRanges.remove(ranges[i]); 7553 } 7554 } 7555 7556 try { 7557 mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges)); 7558 } catch (RemoteException | ServiceSpecificException e) { 7559 Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", " 7560 + Arrays.toString(ranges) + "): netd command failed: " + e); 7561 } 7562 7563 if (mDeps.isAtLeastT()) { 7564 mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges); 7565 } 7566 7567 forEachNetworkAgentInfo(nai -> { 7568 final boolean curMetered = nai.networkCapabilities.isMetered(); 7569 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, 7570 mVpnBlockedUidRanges, newVpnBlockedUidRanges); 7571 }); 7572 7573 mVpnBlockedUidRanges = newVpnBlockedUidRanges; 7574 } 7575 7576 @Override 7577 public void setLegacyLockdownVpnEnabled(boolean enabled) { 7578 enforceNetworkStackOrSettingsPermission(); 7579 mHandler.post(() -> mLockdownEnabled = enabled); 7580 } 7581 7582 private boolean isLegacyLockdownNai(NetworkAgentInfo nai) { 7583 return mLockdownEnabled 7584 && isLegacyVpn(nai) 7585 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID); 7586 } 7587 7588 private NetworkAgentInfo getLegacyLockdownNai() { 7589 if (!mLockdownEnabled) { 7590 return null; 7591 } 7592 // The legacy lockdown VPN always only applies to userId 0. 7593 final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID); 7594 if (nai == null || !isLegacyLockdownNai(nai)) return null; 7595 7596 // The legacy lockdown VPN must always have exactly one underlying network. 7597 // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in 7598 // a local variable. There is no need to make a copy because its contents cannot change. 7599 final Network[] underlying = nai.declaredUnderlyingNetworks; 7600 if (underlying == null || underlying.length != 1) { 7601 return null; 7602 } 7603 7604 // The legacy lockdown VPN always uses the default network. 7605 // If the VPN's underlying network is no longer the current default network, it means that 7606 // the default network has just switched, and the VPN is about to disconnect. 7607 // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten 7608 // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED. 7609 final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 7610 if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) { 7611 return null; 7612 } 7613 7614 return nai; 7615 }; 7616 7617 // TODO: move all callers to filterForLegacyLockdown and delete this method. 7618 // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of 7619 // just a DetailedState object. 7620 private DetailedState getLegacyLockdownState(DetailedState origState) { 7621 if (origState != DetailedState.CONNECTED) { 7622 return origState; 7623 } 7624 return (mLockdownEnabled && getLegacyLockdownNai() == null) 7625 ? DetailedState.CONNECTING 7626 : DetailedState.CONNECTED; 7627 } 7628 7629 private void filterForLegacyLockdown(NetworkInfo ni) { 7630 if (!mLockdownEnabled || !ni.isConnected()) return; 7631 // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the 7632 // state of its VPN. This is to ensure that when an underlying network connects, apps will 7633 // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN 7634 // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying 7635 // network, this time with a state of CONNECTED. 7636 // 7637 // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access 7638 // to the internal state of the Vpn object, always replace the state with CONNECTING. This 7639 // is not too far off the truth, since an always-on VPN, when not connected, is always 7640 // trying to reconnect. 7641 if (getLegacyLockdownNai() == null) { 7642 ni.setDetailedState(DetailedState.CONNECTING, "", null); 7643 } 7644 } 7645 7646 @Override 7647 public void setProvisioningNotificationVisible(boolean visible, int networkType, 7648 String action) { 7649 enforceSettingsPermission(); 7650 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 7651 return; 7652 } 7653 final long ident = Binder.clearCallingIdentity(); 7654 try { 7655 // Concatenate the range of types onto the range of NetIDs. 7656 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 7657 mNotifier.setProvNotificationVisible(visible, id, action); 7658 } finally { 7659 Binder.restoreCallingIdentity(ident); 7660 } 7661 } 7662 7663 @Override 7664 public void setAirplaneMode(boolean enable) { 7665 enforceAirplaneModePermission(); 7666 final long ident = Binder.clearCallingIdentity(); 7667 try { 7668 final ContentResolver cr = mContext.getContentResolver(); 7669 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 7670 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 7671 intent.putExtra("state", enable); 7672 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 7673 } finally { 7674 Binder.restoreCallingIdentity(ident); 7675 } 7676 } 7677 7678 private void onUserAdded(@NonNull final UserHandle user) { 7679 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 7680 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7681 } 7682 updateProfileAllowedNetworks(); 7683 } 7684 7685 private void onUserRemoved(@NonNull final UserHandle user) { 7686 // If there was a network preference for this user, remove it. 7687 handleSetProfileNetworkPreference( 7688 List.of(new ProfileNetworkPreferenceInfo(user, null, true, 7689 false /* blockingNonEnterprise */)), 7690 null /* listener */); 7691 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 7692 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7693 } 7694 } 7695 7696 private void onPackageChanged(@NonNull final String packageName) { 7697 // This is necessary in case a package is added or removed, but also when it's replaced to 7698 // run as a new UID by its manifest rules. Also, if a separate package shares the same UID 7699 // as one in the preferences, then it should follow the same routing as that other package, 7700 // which means updating the rules is never to be needed in this case (whether it joins or 7701 // leaves a UID with a preference). 7702 if (isMappedInOemNetworkPreference(packageName)) { 7703 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 7704 } 7705 7706 // Invalidates cache entry when the package is updated. 7707 synchronized (mSelfCertifiedCapabilityCache) { 7708 mSelfCertifiedCapabilityCache.remove(packageName); 7709 } 7710 } 7711 7712 private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 7713 @Override 7714 public void onReceive(Context context, Intent intent) { 7715 ensureRunningOnConnectivityServiceThread(); 7716 final String action = intent.getAction(); 7717 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 7718 7719 // User should be filled for below intents, check the existence. 7720 if (user == null) { 7721 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER"); 7722 return; 7723 } 7724 7725 if (Intent.ACTION_USER_ADDED.equals(action)) { 7726 onUserAdded(user); 7727 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 7728 onUserRemoved(user); 7729 } else { 7730 Log.wtf(TAG, "received unexpected intent: " + action); 7731 } 7732 } 7733 }; 7734 7735 private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { 7736 @Override 7737 public void onReceive(Context context, Intent intent) { 7738 ensureRunningOnConnectivityServiceThread(); 7739 switch (intent.getAction()) { 7740 case Intent.ACTION_PACKAGE_ADDED: 7741 case Intent.ACTION_PACKAGE_REMOVED: 7742 case Intent.ACTION_PACKAGE_REPLACED: 7743 onPackageChanged(intent.getData().getSchemeSpecificPart()); 7744 break; 7745 default: 7746 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 7747 } 7748 } 7749 }; 7750 7751 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 7752 private final BroadcastReceiver mDataSaverReceiver = new BroadcastReceiver() { 7753 @Override 7754 public void onReceive(Context context, Intent intent) { 7755 if (mDeps.isAtLeastV()) { 7756 throw new IllegalStateException( 7757 "data saver status should be updated from platform"); 7758 } 7759 ensureRunningOnConnectivityServiceThread(); 7760 switch (intent.getAction()) { 7761 case ACTION_RESTRICT_BACKGROUND_CHANGED: 7762 // If the uid is present in the deny list, the API will consistently 7763 // return ENABLED. To retrieve the global switch status, the system 7764 // uid is chosen because it will never be included in the deny list. 7765 final int dataSaverForSystemUid = 7766 mPolicyManager.getRestrictBackgroundStatus(Process.SYSTEM_UID); 7767 final boolean isDataSaverEnabled = (dataSaverForSystemUid 7768 != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED); 7769 mBpfNetMaps.setDataSaverEnabled(isDataSaverEnabled); 7770 break; 7771 default: 7772 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 7773 } 7774 } 7775 }; 7776 7777 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); 7778 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); 7779 7780 private static class NetworkProviderInfo { 7781 public final String name; 7782 public final Messenger messenger; 7783 private final IBinder.DeathRecipient mDeathRecipient; 7784 public final int providerId; 7785 7786 NetworkProviderInfo(String name, Messenger messenger, int providerId, 7787 @NonNull IBinder.DeathRecipient deathRecipient) { 7788 this.name = name; 7789 this.messenger = messenger; 7790 this.providerId = providerId; 7791 mDeathRecipient = deathRecipient; 7792 7793 if (mDeathRecipient == null) { 7794 throw new AssertionError("Must pass a deathRecipient"); 7795 } 7796 } 7797 7798 void connect(Context context, Handler handler) { 7799 try { 7800 messenger.getBinder().linkToDeath(mDeathRecipient, 0); 7801 } catch (RemoteException e) { 7802 mDeathRecipient.binderDied(); 7803 } 7804 } 7805 } 7806 7807 private void ensureAllNetworkRequestsHaveSupportedType(List<NetworkRequest> requests) { 7808 final boolean isMultilayerRequest = requests.size() > 1; 7809 for (int i = 0; i < requests.size(); i++) { 7810 ensureNetworkRequestHasSupportedType(requests.get(i), isMultilayerRequest); 7811 } 7812 } 7813 7814 private void ensureNetworkRequestHasSupportedType(NetworkRequest request, 7815 boolean isMultilayerRequest) { 7816 if (request.type == NetworkRequest.Type.NONE) { 7817 throw new IllegalArgumentException( 7818 "All NetworkRequests in ConnectivityService must have a type"); 7819 } 7820 if (isMultilayerRequest && request.type == NetworkRequest.Type.RESERVATION) { 7821 throw new IllegalArgumentException( 7822 "Reservation requests are not supported in multilayer request"); 7823 } 7824 } 7825 7826 /** 7827 * Tracks info about the requester. 7828 * Also used to notice when the calling process dies so as to self-expire 7829 */ 7830 @VisibleForTesting 7831 protected class NetworkRequestInfo implements IBinder.DeathRecipient { 7832 // The requests to be satisfied in priority order. Non-multilayer requests will only have a 7833 // single NetworkRequest in mRequests. 7834 final List<NetworkRequest> mRequests; 7835 7836 /** 7837 * List of callbacks that are queued for sending later when the requesting app is unfrozen. 7838 * 7839 * <p>There may typically be hundreds of NetworkRequestInfo, so a memory-efficient structure 7840 * (just an int[]) is used to keep queued callbacks. This reduces the number of object 7841 * references. 7842 * 7843 * <p>This is intended to be used with {@link CallbackQueue} which defines the internal 7844 * format. 7845 */ 7846 @NonNull 7847 private int[] mQueuedCallbacks = new int[0]; 7848 7849 private static final int MATCHED_NETID_NOT_FROZEN = -1; 7850 7851 /** 7852 * If this request was already satisfied by a network when the requesting UID was frozen, 7853 * the netId that was matched at that time. Otherwise, NETID_UNSET if no network was 7854 * satisfying this request when frozen (including if this is a listen and not a request), 7855 * and MATCHED_NETID_NOT_FROZEN if not frozen. 7856 */ 7857 private int mMatchedNetIdWhenFrozen = MATCHED_NETID_NOT_FROZEN; 7858 7859 // mSatisfier and mActiveRequest rely on one another therefore set them together. 7860 void setSatisfier( 7861 @Nullable final NetworkAgentInfo satisfier, 7862 @Nullable final NetworkRequest activeRequest) { 7863 mSatisfier = satisfier; 7864 mActiveRequest = activeRequest; 7865 } 7866 7867 // The network currently satisfying this NRI. Only one request in an NRI can have a 7868 // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier. 7869 @Nullable 7870 private NetworkAgentInfo mSatisfier; 7871 NetworkAgentInfo getSatisfier() { 7872 return mSatisfier; 7873 } 7874 7875 // The request in mRequests assigned to a network agent. This is null if none of the 7876 // requests in mRequests can be satisfied. This member has the constraint of only being 7877 // accessible on the handler thread. 7878 @Nullable 7879 private NetworkRequest mActiveRequest; 7880 NetworkRequest getActiveRequest() { 7881 return mActiveRequest; 7882 } 7883 7884 final PendingIntent mPendingIntent; 7885 boolean mPendingIntentSent; 7886 @Nullable 7887 final Messenger mMessenger; 7888 7889 // Information about the caller that caused this object to be created. 7890 @Nullable 7891 private final IBinder mBinder; 7892 final int mPid; 7893 final int mUid; 7894 final @NetworkCallback.Flag int mCallbackFlags; 7895 @Nullable 7896 final String mCallingAttributionTag; 7897 7898 // Counter keeping track of this NRI. 7899 final RequestInfoPerUidCounter mPerUidCounter; 7900 7901 // Effective UID of this request. This is different from mUid when a privileged process 7902 // files a request on behalf of another UID. This UID is used to determine blocked status, 7903 // UID matching, and so on. mUid above is used for permission checks and to enforce the 7904 // maximum limit of registered callbacks per UID. 7905 final int mAsUid; 7906 7907 // Flag to indicate that uid of this nri is tracked for sending blocked status callbacks. 7908 // It is always true on V+ if mMessenger != null. As such, it's not strictly necessary. 7909 // it's used only as a safeguard to avoid double counting or leaking. 7910 boolean mUidTrackedForBlockedStatus; 7911 7912 // Preference order of this request. 7913 final int mPreferenceOrder; 7914 7915 final int mDeclaredMethodsFlags; 7916 7917 // In order to preserve the mapping of NetworkRequest-to-callback when apps register 7918 // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be 7919 // maintained for keying off of. This is only a concern when the original nri 7920 // mNetworkRequests changes which happens currently for apps that register callbacks to 7921 // track the default network. In those cases, the nri is updated to have mNetworkRequests 7922 // that match the per-app default nri that currently tracks the calling app's uid so that 7923 // callbacks are fired at the appropriate time. When the callbacks fire, 7924 // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When 7925 // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue. 7926 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 7927 @NonNull 7928 private final NetworkRequest mNetworkRequestForCallback; 7929 NetworkRequest getNetworkRequestForCallback() { 7930 return mNetworkRequestForCallback; 7931 } 7932 7933 /** 7934 * NetworkCapabilities that were created as part of a NetworkOffer in response to a 7935 * RESERVATION request. mReservedCapabilities is null if no current offer matches the 7936 * RESERVATION request or if the request is not a RESERVATION. Matching is based on 7937 * reservationId. 7938 */ 7939 @Nullable 7940 private NetworkCapabilities mReservedCapabilities; 7941 @Nullable 7942 NetworkCapabilities getReservedCapabilities() { 7943 return mReservedCapabilities; 7944 } 7945 7946 void setReservedCapabilities(@NonNull NetworkCapabilities caps) { 7947 // This function can only be called once. NetworkCapabilities are never reset as the 7948 // reservation is released when the offer disappears. 7949 if (mReservedCapabilities != null) { 7950 logwtf("ReservedCapabilities can only be set once"); 7951 } 7952 mReservedCapabilities = caps; 7953 } 7954 7955 /** 7956 * Get the list of UIDs this nri applies to. 7957 */ 7958 @NonNull 7959 Set<UidRange> getUids() { 7960 // networkCapabilities.getUids() returns a defensive copy. 7961 // multilayer requests will all have the same uids so return the first one. 7962 final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges(); 7963 return (null == uids) ? new ArraySet<>() : uids; 7964 } 7965 7966 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, 7967 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) { 7968 this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag, 7969 PREFERENCE_ORDER_INVALID); 7970 } 7971 7972 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 7973 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, 7974 @Nullable String callingAttributionTag, final int preferenceOrder) { 7975 ensureAllNetworkRequestsHaveSupportedType(r); 7976 mRequests = initializeRequests(r); 7977 mNetworkRequestForCallback = requestForCallback; 7978 mPendingIntent = pi; 7979 mMessenger = null; 7980 mBinder = null; 7981 mPid = getCallingPid(); 7982 mUid = mDeps.getCallingUid(); 7983 mAsUid = asUid; 7984 mPerUidCounter = getRequestCounter(this); 7985 /** 7986 * Location sensitive data not included in pending intent. Only included in 7987 * {@link NetworkCallback}. 7988 */ 7989 mCallbackFlags = NetworkCallback.FLAG_NONE; 7990 mCallingAttributionTag = callingAttributionTag; 7991 mPreferenceOrder = preferenceOrder; 7992 mDeclaredMethodsFlags = DECLARED_METHODS_NONE; 7993 } 7994 7995 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, 7996 @Nullable final IBinder binder, 7997 @NetworkCallback.Flag int callbackFlags, 7998 @Nullable String callingAttributionTag, int declaredMethodsFlags) { 7999 this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags, 8000 callingAttributionTag, declaredMethodsFlags); 8001 } 8002 8003 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 8004 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, 8005 @Nullable final IBinder binder, 8006 @NetworkCallback.Flag int callbackFlags, 8007 @Nullable String callingAttributionTag, int declaredMethodsFlags) { 8008 super(); 8009 ensureAllNetworkRequestsHaveSupportedType(r); 8010 mRequests = initializeRequests(r); 8011 mNetworkRequestForCallback = requestForCallback; 8012 mMessenger = m; 8013 mBinder = binder; 8014 mPid = getCallingPid(); 8015 mUid = mDeps.getCallingUid(); 8016 mAsUid = asUid; 8017 mPendingIntent = null; 8018 mPerUidCounter = getRequestCounter(this); 8019 mCallbackFlags = callbackFlags; 8020 mCallingAttributionTag = callingAttributionTag; 8021 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 8022 mDeclaredMethodsFlags = declaredMethodsFlags; 8023 linkDeathRecipient(); 8024 } 8025 8026 NetworkRequestInfo(@NonNull final NetworkRequestInfo nri, 8027 @NonNull final List<NetworkRequest> r) { 8028 super(); 8029 ensureAllNetworkRequestsHaveSupportedType(r); 8030 mRequests = initializeRequests(r); 8031 mNetworkRequestForCallback = nri.getNetworkRequestForCallback(); 8032 final NetworkAgentInfo satisfier = nri.getSatisfier(); 8033 if (null != satisfier) { 8034 // If the old NRI was satisfied by an NAI, then it may have had an active request. 8035 // The active request is necessary to figure out what callbacks to send, in 8036 // particular when a network updates its capabilities. 8037 // As this code creates a new NRI with a new set of requests, figure out which of 8038 // the list of requests should be the active request. It is always the first 8039 // request of the list that can be satisfied by the satisfier since the order of 8040 // requests is a priority order. 8041 // Note even in the presence of a satisfier there may not be an active request, 8042 // when the satisfier is the no-service network. 8043 NetworkRequest activeRequest = null; 8044 for (final NetworkRequest candidate : r) { 8045 if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) { 8046 activeRequest = candidate; 8047 break; 8048 } 8049 } 8050 setSatisfier(satisfier, activeRequest); 8051 } 8052 mMatchedNetIdWhenFrozen = nri.mMatchedNetIdWhenFrozen; 8053 mQueuedCallbacks = nri.mQueuedCallbacks; 8054 mMessenger = nri.mMessenger; 8055 mBinder = nri.mBinder; 8056 mPid = nri.mPid; 8057 mUid = nri.mUid; 8058 mAsUid = nri.mAsUid; 8059 mPendingIntent = nri.mPendingIntent; 8060 mPerUidCounter = nri.mPerUidCounter; 8061 mCallbackFlags = nri.mCallbackFlags; 8062 mCallingAttributionTag = nri.mCallingAttributionTag; 8063 mUidTrackedForBlockedStatus = nri.mUidTrackedForBlockedStatus; 8064 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 8065 mDeclaredMethodsFlags = nri.mDeclaredMethodsFlags; 8066 linkDeathRecipient(); 8067 } 8068 8069 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) { 8070 this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID); 8071 } 8072 8073 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 8074 final int preferenceOrder) { 8075 this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */, 8076 preferenceOrder); 8077 } 8078 8079 // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer 8080 // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning 8081 // false. 8082 boolean isBeingSatisfied() { 8083 return (null != mSatisfier && null != mActiveRequest); 8084 } 8085 8086 boolean isMultilayerRequest() { 8087 return mRequests.size() > 1; 8088 } 8089 8090 private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) { 8091 // Creating a defensive copy to prevent the sender from modifying the list being 8092 // reflected in the return value of this method. 8093 final List<NetworkRequest> tempRequests = new ArrayList<>(r); 8094 return Collections.unmodifiableList(tempRequests); 8095 } 8096 8097 void linkDeathRecipient() { 8098 if (null != mBinder) { 8099 try { 8100 mBinder.linkToDeath(this, 0); 8101 } catch (RemoteException e) { 8102 binderDied(); 8103 } 8104 } 8105 } 8106 8107 void unlinkDeathRecipient() { 8108 if (null != mBinder) { 8109 try { 8110 mBinder.unlinkToDeath(this, 0); 8111 } catch (NoSuchElementException e) { 8112 // Temporary workaround for b/194394697 pending analysis of additional logs 8113 Log.wtf(TAG, "unlinkToDeath for already unlinked NRI " + this); 8114 } 8115 } 8116 } 8117 8118 /** 8119 * Called when this NRI is being frozen. 8120 * 8121 * <p>Calling this method multiple times when the NRI is frozen is fine. This may happen 8122 * if iterating through the NetworkRequest -> NRI map since there are duplicates in the 8123 * NRI values for multilayer requests. It may also happen if an app is frozen, killed, 8124 * restarted and refrozen since there is no callback sent when processes are killed, but in 8125 * that case the callbacks to the killed app do not matter. 8126 */ 8127 void onFrozen() { 8128 if (mMatchedNetIdWhenFrozen != MATCHED_NETID_NOT_FROZEN) { 8129 // Already frozen 8130 return; 8131 } 8132 if (mSatisfier != null) { 8133 mMatchedNetIdWhenFrozen = mSatisfier.network.netId; 8134 } else { 8135 mMatchedNetIdWhenFrozen = NETID_UNSET; 8136 } 8137 } 8138 8139 boolean maybeQueueCallback(@NonNull NetworkAgentInfo nai, int callbackId) { 8140 if (mMatchedNetIdWhenFrozen == MATCHED_NETID_NOT_FROZEN) { 8141 return false; 8142 } 8143 8144 boolean ignoreThisCallback = false; 8145 final int netId = nai.network.netId; 8146 final CallbackQueue queue = new CallbackQueue(mQueuedCallbacks); 8147 // Based on the new callback, clear previous callbacks that are no longer necessary. 8148 // For example, if the network is lost, there is no need to send intermediate callbacks. 8149 switch (callbackId) { 8150 // PRECHECK is not an API and not very meaningful, do not deliver it for frozen apps 8151 // Networks are likely to already be lost when the app is unfrozen, also skip LOSING 8152 case CALLBACK_PRECHECK: 8153 case CALLBACK_LOSING: 8154 ignoreThisCallback = true; 8155 break; 8156 case CALLBACK_LOST: 8157 // All callbacks for this netId before onLost are unnecessary. And onLost itself 8158 // is also unnecessary if onAvailable was previously queued for this netId: the 8159 // Network just appeared and disappeared while the app was frozen. 8160 ignoreThisCallback = queue.hasCallback(netId, CALLBACK_AVAILABLE); 8161 queue.removeCallbacksForNetId(netId); 8162 break; 8163 case CALLBACK_AVAILABLE: 8164 if (mSatisfier != null) { 8165 // For requests that are satisfied by individual networks (not LISTEN), when 8166 // AVAILABLE is received, the request is matching a new Network, so previous 8167 // callbacks (for other Networks) are unnecessary. 8168 queue.clear(); 8169 } 8170 break; 8171 case CALLBACK_SUSPENDED: 8172 case CALLBACK_RESUMED: 8173 if (queue.hasCallback(netId, CALLBACK_AVAILABLE)) { 8174 // AVAILABLE will already send the latest suspended status 8175 ignoreThisCallback = true; 8176 break; 8177 } 8178 // If SUSPENDED was queued, just remove it from the queue instead of sending 8179 // RESUMED; and vice-versa. 8180 final int otherCb = callbackId == CALLBACK_SUSPENDED 8181 ? CALLBACK_RESUMED 8182 : CALLBACK_SUSPENDED; 8183 ignoreThisCallback = queue.removeCallbacks(netId, otherCb); 8184 break; 8185 case CALLBACK_CAP_CHANGED: 8186 case CALLBACK_IP_CHANGED: 8187 case CALLBACK_LOCAL_NETWORK_INFO_CHANGED: 8188 case CALLBACK_BLK_CHANGED: 8189 ignoreThisCallback = queue.hasCallback(netId, CALLBACK_AVAILABLE); 8190 break; 8191 default: 8192 Log.wtf(TAG, "Unexpected callback type: " 8193 + ConnectivityManager.getCallbackName(callbackId)); 8194 return false; 8195 } 8196 8197 if (!ignoreThisCallback) { 8198 // For non-listen (matching) callbacks, AVAILABLE can appear in the queue twice in a 8199 // row for the same network if the new AVAILABLE suppressed intermediate AVAILABLEs 8200 // for other networks. Example: 8201 // A is matched, app is frozen, B is matched, A is matched again (removes callbacks 8202 // for B), app is unfrozen. 8203 // In that case call AVAILABLE sub-callbacks to update state, but not AVAILABLE 8204 // itself. 8205 if (callbackId == CALLBACK_AVAILABLE && netId == mMatchedNetIdWhenFrozen) { 8206 // The queue should have been cleared here, since this is AVAILABLE on a 8207 // non-listen callback (mMatchedNetIdWhenFrozen is set). 8208 addAvailableSubCallbacks(nai, queue); 8209 } else { 8210 // When unfreezing, no need to send a callback multiple times for the same netId 8211 queue.removeCallbacks(netId, callbackId); 8212 // TODO: this code always adds the callback for simplicity. It would save 8213 // some CPU/memory if the code instead only added to the queue callbacks where 8214 // isCallbackOverridden=true, or which need to be in the queue because they 8215 // affect other callbacks that are overridden. 8216 queue.addCallback(netId, callbackId); 8217 } 8218 } 8219 // Instead of shrinking the queue, possibly reallocating, the NRI could keep the array 8220 // and length in memory for future adds, but this saves memory by avoiding the cost 8221 // of an extra member and of unused array length (there are often hundreds of NRIs). 8222 mQueuedCallbacks = queue.getMinimizedBackingArray(); 8223 return true; 8224 } 8225 8226 /** 8227 * Called when this NRI is being unfrozen to stop queueing, and send queued callbacks. 8228 * 8229 * <p>Calling this method multiple times when the NRI is unfrozen (for example iterating 8230 * through the NetworkRequest -> NRI map where there are duplicate values for multilayer 8231 * requests) is fine. 8232 */ 8233 void sendQueuedCallbacks() { 8234 mMatchedNetIdWhenFrozen = MATCHED_NETID_NOT_FROZEN; 8235 if (mQueuedCallbacks.length == 0) { 8236 return; 8237 } 8238 new CallbackQueue(mQueuedCallbacks).forEach((netId, callbackId) -> { 8239 // For CALLBACK_LOST only, there will not be a NAI for the netId. Build and send the 8240 // callback directly. 8241 if (callbackId == CALLBACK_LOST) { 8242 if (isCallbackOverridden(CALLBACK_LOST)) { 8243 final Bundle cbBundle = makeCommonBundleForCallback(this, 8244 new Network(netId)); 8245 callCallbackForRequest(this, CALLBACK_LOST, cbBundle, 0 /* arg1 */); 8246 } 8247 return; // Next item in forEach 8248 } 8249 8250 // Other callbacks should always have a NAI, because if a Network disconnects 8251 // LOST will be called, unless the request is no longer satisfied by that Network in 8252 // which case AVAILABLE will have been called for another Network. In both cases 8253 // previous callbacks are cleared. 8254 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 8255 if (nai == null) { 8256 Log.wtf(TAG, "Missing NetworkAgentInfo for net " + netId 8257 + " for callback " + callbackId); 8258 return; // Next item in forEach 8259 } 8260 8261 final int arg1 = 8262 callbackId == CALLBACK_AVAILABLE || callbackId == CALLBACK_BLK_CHANGED 8263 ? getBlockedState(nai, mAsUid) 8264 : 0; 8265 callCallbackForRequest(this, nai, callbackId, arg1); 8266 }); 8267 mQueuedCallbacks = new int[0]; 8268 } 8269 8270 boolean isCallbackOverridden(int callbackId) { 8271 return !mUseDeclaredMethodsForCallbacksEnabled 8272 || (mDeclaredMethodsFlags & (1 << callbackId)) != 0; 8273 } 8274 8275 /** 8276 * Queue all callbacks that are called by AVAILABLE, except onAvailable. 8277 * 8278 * <p>AVAILABLE may call SUSPENDED, CAP_CHANGED, IP_CHANGED, LOCAL_NETWORK_INFO_CHANGED, 8279 * and BLK_CHANGED, in this order. 8280 */ 8281 private void addAvailableSubCallbacks( 8282 @NonNull NetworkAgentInfo nai, @NonNull CallbackQueue queue) { 8283 final boolean callSuspended = 8284 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 8285 final boolean callLocalInfoChanged = nai.isLocalNetwork(); 8286 8287 final int cbCount = 3 + (callSuspended ? 1 : 0) + (callLocalInfoChanged ? 1 : 0); 8288 // Avoid unnecessary re-allocations by reserving enough space for all callbacks to add. 8289 queue.ensureHasCapacity(cbCount); 8290 final int netId = nai.network.netId; 8291 if (callSuspended) { 8292 queue.addCallback(netId, CALLBACK_SUSPENDED); 8293 } 8294 queue.addCallback(netId, CALLBACK_CAP_CHANGED); 8295 queue.addCallback(netId, CALLBACK_IP_CHANGED); 8296 if (callLocalInfoChanged) { 8297 queue.addCallback(netId, CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 8298 } 8299 queue.addCallback(netId, CALLBACK_BLK_CHANGED); 8300 } 8301 8302 boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) { 8303 // Compare two preference orders. 8304 return mPreferenceOrder < target.mPreferenceOrder; 8305 } 8306 8307 int getPreferenceOrderForNetd() { 8308 if (mPreferenceOrder >= PREFERENCE_ORDER_NONE 8309 && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) { 8310 return mPreferenceOrder; 8311 } 8312 return PREFERENCE_ORDER_NONE; 8313 } 8314 8315 public int getReservationId() { 8316 // RESERVATIONs cannot be used in multilayer requests. 8317 if (isMultilayerRequest()) return RES_ID_UNSET; 8318 final NetworkRequest req = mRequests.get(0); 8319 // Non-reservation types return RES_ID_UNSET. 8320 return req.networkCapabilities.getReservationId(); 8321 } 8322 8323 @Override 8324 public void binderDied() { 8325 // As an immutable collection, mRequests cannot change by the time the 8326 // lambda is evaluated on the handler thread so calling .get() from a binder thread 8327 // is acceptable. Use handleReleaseNetworkRequest and not directly 8328 // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case 8329 // the app already unregistered the request. 8330 mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0), 8331 mUid, false /* callOnUnavailable */)); 8332 } 8333 8334 @Override 8335 public String toString() { 8336 final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid; 8337 return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: " 8338 + (mActiveRequest == null ? null : mActiveRequest.requestId) 8339 + " callbackRequest: " 8340 + mNetworkRequestForCallback.requestId 8341 + " " + mRequests 8342 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent) 8343 + " callback flags: " + mCallbackFlags 8344 + " order: " + mPreferenceOrder 8345 + " isUidTracked: " + mUidTrackedForBlockedStatus 8346 + " declaredMethods: " + declaredMethodsFlagsToString(mDeclaredMethodsFlags); 8347 } 8348 } 8349 8350 /** 8351 * Get a readable String for a bitmask of declared methods. 8352 */ 8353 @VisibleForTesting 8354 public static String declaredMethodsFlagsToString(int flags) { 8355 if (flags == DECLARED_METHODS_NONE) { 8356 return "NONE"; 8357 } 8358 if (flags == DECLARED_METHODS_ALL) { 8359 return "ALL"; 8360 } 8361 final StringBuilder sb = new StringBuilder(); 8362 flags = maybeAppendDeclaredMethod(flags, CALLBACK_PRECHECK, "PRECHK", sb); 8363 flags = maybeAppendDeclaredMethod(flags, CALLBACK_AVAILABLE, "AVAIL", sb); 8364 flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOSING, "LOSING", sb); 8365 flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOST, "LOST", sb); 8366 flags = maybeAppendDeclaredMethod(flags, CALLBACK_UNAVAIL, "UNAVAIL", sb); 8367 flags = maybeAppendDeclaredMethod(flags, CALLBACK_CAP_CHANGED, "NC", sb); 8368 flags = maybeAppendDeclaredMethod(flags, CALLBACK_IP_CHANGED, "LP", sb); 8369 flags = maybeAppendDeclaredMethod(flags, CALLBACK_SUSPENDED, "SUSP", sb); 8370 flags = maybeAppendDeclaredMethod(flags, CALLBACK_RESUMED, "RESUME", sb); 8371 flags = maybeAppendDeclaredMethod(flags, CALLBACK_BLK_CHANGED, "BLK", sb); 8372 flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOCAL_NETWORK_INFO_CHANGED, 8373 "LOCALINF", sb); 8374 flags = maybeAppendDeclaredMethod(flags, CALLBACK_RESERVED, "RES", sb); 8375 if (flags != 0) { 8376 sb.append("|0x").append(Integer.toHexString(flags)); 8377 } 8378 return sb.toString(); 8379 } 8380 8381 private static int maybeAppendDeclaredMethod(int declaredMethodsFlags, 8382 int callbackId, String callbackName, @NonNull StringBuilder builder) { 8383 final int callbackFlag = 1 << callbackId; 8384 if ((declaredMethodsFlags & callbackFlag) != 0) { 8385 if (builder.length() > 0) { 8386 builder.append('|'); 8387 } 8388 builder.append(callbackName); 8389 } 8390 return declaredMethodsFlags & ~callbackFlag; 8391 } 8392 8393 // Keep backward compatibility since the ServiceSpecificException is used by 8394 // the API surface, see {@link ConnectivityManager#convertServiceException}. 8395 public static class RequestInfoPerUidCounter extends PerUidCounter { 8396 RequestInfoPerUidCounter(int maxCountPerUid) { 8397 super(maxCountPerUid); 8398 } 8399 8400 @Override 8401 public synchronized void incrementCountOrThrow(int uid) { 8402 try { 8403 super.incrementCountOrThrow(uid); 8404 } catch (IllegalStateException e) { 8405 throw new ServiceSpecificException( 8406 ConnectivityManager.Errors.TOO_MANY_REQUESTS, 8407 "Uid " + uid + " exceeded its allotted requests limit"); 8408 } 8409 } 8410 8411 @Override 8412 public synchronized void decrementCountOrThrow(int uid) { 8413 throw new UnsupportedOperationException("Use decrementCount instead."); 8414 } 8415 8416 public synchronized void decrementCount(int uid) { 8417 try { 8418 super.decrementCountOrThrow(uid); 8419 } catch (IllegalStateException e) { 8420 logwtf("Exception when decrement per uid request count: ", e); 8421 } 8422 } 8423 } 8424 8425 // This checks that the passed capabilities either do not request a 8426 // specific SSID/SignalStrength, or the calling app has permission to do so. 8427 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 8428 int callerPid, int callerUid, String callerPackageName) { 8429 if (null != nc.getSsid() && !hasSettingsPermission(callerPid, callerUid)) { 8430 throw new SecurityException("Insufficient permissions to request a specific SSID"); 8431 } 8432 8433 if (nc.hasSignalStrength() 8434 && !hasNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { 8435 throw new SecurityException( 8436 "Insufficient permissions to request a specific signal strength"); 8437 } 8438 mAppOpsManager.checkPackage(callerUid, callerPackageName); 8439 } 8440 8441 private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { 8442 final SortedSet<Integer> thresholds = new TreeSet<>(); 8443 synchronized (nai) { 8444 // mNetworkRequests may contain the same value multiple times in case of 8445 // multilayer requests. It won't matter in this case because the thresholds 8446 // will then be the same and be deduplicated as they enter the `thresholds` set. 8447 // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like. 8448 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 8449 for (final NetworkRequest req : nri.mRequests) { 8450 if (req.networkCapabilities.hasSignalStrength() 8451 && nai.satisfiesImmutableCapabilitiesOf(req)) { 8452 thresholds.add(req.networkCapabilities.getSignalStrength()); 8453 } 8454 } 8455 } 8456 } 8457 return CollectionUtils.toIntArray(new ArrayList<>(thresholds)); 8458 } 8459 8460 private void updateSignalStrengthThresholds( 8461 NetworkAgentInfo nai, String reason, NetworkRequest request) { 8462 final int[] thresholdsArray = getSignalStrengthThresholds(nai); 8463 8464 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 8465 String detail; 8466 if (request != null && request.networkCapabilities.hasSignalStrength()) { 8467 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 8468 } else { 8469 detail = reason; 8470 } 8471 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 8472 detail, Arrays.toString(thresholdsArray), nai.toShortString())); 8473 } 8474 8475 nai.onSignalStrengthThresholdsUpdated(thresholdsArray); 8476 } 8477 8478 private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 8479 if (nc == null) { 8480 return; 8481 } 8482 NetworkSpecifier ns = nc.getNetworkSpecifier(); 8483 if (ns == null) { 8484 return; 8485 } 8486 if (ns instanceof MatchAllNetworkSpecifier) { 8487 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); 8488 } 8489 } 8490 8491 private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) { 8492 ensureValidNetworkSpecifier(nc); 8493 if (nc.isPrivateDnsBroken()) { 8494 throw new IllegalArgumentException("Can't request broken private DNS"); 8495 } 8496 if (nc.hasAllowedUids()) { 8497 throw new IllegalArgumentException("Can't request access UIDs"); 8498 } 8499 } 8500 8501 private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) { 8502 ensureListenableCapabilities(nc); 8503 final String badCapability = nc.describeFirstNonRequestableCapability(); 8504 if (badCapability != null) { 8505 throw new IllegalArgumentException("Cannot request network with " + badCapability); 8506 } 8507 } 8508 8509 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 8510 @TargetApi(Build.VERSION_CODES.S) 8511 private boolean isTargetSdkAtleast(int version, int callingUid, 8512 @NonNull String callingPackageName) { 8513 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 8514 final PackageManager pm = 8515 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 8516 try { 8517 final int callingVersion = pm.getTargetSdkVersion(callingPackageName); 8518 if (callingVersion < version) return false; 8519 } catch (PackageManager.NameNotFoundException e) { } 8520 return true; 8521 } 8522 8523 @Override 8524 public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities, 8525 int reqTypeInt, Messenger messenger, int timeoutMs, final IBinder binder, 8526 int legacyType, int callbackFlags, @NonNull String callingPackageName, 8527 @Nullable String callingAttributionTag, int declaredMethodsFlag) { 8528 if (declaredMethodsFlag == 0) { 8529 // This could happen if raw binder calls are used to call the previous overload of 8530 // requestNetwork, as missing int arguments in a binder call end up as 0 8531 // (Parcel.readInt returns 0 at the end of a parcel). Such raw calls this would be 8532 // really unexpected bad behavior from the caller though. 8533 // TODO: remove after verifying this does not happen. This could allow enabling the 8534 // optimization for callbacks that do not override any method (right now they use 8535 // DECLARED_METHODS_ALL), if it is OK to break NetworkCallbacks created using 8536 // dexmaker-mockito-inline and either spy() or MockSettings.useConstructor (see 8537 // comment in ConnectivityManager which sets the flag to DECLARED_METHODS_ALL). 8538 Log.wtf(TAG, "requestNetwork called without declaredMethodsFlag from " 8539 + callingPackageName); 8540 declaredMethodsFlag = DECLARED_METHODS_ALL; 8541 } 8542 if (legacyType != TYPE_NONE && !hasNetworkStackPermission()) { 8543 if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(), 8544 callingPackageName)) { 8545 throw new SecurityException("Insufficient permissions to specify legacy type"); 8546 } 8547 } 8548 final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities; 8549 final int callingUid = mDeps.getCallingUid(); 8550 // Privileged callers can track the default network of another UID by passing in a UID. 8551 if (asUid != Process.INVALID_UID) { 8552 enforceSettingsPermission(); 8553 } else { 8554 asUid = callingUid; 8555 } 8556 final NetworkRequest.Type reqType; 8557 try { 8558 reqType = NetworkRequest.Type.values()[reqTypeInt]; 8559 } catch (ArrayIndexOutOfBoundsException e) { 8560 throw new IllegalArgumentException("Unsupported request type " + reqTypeInt); 8561 } 8562 switch (reqType) { 8563 case TRACK_DEFAULT: 8564 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities} 8565 // is unused and will be replaced by ones appropriate for the UID (usually, the 8566 // calling app). This allows callers to keep track of the default network. 8567 networkCapabilities = copyDefaultNetworkCapabilitiesForUid( 8568 defaultNc, asUid, callingUid, callingPackageName); 8569 enforceAccessPermission(); 8570 break; 8571 case TRACK_SYSTEM_DEFAULT: 8572 enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission(); 8573 networkCapabilities = new NetworkCapabilities(defaultNc); 8574 break; 8575 case BACKGROUND_REQUEST: 8576 enforceNetworkStackOrSettingsPermission(); 8577 // Fall-through since other checks are the same with normal requests. 8578 case REQUEST: 8579 case RESERVATION: 8580 networkCapabilities = new NetworkCapabilities(networkCapabilities); 8581 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 8582 callingAttributionTag, callingUid); 8583 // TODO: this is incorrect. We mark the request as metered or not depending on 8584 // the state of the app when the request is filed, but we never change the 8585 // request if the app changes network state. http://b/29964605 8586 enforceMeteredApnPolicy(networkCapabilities); 8587 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid); 8588 break; 8589 case LISTEN_FOR_BEST: 8590 enforceAccessPermission(); 8591 networkCapabilities = new NetworkCapabilities(networkCapabilities); 8592 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid); 8593 break; 8594 default: 8595 throw new IllegalArgumentException("Unsupported request type " + reqType); 8596 } 8597 ensureRequestableCapabilities(networkCapabilities); 8598 ensureSufficientPermissionsForRequest(networkCapabilities, 8599 Binder.getCallingPid(), callingUid, callingPackageName); 8600 8601 // Enforce FOREGROUND if the caller does not have permission to use background network. 8602 if (reqType == LISTEN_FOR_BEST) { 8603 restrictBackgroundRequestForCaller(networkCapabilities); 8604 } 8605 8606 // Set the UID range for this request to the single UID of the requester, unless the 8607 // requester has the permission to specify other UIDs. 8608 // This will overwrite any allowed UIDs in the requested capabilities. Though there 8609 // are no visible methods to set the UIDs, an app could use reflection to try and get 8610 // networks for other apps so it's essential that the UIDs are overwritten. 8611 // Also set the requester UID and package name in the request. 8612 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 8613 callingUid, callingPackageName); 8614 8615 if (timeoutMs < 0) { 8616 throw new IllegalArgumentException("Bad timeout specified"); 8617 } 8618 8619 // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were 8620 // copied from the default request above. (This is necessary to ensure, for example, that 8621 // the callback does not leak sensitive information to unprivileged apps.) Check that the 8622 // changes don't alter request matching. 8623 if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT && 8624 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) { 8625 throw new IllegalStateException( 8626 "TRACK_SYSTEM_DEFAULT capabilities don't match default request: " 8627 + networkCapabilities + " vs. " + defaultNc); 8628 } 8629 8630 final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 8631 nextNetworkRequestId(), reqType); 8632 final NetworkRequestInfo nri = getNriToRegister( 8633 asUid, networkRequest, messenger, binder, callbackFlags, 8634 callingAttributionTag, declaredMethodsFlag); 8635 if (DBG) log("requestNetwork for " + nri); 8636 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST, nri); 8637 if (timeoutMs > 0) { 8638 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 8639 nri), timeoutMs); 8640 } 8641 return networkRequest; 8642 } 8643 8644 /** 8645 * Return the nri to be used when registering a network request. Specifically, this is used with 8646 * requests registered to track the default request. If there is currently a per-app default 8647 * tracking the app requestor, then we need to create a version of this nri that mirrors that of 8648 * the tracking per-app default so that callbacks are sent to the app requestor appropriately. 8649 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 8650 * when a privileged caller is tracking the default network for another uid. 8651 * @param nr the network request for the nri. 8652 * @param msgr the messenger for the nri. 8653 * @param binder the binder for the nri. 8654 * @param callingAttributionTag the calling attribution tag for the nri. 8655 * @return the nri to register. 8656 */ 8657 private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, 8658 @Nullable final Messenger msgr, @Nullable final IBinder binder, 8659 @NetworkCallback.Flag int callbackFlags, 8660 @Nullable String callingAttributionTag, int declaredMethodsFlags) { 8661 final List<NetworkRequest> requests; 8662 if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) { 8663 requests = copyDefaultNetworkRequestsForUid( 8664 asUid, nr.getRequestorUid(), nr.getRequestorPackageName()); 8665 } else { 8666 requests = Collections.singletonList(nr); 8667 } 8668 return new NetworkRequestInfo( 8669 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag, 8670 declaredMethodsFlags); 8671 } 8672 8673 private boolean shouldCheckCapabilitiesDeclaration( 8674 @NonNull final NetworkCapabilities networkCapabilities, final int callingUid, 8675 @NonNull final String callingPackageName) { 8676 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 8677 // Only run the check if the change is enabled. 8678 if (!mDeps.isChangeEnabled( 8679 ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION, 8680 callingPackageName, user)) { 8681 return false; 8682 } 8683 8684 return networkCapabilities.hasCapability( 8685 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 8686 || networkCapabilities.hasCapability( 8687 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY); 8688 } 8689 8690 private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName, 8691 @NonNull final NetworkCapabilities networkCapabilities, int callingUid) { 8692 // This check is added to fix the linter error for "current min is 30", which is not going 8693 // to happen because Connectivity service always run in S+. 8694 if (!mDeps.isAtLeastS()) { 8695 Log.wtf(TAG, "Connectivity service should always run in at least SDK S"); 8696 return; 8697 } 8698 ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities; 8699 final long ident = Binder.clearCallingIdentity(); 8700 try { 8701 synchronized (mSelfCertifiedCapabilityCache) { 8702 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get( 8703 callerPackageName); 8704 if (applicationNetworkCapabilities == null) { 8705 final PackageManager packageManager = 8706 mContext.createContextAsUser(UserHandle.getUserHandleForUid( 8707 callingUid), 0 /* flags */).getPackageManager(); 8708 final PackageManager.Property networkSliceProperty = packageManager.getProperty( 8709 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 8710 callerPackageName 8711 ); 8712 final XmlResourceParser parser = packageManager 8713 .getResourcesForApplication(callerPackageName) 8714 .getXml(networkSliceProperty.getResourceId()); 8715 applicationNetworkCapabilities = 8716 ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser); 8717 mSelfCertifiedCapabilityCache.put(callerPackageName, 8718 applicationNetworkCapabilities); 8719 } 8720 8721 } 8722 } catch (PackageManager.NameNotFoundException ne) { 8723 throw new SecurityException( 8724 "Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES 8725 + " property"); 8726 } catch (XmlPullParserException | IOException | InvalidTagException e) { 8727 throw new SecurityException(e.getMessage()); 8728 } finally { 8729 Binder.restoreCallingIdentity(ident); 8730 } 8731 8732 applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared( 8733 networkCapabilities); 8734 } 8735 8736 private boolean canRequestRestrictedNetworkDueToCarrierPrivileges( 8737 NetworkCapabilities networkCapabilities, int callingUid) { 8738 if (mRequestRestrictedWifiEnabled) { 8739 // For U+ devices, callers with carrier privilege could request restricted networks 8740 // with CBS capabilities, or any restricted WiFi networks. 8741 return ((networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS) 8742 || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) 8743 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)); 8744 } else { 8745 // For T+ devices, callers with carrier privilege could request with CBS 8746 // capabilities. 8747 return (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS) 8748 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)); 8749 } 8750 } 8751 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, 8752 String callingPackageName, String callingAttributionTag, final int callingUid) { 8753 if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid, 8754 callingPackageName)) { 8755 enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities, 8756 callingUid); 8757 } 8758 if (!networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 8759 if (!canRequestRestrictedNetworkDueToCarrierPrivileges( 8760 networkCapabilities, callingUid)) { 8761 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 8762 } 8763 } else { 8764 enforceChangePermission(callingPackageName, callingAttributionTag); 8765 } 8766 } 8767 8768 @Override 8769 public boolean requestBandwidthUpdate(Network network) { 8770 enforceAccessPermission(); 8771 NetworkAgentInfo nai = null; 8772 if (network == null) { 8773 return false; 8774 } 8775 synchronized (mNetworkForNetId) { 8776 nai = mNetworkForNetId.get(network.getNetId()); 8777 } 8778 if (nai != null) { 8779 nai.onBandwidthUpdateRequested(); 8780 synchronized (mBandwidthRequests) { 8781 final int uid = mDeps.getCallingUid(); 8782 Integer uidReqs = mBandwidthRequests.get(uid); 8783 if (uidReqs == null) { 8784 uidReqs = 0; 8785 } 8786 mBandwidthRequests.put(uid, ++uidReqs); 8787 } 8788 return true; 8789 } 8790 return false; 8791 } 8792 8793 private boolean isSystem(int uid) { 8794 return uid < Process.FIRST_APPLICATION_UID; 8795 } 8796 8797 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 8798 final int uid = mDeps.getCallingUid(); 8799 if (isSystem(uid)) { 8800 // Exemption for system uid. 8801 return; 8802 } 8803 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 8804 // Policy already enforced. 8805 return; 8806 } 8807 final boolean isRestrictedOnMeteredNetworks = mDeps.isAtLeastV() 8808 ? mBpfNetMaps.isUidRestrictedOnMeteredNetworks(uid) 8809 : BinderUtils.withCleanCallingIdentity(() -> 8810 mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)); 8811 if (isRestrictedOnMeteredNetworks) { 8812 // If UID is restricted, don't allow them to bring up metered APNs. 8813 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 8814 } 8815 } 8816 8817 @Override 8818 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 8819 PendingIntent operation, @NonNull String callingPackageName, 8820 @Nullable String callingAttributionTag) { 8821 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8822 final int callingUid = mDeps.getCallingUid(); 8823 networkCapabilities = new NetworkCapabilities(networkCapabilities); 8824 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 8825 callingAttributionTag, callingUid); 8826 enforceMeteredApnPolicy(networkCapabilities); 8827 ensureRequestableCapabilities(networkCapabilities); 8828 ensureSufficientPermissionsForRequest(networkCapabilities, 8829 Binder.getCallingPid(), callingUid, callingPackageName); 8830 restrictRequestNetworkCapabilitiesForCaller( 8831 networkCapabilities, callingUid, callingPackageName); 8832 8833 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 8834 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 8835 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 8836 callingAttributionTag); 8837 if (DBG) log("pendingRequest for " + nri); 8838 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, nri); 8839 return networkRequest; 8840 } 8841 8842 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 8843 mHandler.sendMessageDelayed( 8844 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 8845 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 8846 } 8847 8848 @Override 8849 public void releasePendingNetworkRequest(PendingIntent operation) { 8850 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8851 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 8852 mDeps.getCallingUid(), 0, operation)); 8853 } 8854 8855 // In order to implement the compatibility measure for pre-M apps that call 8856 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 8857 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 8858 // This ensures it has permission to do so. 8859 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 8860 if (nc == null) { 8861 return false; 8862 } 8863 int[] transportTypes = nc.getTransportTypes(); 8864 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 8865 return false; 8866 } 8867 try { 8868 mContext.enforceCallingOrSelfPermission( 8869 android.Manifest.permission.ACCESS_WIFI_STATE, 8870 "ConnectivityService"); 8871 } catch (SecurityException e) { 8872 return false; 8873 } 8874 return true; 8875 } 8876 8877 private boolean isAppRequest(NetworkRequestInfo nri) { 8878 return nri.mMessenger != null || nri.mPendingIntent != null; 8879 } 8880 8881 private void trackUidAndMaybePostCurrentBlockedReason(final NetworkRequestInfo nri) { 8882 if (!isAppRequest(nri)) { 8883 Log.wtf(TAG, "trackUidAndMaybePostCurrentBlockedReason is called for non app" 8884 + "request: " + nri); 8885 return; 8886 } 8887 nri.mPerUidCounter.incrementCountOrThrow(nri.mUid); 8888 8889 // If nri.mMessenger is null, this nri does not have NetworkCallback so ConnectivityService 8890 // does not need to send onBlockedStatusChanged callback for this uid and does not need to 8891 // track the uid in mBlockedStatusTrackingUids 8892 if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) { 8893 return; 8894 } 8895 if (nri.mUidTrackedForBlockedStatus) { 8896 Log.wtf(TAG, "Nri is already tracked for sending blocked status: " + nri); 8897 return; 8898 } 8899 nri.mUidTrackedForBlockedStatus = true; 8900 synchronized (mBlockedStatusTrackingUids) { 8901 final int uid = nri.mAsUid; 8902 final int count = mBlockedStatusTrackingUids.get(uid, 0); 8903 if (count == 0) { 8904 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 8905 List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))))); 8906 } 8907 mBlockedStatusTrackingUids.put(uid, count + 1); 8908 } 8909 } 8910 8911 private void trackUidAndRegisterNetworkRequest(final int event, NetworkRequestInfo nri) { 8912 // Post the update of the UID's blocked reasons before posting the message that registers 8913 // the callback. This is necessary because if the callback immediately matches a request, 8914 // the onBlockedStatusChanged must be called with the correct blocked reasons. 8915 // Also, once trackUidAndMaybePostCurrentBlockedReason is called, the register network 8916 // request event must be posted, because otherwise the counter for uid will never be 8917 // decremented. 8918 trackUidAndMaybePostCurrentBlockedReason(nri); 8919 mHandler.sendMessage(mHandler.obtainMessage(event, nri)); 8920 } 8921 8922 private void maybeUntrackUidAndClearBlockedReasons(final NetworkRequestInfo nri) { 8923 if (!isAppRequest(nri)) { 8924 // Not an app request. 8925 return; 8926 } 8927 nri.mPerUidCounter.decrementCount(nri.mUid); 8928 8929 if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) { 8930 return; 8931 } 8932 if (!nri.mUidTrackedForBlockedStatus) { 8933 Log.wtf(TAG, "Nri is not tracked for sending blocked status: " + nri); 8934 return; 8935 } 8936 nri.mUidTrackedForBlockedStatus = false; 8937 synchronized (mBlockedStatusTrackingUids) { 8938 final int count = mBlockedStatusTrackingUids.get(nri.mAsUid); 8939 if (count > 1) { 8940 mBlockedStatusTrackingUids.put(nri.mAsUid, count - 1); 8941 } else { 8942 mBlockedStatusTrackingUids.delete(nri.mAsUid); 8943 mUidBlockedReasons.delete(nri.mAsUid); 8944 } 8945 } 8946 } 8947 8948 @Override 8949 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 8950 Messenger messenger, IBinder binder, 8951 @NetworkCallback.Flag int callbackFlags, 8952 @NonNull String callingPackageName, @NonNull String callingAttributionTag, 8953 int declaredMethodsFlag) { 8954 if (declaredMethodsFlag == 0) { 8955 Log.wtf(TAG, "listenForNetwork called without declaredMethodsFlag from " 8956 + callingPackageName); 8957 declaredMethodsFlag = DECLARED_METHODS_ALL; 8958 } 8959 final int callingUid = mDeps.getCallingUid(); 8960 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 8961 enforceAccessPermission(); 8962 } 8963 8964 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 8965 ensureSufficientPermissionsForRequest(networkCapabilities, 8966 Binder.getCallingPid(), callingUid, callingPackageName); 8967 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 8968 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 8969 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 8970 // onLost and onAvailable callbacks when networks move in and out of the background. 8971 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 8972 // can't request networks. 8973 restrictBackgroundRequestForCaller(nc); 8974 ensureListenableCapabilities(nc); 8975 8976 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 8977 NetworkRequest.Type.LISTEN); 8978 NetworkRequestInfo nri = 8979 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags, 8980 callingAttributionTag, declaredMethodsFlag); 8981 if (VDBG) log("listenForNetwork for " + nri); 8982 8983 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER, nri); 8984 return networkRequest; 8985 } 8986 8987 @Override 8988 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 8989 PendingIntent operation, @NonNull String callingPackageName, 8990 @Nullable String callingAttributionTag) { 8991 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 8992 final int callingUid = mDeps.getCallingUid(); 8993 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 8994 enforceAccessPermission(); 8995 } 8996 ensureListenableCapabilities(networkCapabilities); 8997 ensureSufficientPermissionsForRequest(networkCapabilities, 8998 Binder.getCallingPid(), callingUid, callingPackageName); 8999 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 9000 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 9001 9002 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 9003 NetworkRequest.Type.LISTEN); 9004 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 9005 callingAttributionTag); 9006 if (VDBG) log("pendingListenForNetwork for " + nri); 9007 9008 trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri); 9009 } 9010 9011 /** Returns the next Network provider ID. */ 9012 public final int nextNetworkProviderId() { 9013 return mNextNetworkProviderId.getAndIncrement(); 9014 } 9015 9016 @Override 9017 public void releaseNetworkRequest(NetworkRequest networkRequest) { 9018 ensureNetworkRequestHasSupportedType(networkRequest, false /* isMultilayerRequest */); 9019 mHandler.sendMessage(mHandler.obtainMessage( 9020 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest)); 9021 } 9022 9023 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { 9024 if (mNetworkProviderInfos.containsKey(npi.messenger)) { 9025 // Avoid creating duplicates. even if an app makes a direct AIDL call. 9026 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, 9027 // as that will throw if a duplicate provider is registered. 9028 loge("Attempt to register existing NetworkProviderInfo " 9029 + mNetworkProviderInfos.get(npi.messenger).name); 9030 return; 9031 } 9032 9033 if (DBG) log("Got NetworkProvider Messenger for " + npi.name); 9034 mNetworkProviderInfos.put(npi.messenger, npi); 9035 npi.connect(mContext, mTrackerHandler); 9036 } 9037 9038 @Override 9039 public int registerNetworkProvider(Messenger messenger, String name) { 9040 enforceNetworkFactoryOrSettingsPermission(); 9041 Objects.requireNonNull(messenger, "messenger must be non-null"); 9042 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, 9043 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); 9044 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); 9045 return npi.providerId; 9046 } 9047 9048 @Override 9049 public void unregisterNetworkProvider(Messenger messenger) { 9050 enforceNetworkFactoryOrSettingsPermission(); 9051 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); 9052 } 9053 9054 @Override 9055 public void offerNetwork(final int providerId, 9056 @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, 9057 @NonNull final INetworkOfferCallback callback) { 9058 Objects.requireNonNull(score); 9059 Objects.requireNonNull(caps); 9060 Objects.requireNonNull(callback); 9061 if (caps.hasTransport(TRANSPORT_TEST)) { 9062 enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS); 9063 } else { 9064 enforceNetworkFactoryPermission(); 9065 } 9066 final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 9067 final NetworkOffer offer = new NetworkOffer( 9068 FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi), 9069 caps, callback, providerId); 9070 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer)); 9071 } 9072 9073 private void updateOfferScore(final NetworkOffer offer) { 9074 final boolean yieldToBadWiFi = 9075 offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 9076 final NetworkOffer newOffer = new NetworkOffer( 9077 offer.score.withYieldToBadWiFi(yieldToBadWiFi), 9078 offer.caps, offer.callback, offer.providerId); 9079 if (offer.equals(newOffer)) return; 9080 handleRegisterNetworkOffer(newOffer); 9081 } 9082 9083 @Override 9084 public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { 9085 Objects.requireNonNull(callback); 9086 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback)); 9087 } 9088 9089 private void handleUnregisterNetworkProvider(Messenger messenger) { 9090 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); 9091 if (npi == null) { 9092 loge("Failed to find Messenger in unregisterNetworkProvider"); 9093 return; 9094 } 9095 // Unregister all the offers from this provider 9096 final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>(); 9097 for (final NetworkOfferInfo noi : mNetworkOffers) { 9098 if (noi.offer.providerId == npi.providerId) { 9099 // Can't call handleUnregisterNetworkOffer here because iteration is in progress 9100 toRemove.add(noi); 9101 } 9102 } 9103 for (final NetworkOfferInfo noi : toRemove) { 9104 handleUnregisterNetworkOffer(noi, true /* releaseReservations */); 9105 } 9106 if (DBG) log("unregisterNetworkProvider for " + npi.name); 9107 } 9108 9109 @Override 9110 public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) { 9111 if (request.hasTransport(TRANSPORT_TEST)) { 9112 enforceNetworkFactoryOrTestNetworksPermission(); 9113 } else { 9114 enforceNetworkFactoryPermission(); 9115 } 9116 final NetworkRequestInfo nri = mNetworkRequests.get(request); 9117 if (nri != null) { 9118 // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests. 9119 ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable"); 9120 mHandler.post(() -> handleReleaseNetworkRequest( 9121 nri.mRequests.get(0), mDeps.getCallingUid(), true)); 9122 } 9123 } 9124 9125 // NOTE: Accessed on multiple threads, must be synchronized on itself. 9126 @GuardedBy("mNetworkForNetId") 9127 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); 9128 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 9129 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so 9130 // there may not be a strict 1:1 correlation between the two. 9131 private final NetIdManager mNetIdManager; 9132 9133 // Tracks all NetworkAgents that are currently registered. 9134 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 9135 // Code iterating over this set is recommended to use forAllNetworkAgentInfos(), which allows 9136 // code within the loop to disconnect networks during iteration without causing null pointer or 9137 // OOB exceptions. 9138 private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>(); 9139 9140 // UID ranges for users that are currently blocked by VPNs. 9141 // This array is accessed and iterated on multiple threads without holding locks, so its 9142 // contents must never be mutated. When the ranges change, the array is replaced with a new one 9143 // (on the handler thread). 9144 private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>(); 9145 9146 // Must only be accessed on the handler thread 9147 @NonNull 9148 private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>(); 9149 9150 @GuardedBy("mBlockedAppUids") 9151 private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 9152 9153 // Current OEM network preferences. This object must only be written to on the handler thread. 9154 // Since it is immutable and always non-null, other threads may read it if they only care 9155 // about seeing a consistent object but not that it is current. 9156 @NonNull 9157 private OemNetworkPreferences mOemNetworkPreferences = 9158 new OemNetworkPreferences.Builder().build(); 9159 // Current per-profile network preferences. This object follows the same threading rules as 9160 // the OEM network preferences above. 9161 @NonNull 9162 private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> 9163 mProfileNetworkPreferences = new NetworkPreferenceList<>(); 9164 9165 // Current VPN network preferences. This object follows the same threading rules as the OEM 9166 // network preferences above. 9167 @NonNull 9168 private NetworkPreferenceList<String, VpnNetworkPreferenceInfo> 9169 mVpnNetworkPreferences = new NetworkPreferenceList<>(); 9170 9171 // A set of UIDs that should use mobile data preferentially if available. This object follows 9172 // the same threading rules as the OEM network preferences above. 9173 @NonNull 9174 private Set<Integer> mMobileDataPreferredUids = new ArraySet<>(); 9175 9176 // OemNetworkPreferences activity String log entries. 9177 private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20; 9178 @NonNull 9179 private final LocalLog mOemNetworkPreferencesLogs = 9180 new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS); 9181 9182 /** 9183 * Determine whether a given package has a mapping in the current OemNetworkPreferences. 9184 * @param packageName the package name to check existence of a mapping for. 9185 * @return true if a mapping exists, false otherwise 9186 */ 9187 private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) { 9188 return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName); 9189 } 9190 9191 // The always-on request for an Internet-capable network that apps without a specific default 9192 // fall back to. 9193 @VisibleForTesting 9194 @NonNull 9195 final NetworkRequestInfo mDefaultRequest; 9196 // Collection of NetworkRequestInfo's used for default networks. 9197 // This set is read and iterated on multiple threads. 9198 // Using CopyOnWriteArraySet since number of default network request is small (system default 9199 // network request + per-app default network requests) and updated infrequently but read 9200 // frequently. 9201 @VisibleForTesting 9202 @NonNull 9203 final CopyOnWriteArraySet<NetworkRequestInfo> mDefaultNetworkRequests = 9204 new CopyOnWriteArraySet<>(); 9205 9206 9207 private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) { 9208 return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri); 9209 } 9210 9211 /** 9212 * Return the default network request currently tracking the given uid. 9213 * @param uid the uid to check. 9214 * @return the NetworkRequestInfo tracking the given uid. 9215 */ 9216 @NonNull 9217 private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) { 9218 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 9219 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 9220 // Checking the first request is sufficient as only multilayer requests will have more 9221 // than one request and for multilayer, all requests will track the same uids. 9222 if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) { 9223 // Find out the highest priority request. 9224 if (nri.hasHigherOrderThan(highestPriorityNri)) { 9225 highestPriorityNri = nri; 9226 } 9227 } 9228 } 9229 return highestPriorityNri; 9230 } 9231 9232 /** 9233 * Get a copy of the network requests of the default request that is currently tracking the 9234 * given uid. 9235 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 9236 * when a privileged caller is tracking the default network for another uid. 9237 * @param requestorUid the uid to check the default for. 9238 * @param requestorPackageName the requestor's package name. 9239 * @return a copy of the default's NetworkRequest that is tracking the given uid. 9240 */ 9241 @NonNull 9242 private List<NetworkRequest> copyDefaultNetworkRequestsForUid( 9243 final int asUid, final int requestorUid, @NonNull final String requestorPackageName) { 9244 return copyNetworkRequestsForUid( 9245 getDefaultRequestTrackingUid(asUid).mRequests, 9246 asUid, requestorUid, requestorPackageName); 9247 } 9248 9249 /** 9250 * Copy the given nri's NetworkRequest collection. 9251 * @param requestsToCopy the NetworkRequest collection to be copied. 9252 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 9253 * when a privileged caller is tracking the default network for another uid. 9254 * @param requestorUid the uid to set on the copied collection. 9255 * @param requestorPackageName the package name to set on the copied collection. 9256 * @return the copied NetworkRequest collection. 9257 */ 9258 @NonNull 9259 private List<NetworkRequest> copyNetworkRequestsForUid( 9260 @NonNull final List<NetworkRequest> requestsToCopy, final int asUid, 9261 final int requestorUid, @NonNull final String requestorPackageName) { 9262 final List<NetworkRequest> requests = new ArrayList<>(); 9263 for (final NetworkRequest nr : requestsToCopy) { 9264 requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid( 9265 nr.networkCapabilities, asUid, requestorUid, requestorPackageName), 9266 nr.legacyType, nextNetworkRequestId(), nr.type)); 9267 } 9268 return requests; 9269 } 9270 9271 @NonNull 9272 private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid( 9273 @NonNull final NetworkCapabilities netCapToCopy, final int asUid, 9274 final int requestorUid, @NonNull final String requestorPackageName) { 9275 // These capabilities are for a TRACK_DEFAULT callback, so: 9276 // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between 9277 // mDefaultRequest and a per-UID default request. 9278 // TODO: stop depending on the fact that these two unrelated things happen to be the same 9279 // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will 9280 // not do this in the case of a privileged application. 9281 final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy); 9282 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 9283 netCap.setSingleUid(asUid); 9284 restrictRequestUidsForCallerAndSetRequestorInfo( 9285 netCap, requestorUid, requestorPackageName); 9286 return netCap; 9287 } 9288 9289 /** 9290 * Get the nri that is currently being tracked for callbacks by per-app defaults. 9291 * @param nr the network request to check for equality against. 9292 * @return the nri if one exists, null otherwise. 9293 */ 9294 @Nullable 9295 private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) { 9296 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 9297 if (nri.getNetworkRequestForCallback().equals(nr)) { 9298 return nri; 9299 } 9300 } 9301 return null; 9302 } 9303 9304 /** 9305 * Check if an nri is currently being managed by per-app default networking. 9306 * @param nri the nri to check. 9307 * @return true if this nri is currently being managed by per-app default networking. 9308 */ 9309 private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) { 9310 // nri.mRequests.get(0) is only different from the original request filed in 9311 // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default 9312 // functionality therefore if these two don't match, it means this particular nri is 9313 // currently being managed by a per-app default. 9314 return nri.getNetworkRequestForCallback() != nri.mRequests.get(0); 9315 } 9316 9317 /** 9318 * Determine if an nri is a managed default request that disallows default networking. 9319 * @param nri the request to evaluate 9320 * @return true if device-default networking is disallowed 9321 */ 9322 private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) { 9323 // Check if this nri is a managed default that supports the default network at its 9324 // lowest priority request. 9325 final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0); 9326 final NetworkCapabilities lowestPriorityNetCap = 9327 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities; 9328 return isPerAppDefaultRequest(nri) 9329 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities( 9330 lowestPriorityNetCap)); 9331 } 9332 9333 // Request used to optionally keep mobile data active even when higher 9334 // priority networks like Wi-Fi are active. 9335 private final NetworkRequest mDefaultMobileDataRequest; 9336 9337 // Request used to optionally keep wifi data active even when higher 9338 // priority networks like ethernet are active. 9339 private final NetworkRequest mDefaultWifiRequest; 9340 9341 // Request used to optionally keep vehicle internal network always active 9342 private final NetworkRequest mDefaultVehicleRequest; 9343 9344 // Sentinel NAI used to direct apps with default networks that should have no connectivity to a 9345 // network with no service. This NAI should never be matched against, nor should any public API 9346 // ever return the associated network. For this reason, this NAI is not in the list of available 9347 // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device 9348 // default requests that don't support using the device default network which will ultimately 9349 // allow ConnectivityService to use this no-service network when calling makeDefaultForApps(). 9350 @VisibleForTesting 9351 final NetworkAgentInfo mNoServiceNetwork; 9352 9353 // The NetworkAgentInfo currently satisfying the default request, if any. 9354 private NetworkAgentInfo getDefaultNetwork() { 9355 return mDefaultRequest.mSatisfier; 9356 } 9357 9358 private NetworkAgentInfo getDefaultNetworkForUid(final int uid) { 9359 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 9360 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 9361 // Currently, all network requests will have the same uids therefore checking the first 9362 // one is sufficient. If/when uids are tracked at the nri level, this can change. 9363 final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges(); 9364 if (null == uids) { 9365 continue; 9366 } 9367 for (final UidRange range : uids) { 9368 if (range.contains(uid)) { 9369 if (nri.hasHigherOrderThan(highestPriorityNri)) { 9370 highestPriorityNri = nri; 9371 } 9372 } 9373 } 9374 } 9375 if (!highestPriorityNri.isBeingSatisfied()) return null; 9376 return highestPriorityNri.getSatisfier(); 9377 } 9378 9379 @Nullable 9380 private Network getNetwork(@Nullable NetworkAgentInfo nai) { 9381 return nai != null ? nai.network : null; 9382 } 9383 9384 private void ensureRunningOnConnectivityServiceThread() { 9385 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 9386 } 9387 9388 @VisibleForTesting 9389 protected boolean isDefaultNetwork(NetworkAgentInfo nai) { 9390 return nai == getDefaultNetwork(); 9391 } 9392 9393 /** 9394 * Returns whether local agents are supported on this device. 9395 * 9396 * Local agents are supported from U on TVs, and from V on all devices. 9397 */ 9398 @VisibleForTesting 9399 public boolean areLocalAgentsSupported() { 9400 final PackageManager pm = mContext.getPackageManager(); 9401 // Local agents are supported starting on U on TVs and on V on everything else. 9402 return mDeps.isAtLeastV() || (mDeps.isAtLeastU() && pm.hasSystemFeature(FEATURE_LEANBACK)); 9403 } 9404 9405 /** 9406 * Register a new agent with ConnectivityService to handle a network. 9407 * 9408 * @param na a reference for ConnectivityService to contact the agent asynchronously. 9409 * @param networkInfo the initial info associated with this network. It can be updated later : 9410 * see {@link #updateNetworkInfo}. 9411 * @param linkProperties the initial link properties of this network. They can be updated 9412 * later : see {@link #updateLinkProperties}. 9413 * @param networkCapabilities the initial capabilites of this network. They can be updated 9414 * later : see {@link #updateCapabilities}. 9415 * @param initialScore the initial score of the network. See {@link NetworkAgentInfo#getScore}. 9416 * @param localNetworkConfig config about this local network, or null if not a local network 9417 * @param networkAgentConfig metadata about the network. This is never updated. 9418 * @param providerId the ID of the provider owning this NetworkAgent. 9419 * @return the network created for this agent. 9420 */ 9421 public NetworkAndAgentRegistryParcelable registerNetworkAgent(INetworkAgent na, 9422 NetworkInfo networkInfo, 9423 LinkProperties linkProperties, 9424 NetworkCapabilities networkCapabilities, 9425 @NonNull NetworkScore initialScore, 9426 @Nullable LocalNetworkConfig localNetworkConfig, 9427 NetworkAgentConfig networkAgentConfig, 9428 int providerId) { 9429 Objects.requireNonNull(networkInfo, "networkInfo must not be null"); 9430 Objects.requireNonNull(linkProperties, "linkProperties must not be null"); 9431 Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); 9432 Objects.requireNonNull(initialScore, "initialScore must not be null"); 9433 Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); 9434 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 9435 enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS); 9436 } else { 9437 enforceNetworkFactoryPermission(); 9438 } 9439 final boolean hasLocalCap = 9440 networkCapabilities.hasCapability(NET_CAPABILITY_LOCAL_NETWORK); 9441 if (hasLocalCap && !areLocalAgentsSupported()) { 9442 // Before U, netd doesn't support PHYSICAL_LOCAL networks so this can't work. 9443 throw new IllegalArgumentException("Local agents are not supported in this version"); 9444 } 9445 final boolean hasLocalNetworkConfig = null != localNetworkConfig; 9446 if (hasLocalCap != hasLocalNetworkConfig) { 9447 throw new IllegalArgumentException(null != localNetworkConfig 9448 ? "Only local network agents can have a LocalNetworkConfig" 9449 : "Local network agents must have a LocalNetworkConfig" 9450 ); 9451 } 9452 9453 final int uid = mDeps.getCallingUid(); 9454 final long token = Binder.clearCallingIdentity(); 9455 try { 9456 return registerNetworkAgentInternal(na, networkInfo, linkProperties, 9457 networkCapabilities, initialScore, networkAgentConfig, localNetworkConfig, 9458 providerId, uid); 9459 } finally { 9460 Binder.restoreCallingIdentity(token); 9461 } 9462 } 9463 9464 private NetworkAndAgentRegistryParcelable registerNetworkAgentInternal( 9465 INetworkAgent na, NetworkInfo networkInfo, 9466 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 9467 NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, 9468 @Nullable LocalNetworkConfig localNetworkConfig, int providerId, 9469 int uid) { 9470 9471 // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them 9472 // and mutate them at any time. 9473 final NetworkInfo niCopy = new NetworkInfo(networkInfo); 9474 final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities); 9475 final LinkProperties lpCopy = new LinkProperties(linkProperties); 9476 // No need to copy |localNetworkConfiguration| as it is immutable. 9477 9478 // At this point the capabilities/properties are untrusted and unverified, e.g. checks that 9479 // the capabilities' access UIDs comply with security limitations. They will be sanitized 9480 // as the NAI registration finishes, in handleRegisterNetworkAgent(). This is 9481 // because some of the checks must happen on the handler thread. 9482 final NetworkAgentInfo nai = new NetworkAgentInfo(na, 9483 new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy, 9484 localNetworkConfig, currentScore, mContext, mTrackerHandler, 9485 new NetworkAgentConfig(networkAgentConfig), this, mNetd, mDnsResolver, providerId, 9486 uid, mLingerDelayMs, mQosCallbackTracker, mDeps); 9487 9488 final String extraInfo = niCopy.getExtraInfo(); 9489 final String name = TextUtils.isEmpty(extraInfo) 9490 ? nai.networkCapabilities.getSsid() : extraInfo; 9491 if (DBG) log("registerNetworkAgent " + nai); 9492 mDeps.getNetworkStack().makeNetworkMonitor( 9493 nai.network, name, new NetworkMonitorCallbacks(nai)); 9494 // NetworkAgentInfo registration is done, but CS will only accept messages when the 9495 // NetworkMonitor is created. If the network disconnects or sends any other event 9496 // before that, messages are deferred by the Tracker Handler until it is (by asking 9497 // NetworkAgentInfo to do it). The window is very small unless the NetworkStack 9498 // doesn't reply immediately, which would mean a broken system anyway. 9499 final NetworkAndAgentRegistryParcelable result = new NetworkAndAgentRegistryParcelable(); 9500 result.network = nai.network; 9501 result.registry = nai.getRegistry(); 9502 return result; 9503 } 9504 9505 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { 9506 if (VDBG) log("Network Monitor created for " + nai); 9507 // Store a copy of the declared capabilities. 9508 nai.setDeclaredCapabilities(nai.networkCapabilities); 9509 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said. 9510 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, 9511 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator))); 9512 processLinkPropertiesFromAgent(nai, nai.linkProperties); 9513 9514 mNetworkAgentInfos.add(nai); 9515 synchronized (mNetworkForNetId) { 9516 mNetworkForNetId.put(nai.network.getNetId(), nai); 9517 } 9518 9519 try { 9520 networkMonitor.start(); 9521 } catch (RemoteException e) { 9522 e.rethrowAsRuntimeException(); 9523 } 9524 9525 if (nai.isLocalNetwork()) { 9526 handleUpdateLocalNetworkConfig(nai, null /* oldConfig */, nai.localNetworkConfig); 9527 } 9528 nai.notifyRegistered(networkMonitor); 9529 NetworkInfo networkInfo = nai.networkInfo; 9530 updateNetworkInfo(nai, networkInfo); 9531 if (nai.isVPN()) updateVpnUids(nai, null, nai.networkCapabilities); 9532 nai.processEnqueuedMessages(mTrackerHandler::handleMessage); 9533 } 9534 9535 private class NetworkOfferInfo implements IBinder.DeathRecipient { 9536 @NonNull public final NetworkOffer offer; 9537 9538 NetworkOfferInfo(@NonNull final NetworkOffer offer) { 9539 this.offer = offer; 9540 } 9541 9542 @Override 9543 public void binderDied() { 9544 mHandler.post(() -> handleUnregisterNetworkOffer(this, true /* releaseReservations */)); 9545 } 9546 } 9547 9548 private boolean isNetworkProviderWithIdRegistered(final int providerId) { 9549 for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 9550 if (npi.providerId == providerId) return true; 9551 } 9552 return false; 9553 } 9554 9555 @Nullable 9556 private NetworkRequestInfo maybeGetNriForReservedOffer(NetworkOfferInfo noi) { 9557 final int reservationId = noi.offer.caps.getReservationId(); 9558 if (reservationId == RES_ID_UNSET) return null; // not a reserved offer. 9559 9560 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 9561 if (reservationId == nri.getReservationId()) return nri; 9562 } 9563 // The reservation was withdrawn or the reserving process died. 9564 return null; 9565 } 9566 9567 /** 9568 * Register or update a network offer. 9569 * @param newOffer The new offer. If the callback member is the same as an existing 9570 * offer, it is an update of that offer. 9571 */ 9572 // TODO : rename this to handleRegisterOrUpdateNetworkOffer 9573 private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) { 9574 ensureRunningOnConnectivityServiceThread(); 9575 if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) { 9576 // This may actually happen if a provider updates its score or registers and then 9577 // immediately unregisters. The offer would still be in the handler queue, but the 9578 // provider would have been removed. 9579 if (DBG) log("Received offer from an unregistered provider"); 9580 return; 9581 } 9582 final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback); 9583 9584 // If a reserved offer is updated, ensure the capabilities are not changed. This ensures 9585 // that the reserved offer's capabilities match the ones passed by the onReserved callback, 9586 // which is sent only once. 9587 // 9588 // TODO: consider letting the provider change the capabilities of an offer as long as they 9589 // continue to satisfy the capabilities that were passed to onReserved. This is not needed 9590 // today, but it shouldn't violate the API contract: 9591 // - NetworkOffer capabilities are not promises 9592 // - The app making a reservation must never assume that the capabilities of the reserved 9593 // network are equal to the ones that were passed to onReserved. There will almost always be 9594 // other capabilities, for example, those that change at runtime such as VALIDATED or 9595 // NOT_SUSPENDED. 9596 if (null != existingOffer 9597 && existingOffer.offer.caps.getReservationId() != RES_ID_UNSET 9598 && existingOffer.offer.caps.getReservationId() != RES_ID_MATCH_ALL_RESERVATIONS 9599 && !newOffer.caps.equals(existingOffer.offer.caps)) { 9600 // Reserved offers are not allowed to update their NetworkCapabilities. 9601 // Doing so will immediately remove the offer from CS and send onUnavailable to the app. 9602 handleUnregisterNetworkOffer(existingOffer, true /* releaseReservations */); 9603 existingOffer.offer.notifyUnneeded(); 9604 logwtf("Reserved offers must never update their reserved NetworkCapabilities"); 9605 return; 9606 } 9607 9608 final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer); 9609 if (null != existingOffer) { 9610 // Do not send onUnavailable for a reserved offer when updating it. 9611 handleUnregisterNetworkOffer(existingOffer, false /* releaseReservations */); 9612 newOffer.migrateFrom(existingOffer.offer); 9613 if (DBG) { 9614 // handleUnregisterNetworkOffer has already logged the old offer 9615 log("update offer from providerId " + newOffer.providerId + " new : " + newOffer); 9616 } 9617 } else { 9618 final NetworkRequestInfo reservationNri = maybeGetNriForReservedOffer(noi); 9619 if (reservationNri != null) { 9620 // A NetworkRequest is only allowed to trigger a single reserved offer (and 9621 // onReserved() callback). All subsequent offers are ignored. This either indicates 9622 // a bug in the provider (e.g., responding twice to the same reservation, or 9623 // updating the capabilities of a reserved offer), or multiple providers responding 9624 // to the same offer (which could happen, but is not useful to the requesting app). 9625 if (reservationNri.getReservedCapabilities() != null) { 9626 loge("A reservation can only trigger a single offer; new offer is ignored."); 9627 return; 9628 } 9629 // Always update the reserved offer before calling callCallbackForRequest. 9630 reservationNri.setReservedCapabilities(noi.offer.caps); 9631 callCallbackForRequest( 9632 reservationNri, null /*networkAgent*/, CALLBACK_RESERVED, 0 /*arg1*/); 9633 } 9634 if (DBG) { 9635 log("register offer from providerId " + newOffer.providerId + " : " + newOffer); 9636 } 9637 } 9638 9639 try { 9640 noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */); 9641 } catch (RemoteException e) { 9642 noi.binderDied(); 9643 return; 9644 } 9645 mNetworkOffers.add(noi); 9646 issueNetworkNeeds(noi); 9647 } 9648 9649 private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi, 9650 boolean releaseReservations) { 9651 ensureRunningOnConnectivityServiceThread(); 9652 if (DBG) { 9653 log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer); 9654 } 9655 9656 // If the provider removes the offer and dies immediately afterwards this 9657 // function may be called twice in a row, but the array will no longer contain 9658 // the offer. 9659 if (!mNetworkOffers.remove(noi)) return; 9660 9661 // If the offer was brought up as a result of a reservation, inform the RESERVATION request 9662 // that it has disappeared. There is no need to reset nri.mReservedCapabilities to null, as 9663 // CALLBACK_UNAVAIL will cause the request to be torn down. In addition, leaving 9664 // nri.mReservedOffer set prevents an additional onReserved() callback in 9665 // handleRegisterNetworkOffer() in the case of a migration (which would be ignored as it 9666 // follows an onUnavailable). 9667 final NetworkRequestInfo nri = maybeGetNriForReservedOffer(noi); 9668 if (releaseReservations && nri != null) { 9669 handleRemoveNetworkRequest(nri); 9670 callCallbackForRequest(nri, null /* networkAgent */, CALLBACK_UNAVAIL, 0 /* arg1 */); 9671 } 9672 noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */); 9673 } 9674 9675 @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback( 9676 @NonNull final INetworkOfferCallback callback) { 9677 ensureRunningOnConnectivityServiceThread(); 9678 for (final NetworkOfferInfo noi : mNetworkOffers) { 9679 if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi; 9680 } 9681 return null; 9682 } 9683 9684 /** 9685 * Called when receiving LinkProperties directly from a NetworkAgent. 9686 * Stores into |nai| any data coming from the agent that might also be written to the network's 9687 * LinkProperties by ConnectivityService itself. This ensures that the data provided by the 9688 * agent is not lost when updateLinkProperties is called. 9689 * This method should never alter the agent's LinkProperties, only store data in |nai|. 9690 */ 9691 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { 9692 lp.ensureDirectlyConnectedRoutes(); 9693 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix()); 9694 nai.networkAgentPortalData = lp.getCaptivePortalData(); 9695 } 9696 9697 private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, 9698 @Nullable LinkProperties oldLp) { 9699 int netId = networkAgent.network.getNetId(); 9700 9701 // The NetworkAgent does not know whether clatd is running on its network or not, or whether 9702 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure 9703 // the LinkProperties for the network are accurate. 9704 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 9705 9706 updateInterfaces(newLp, oldLp, netId, networkAgent); 9707 9708 // update filtering rules, need to happen after the interface update so netd knows about the 9709 // new interface (the interface name -> index map becomes initialized) 9710 updateVpnFiltering(newLp, oldLp, networkAgent); 9711 9712 updateIngressToVpnAddressFiltering(newLp, oldLp, networkAgent); 9713 9714 updateMtu(newLp, oldLp); 9715 // TODO - figure out what to do for clat 9716 // for (LinkProperties lp : newLp.getStackedLinks()) { 9717 // updateMtu(lp, null); 9718 // } 9719 if (isDefaultNetwork(networkAgent)) { 9720 mProxyTracker.updateDefaultNetworkProxyPortForPAC(newLp, null); 9721 updateTcpBufferSizes(newLp.getTcpBufferSizes()); 9722 } 9723 9724 updateRoutes(newLp, oldLp, netId); 9725 updateDnses(newLp, oldLp, netId); 9726 // Make sure LinkProperties represents the latest private DNS status. 9727 // This does not need to be done before updateDnses because the 9728 // LinkProperties are not the source of the private DNS configuration. 9729 // updateDnses will fetch the private DNS configuration from DnsManager. 9730 mDnsManager.updatePrivateDnsStatus(netId, newLp); 9731 9732 if (isDefaultNetwork(networkAgent)) { 9733 mProxyTracker.setDefaultProxy(newLp.getHttpProxy()); 9734 } else if (networkAgent.everConnected()) { 9735 updateProxy(newLp, oldLp); 9736 } 9737 9738 updateWakeOnLan(newLp); 9739 9740 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo. 9741 // It is not always contained in the LinkProperties sent from NetworkAgents, and if it 9742 // does, it needs to be merged here. 9743 newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData, 9744 networkAgent.capportApiData)); 9745 9746 // TODO - move this check to cover the whole function 9747 if (!Objects.equals(newLp, oldLp)) { 9748 synchronized (networkAgent) { 9749 networkAgent.linkProperties = newLp; 9750 } 9751 // Start or stop DNS64 detection and 464xlat according to network state. 9752 networkAgent.clatd.update(); 9753 // Notify NSS when relevant events happened. Currently, NSS only cares about 9754 // interface changed to update clat interfaces accounting. 9755 final boolean interfacesChanged = oldLp == null 9756 || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames()); 9757 if (interfacesChanged) { 9758 notifyIfacesChangedForNetworkStats(); 9759 } 9760 networkAgent.networkMonitor().notifyLinkPropertiesChanged( 9761 new LinkProperties(newLp, true /* parcelSensitiveFields */)); 9762 notifyNetworkCallbacks(networkAgent, CALLBACK_IP_CHANGED); 9763 } 9764 9765 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 9766 } 9767 9768 private void applyInitialLinkProperties(@NonNull NetworkAgentInfo nai) { 9769 updateLinkProperties(nai, new LinkProperties(nai.linkProperties), null); 9770 } 9771 9772 /** 9773 * @param naData captive portal data from NetworkAgent 9774 * @param apiData captive portal data from capport API 9775 */ 9776 @Nullable 9777 private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData, 9778 CaptivePortalData apiData) { 9779 if (naData == null || apiData == null) { 9780 return naData == null ? apiData : naData; 9781 } 9782 final CaptivePortalData.Builder captivePortalBuilder = 9783 new CaptivePortalData.Builder(naData); 9784 9785 if (apiData.isCaptive()) { 9786 captivePortalBuilder.setCaptive(true); 9787 } 9788 if (apiData.isSessionExtendable()) { 9789 captivePortalBuilder.setSessionExtendable(true); 9790 } 9791 if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) { 9792 // Expiry time, bytes remaining, refresh time all need to come from the same source, 9793 // otherwise data would be inconsistent. Prefer the capport API info if present, 9794 // as it can generally be refreshed more often. 9795 captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis()); 9796 captivePortalBuilder.setBytesRemaining(apiData.getByteLimit()); 9797 captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis()); 9798 } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) { 9799 // No source has time / bytes remaining information: surface the newest refresh time 9800 // for other fields 9801 captivePortalBuilder.setRefreshTime( 9802 Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis())); 9803 } 9804 9805 // Prioritize the user portal URL from the network agent if the source is authenticated. 9806 if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource() 9807 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 9808 captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(), 9809 apiData.getUserPortalUrlSource()); 9810 } 9811 // Prioritize the venue information URL from the network agent if the source is 9812 // authenticated. 9813 if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource() 9814 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 9815 captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(), 9816 apiData.getVenueInfoUrlSource()); 9817 } 9818 return captivePortalBuilder.build(); 9819 } 9820 9821 @VisibleForTesting 9822 static String makeNflogPrefix(String iface, long networkHandle) { 9823 // This needs to be kept in sync and backwards compatible with the decoding logic in 9824 // NetdEventListenerService, which is non-mainline code. 9825 return SdkLevel.isAtLeastU() ? (networkHandle + ":" + iface) : ("iface:" + iface); 9826 } 9827 9828 private static boolean isWakeupMarkingSupported(NetworkCapabilities capabilities) { 9829 if (capabilities.hasTransport(TRANSPORT_WIFI)) { 9830 return true; 9831 } 9832 if (SdkLevel.isAtLeastU() && capabilities.hasTransport(TRANSPORT_CELLULAR)) { 9833 return true; 9834 } 9835 return false; 9836 } 9837 9838 private void wakeupModifyInterface(String iface, NetworkAgentInfo nai, boolean add) { 9839 // Marks are only available on WiFi interfaces. Checking for 9840 // marks on unsupported interfaces is harmless. 9841 if (!isWakeupMarkingSupported(nai.networkCapabilities)) { 9842 return; 9843 } 9844 9845 // Mask/mark of zero will not detect anything interesting. 9846 // Don't install rules unless both values are nonzero. 9847 if (mWakeUpMark == 0 || mWakeUpMask == 0) { 9848 return; 9849 } 9850 9851 final String prefix = makeNflogPrefix(iface, nai.network.getNetworkHandle()); 9852 try { 9853 if (add) { 9854 mNetd.wakeupAddInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 9855 } else { 9856 mNetd.wakeupDelInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 9857 } 9858 } catch (Exception e) { 9859 loge("Exception modifying wakeup packet monitoring: " + e); 9860 } 9861 } 9862 9863 private void updateInterfaces(final @NonNull LinkProperties newLp, 9864 final @Nullable LinkProperties oldLp, final int netId, 9865 final @NonNull NetworkAgentInfo nai) { 9866 final CompareResult<String> interfaceDiff = new CompareResult<>( 9867 oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames()); 9868 if (!interfaceDiff.added.isEmpty()) { 9869 for (final String iface : interfaceDiff.added) { 9870 try { 9871 if (DBG) log("Adding iface " + iface + " to network " + netId); 9872 mRoutingCoordinatorService.addInterfaceToNetwork(netId, iface); 9873 wakeupModifyInterface(iface, nai, true); 9874 mDeps.reportNetworkInterfaceForTransports(mContext, iface, 9875 nai.networkCapabilities.getTransportTypes()); 9876 mInterfaceTracker.addInterface(iface); 9877 } catch (Exception e) { 9878 logw("Exception adding interface: " + e); 9879 } 9880 } 9881 } 9882 9883 // The local network addresses needs to be updated before interfaces are removed because 9884 // modifying bpf map local_net_access requires mapping interface name to index. 9885 updateLocalNetworkAddresses(newLp, oldLp); 9886 9887 for (final String iface : interfaceDiff.removed) { 9888 try { 9889 if (DBG) log("Removing iface " + iface + " from network " + netId); 9890 wakeupModifyInterface(iface, nai, false); 9891 mRoutingCoordinatorService.removeInterfaceFromNetwork(netId, iface); 9892 mInterfaceTracker.removeInterface(iface); 9893 } catch (Exception e) { 9894 loge("Exception removing interface: " + e); 9895 } 9896 } 9897 } 9898 9899 /** 9900 * Update Local Network Addresses to LocalNetAccess BPF map. 9901 * @param newLp new link properties 9902 * @param oldLp old link properties 9903 */ 9904 private void updateLocalNetworkAddresses(@Nullable final LinkProperties newLp, 9905 @NonNull final LinkProperties oldLp) { 9906 9907 // The maps are available only after 25Q2 release 9908 if (!BpfNetMaps.isAtLeast25Q2()) { 9909 return; 9910 } 9911 9912 final CompareResult<String> interfaceDiff = new CompareResult<>( 9913 oldLp != null ? oldLp.getAllInterfaceNames() : null, 9914 newLp != null ? newLp.getAllInterfaceNames() : null); 9915 9916 for (final String iface : interfaceDiff.added) { 9917 addLocalAddressesToBpfMap(iface, MULTICAST_AND_BROADCAST_PREFIXES, newLp); 9918 } 9919 for (final String iface : interfaceDiff.removed) { 9920 removeLocalAddressesFromBpfMap(iface, MULTICAST_AND_BROADCAST_PREFIXES, oldLp); 9921 } 9922 9923 // The both list contain current link properties + stacked links for new and old LP. 9924 final List<LinkProperties> newLinkProperties = new ArrayList<>(); 9925 final List<LinkProperties> oldLinkProperties = new ArrayList<>(); 9926 9927 if (newLp != null) { 9928 newLinkProperties.add(newLp); 9929 newLinkProperties.addAll(newLp.getStackedLinks()); 9930 } 9931 if (oldLp != null) { 9932 oldLinkProperties.add(oldLp); 9933 oldLinkProperties.addAll(oldLp.getStackedLinks()); 9934 } 9935 9936 // map contains interface name to list of local network prefixes added because of change 9937 // in link properties 9938 final Map<String, List<IpPrefix>> prefixesAddedForInterface = new ArrayMap<>(); 9939 9940 final CompareResult<LinkProperties> linkPropertiesDiff = new CompareResult<>( 9941 oldLinkProperties, newLinkProperties); 9942 9943 for (LinkProperties linkProperty : linkPropertiesDiff.added) { 9944 final List<IpPrefix> unicastLocalPrefixesToBeAdded = new ArrayList<>(); 9945 for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) { 9946 unicastLocalPrefixesToBeAdded.addAll( 9947 getLocalNetworkPrefixesForAddress(linkAddress)); 9948 } 9949 addLocalAddressesToBpfMap(linkProperty.getInterfaceName(), 9950 unicastLocalPrefixesToBeAdded, linkProperty); 9951 9952 // populating interface name -> ip prefixes which were added to local_net_access map. 9953 if (!prefixesAddedForInterface.containsKey(linkProperty.getInterfaceName())) { 9954 prefixesAddedForInterface.put(linkProperty.getInterfaceName(), new ArrayList<>()); 9955 } 9956 prefixesAddedForInterface.get(linkProperty.getInterfaceName()) 9957 .addAll(unicastLocalPrefixesToBeAdded); 9958 } 9959 9960 for (LinkProperties linkProperty : linkPropertiesDiff.removed) { 9961 final List<IpPrefix> unicastLocalPrefixesToBeRemoved = new ArrayList<>(); 9962 final List<IpPrefix> unicastLocalPrefixesAdded = prefixesAddedForInterface.getOrDefault( 9963 linkProperty.getInterfaceName(), Collections.emptyList()); 9964 9965 for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) { 9966 unicastLocalPrefixesToBeRemoved.addAll( 9967 getLocalNetworkPrefixesForAddress(linkAddress)); 9968 } 9969 9970 // This is to ensure if 10.0.10.0/24 was added and 10.0.11.0/24 was removed both will 9971 // still populate the same prefix of 10.0.0.0/8, which mean 10.0.0.0/8 should not be 9972 // removed due to removal of 10.0.11.0/24 9973 unicastLocalPrefixesToBeRemoved.removeAll(unicastLocalPrefixesAdded); 9974 9975 removeLocalAddressesFromBpfMap(linkProperty.getInterfaceName(), 9976 new ArrayList<>(unicastLocalPrefixesToBeRemoved), linkProperty); 9977 } 9978 } 9979 9980 /** 9981 * Filters IpPrefix that are local prefixes and LinkAddress is part of them. 9982 * @param linkAddress link address used for filtering 9983 * @return list of IpPrefix that are local addresses. 9984 */ 9985 private List<IpPrefix> getLocalNetworkPrefixesForAddress(LinkAddress linkAddress) { 9986 List<IpPrefix> localPrefixes = new ArrayList<>(); 9987 if (linkAddress.isIpv6()) { 9988 // For IPv6, if the prefix length is greater than zero then they are part of local 9989 // network 9990 if (linkAddress.getPrefixLength() != 0) { 9991 localPrefixes.add( 9992 new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength())); 9993 } 9994 } else { 9995 // For IPv4, if the linkAddress is part of IpPrefix adding prefix to result. 9996 for (IpPrefix ipv4LocalPrefix : IPV4_LOCAL_PREFIXES) { 9997 if (ipv4LocalPrefix.containsPrefix( 9998 new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength()))) { 9999 localPrefixes.add(ipv4LocalPrefix); 10000 } 10001 } 10002 } 10003 return localPrefixes; 10004 } 10005 10006 /** 10007 * Adds list of prefixes(addresses) to local network access map. 10008 * @param iface interface name 10009 * @param prefixes list of prefixes/addresses 10010 * @param lp LinkProperties 10011 */ 10012 private void addLocalAddressesToBpfMap(final String iface, final List<IpPrefix> prefixes, 10013 @Nullable final LinkProperties lp) { 10014 if (!BpfNetMaps.isAtLeast25Q2()) return; 10015 10016 for (IpPrefix prefix : prefixes) { 10017 // Add local dnses allow rule To BpfMap before adding the block rule for prefix 10018 addLocalDnsesToBpfMap(iface, prefix, lp); 10019 /* 10020 Prefix length is used by LPM trie map(local_net_access_map) for performing longest 10021 prefix matching, this length represents the maximum number of bits used for matching. 10022 The interface index should always be matched which is 32-bit integer. For IPv6, prefix 10023 length is calculated by adding the ip address prefix length along with interface index 10024 making it (32 + length). IPv4 addresses are stored as ipv4-mapped-ipv6 which implies 10025 first 96 bits are common for all ipv4 addresses. Hence, prefix length is calculated as 10026 32(interface index) + 96 (common for ipv4-mapped-ipv6) + length. 10027 */ 10028 final int prefixLengthConstant = (prefix.isIPv4() ? (32 + 96) : 32); 10029 mBpfNetMaps.addLocalNetAccess(prefixLengthConstant + prefix.getPrefixLength(), 10030 iface, prefix.getAddress(), 0, 0, false); 10031 10032 } 10033 10034 } 10035 10036 /** 10037 * Removes list of prefixes(addresses) from local network access map. 10038 * @param iface interface name 10039 * @param prefixes list of prefixes/addresses 10040 * @param lp LinkProperties 10041 */ 10042 private void removeLocalAddressesFromBpfMap(final String iface, final List<IpPrefix> prefixes, 10043 @Nullable final LinkProperties lp) { 10044 if (!BpfNetMaps.isAtLeast25Q2()) return; 10045 10046 for (IpPrefix prefix : prefixes) { 10047 // The reasoning for prefix length is explained in addLocalAddressesToBpfMap() 10048 final int prefixLengthConstant = (prefix.isIPv4() ? (32 + 96) : 32); 10049 mBpfNetMaps.removeLocalNetAccess(prefixLengthConstant 10050 + prefix.getPrefixLength(), iface, prefix.getAddress(), 0, 0); 10051 10052 // Also remove the allow rule for dnses included in the prefix after removing the block 10053 // rule for prefix. 10054 removeLocalDnsesFromBpfMap(iface, prefix, lp); 10055 } 10056 } 10057 10058 /** 10059 * Adds DNS servers to local network access map, if included in the interface prefix 10060 * @param iface interface name 10061 * @param prefix IpPrefix 10062 * @param lp LinkProperties 10063 */ 10064 private void addLocalDnsesToBpfMap(final String iface, IpPrefix prefix, 10065 @Nullable final LinkProperties lp) { 10066 if (!BpfNetMaps.isAtLeast25Q2() || lp == null) return; 10067 10068 for (InetAddress dnsServer : lp.getDnsServers()) { 10069 // Adds dns allow rule to LocalNetAccessMap for both TCP and UDP protocol at port 53, 10070 // if it is a local dns (ie. it falls in the local prefix range). 10071 if (prefix.contains(dnsServer)) { 10072 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10073 IPPROTO_UDP, 53, true); 10074 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10075 IPPROTO_TCP, 53, true); 10076 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10077 IPPROTO_TCP, 853, true); // DNS over TLS 10078 } 10079 } 10080 } 10081 10082 /** 10083 * Removes DNS servers from local network access map, if included in the interface prefix 10084 * @param iface interface name 10085 * @param prefix IpPrefix 10086 * @param lp LinkProperties 10087 */ 10088 private void removeLocalDnsesFromBpfMap(final String iface, IpPrefix prefix, 10089 @Nullable final LinkProperties lp) { 10090 if (!BpfNetMaps.isAtLeast25Q2() || lp == null) return; 10091 10092 for (InetAddress dnsServer : lp.getDnsServers()) { 10093 // Removes dns allow rule from LocalNetAccessMap for both TCP and UDP protocol 10094 // at port 53, if it is a local dns (ie. it falls in the prefix range). 10095 if (prefix.contains(dnsServer)) { 10096 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10097 IPPROTO_UDP, 53); 10098 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10099 IPPROTO_TCP, 53); 10100 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer, 10101 IPPROTO_TCP, 853); // DNS over TLS 10102 } 10103 } 10104 } 10105 10106 /** 10107 * Have netd update routes from oldLp to newLp. 10108 * @return true if routes changed between oldLp and newLp 10109 */ 10110 private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 10111 int netId) { 10112 // compare the route diff to determine which routes have been updated 10113 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff = 10114 new CompareOrUpdateResult<>( 10115 oldLp != null ? oldLp.getAllRoutes() : null, 10116 newLp.getAllRoutes(), 10117 (r) -> r.getRouteKey()); 10118 10119 // add routes before removing old in case it helps with continuous connectivity 10120 10121 // do this twice, adding non-next-hop routes first, then routes they are dependent on 10122 for (RouteInfo route : routeDiff.added) { 10123 if (route.hasGateway()) continue; 10124 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 10125 try { 10126 mRoutingCoordinatorService.addRoute(netId, route); 10127 } catch (Exception e) { 10128 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 10129 loge("Exception in addRoute for non-gateway: " + e); 10130 } 10131 } 10132 } 10133 for (RouteInfo route : routeDiff.added) { 10134 if (!route.hasGateway()) continue; 10135 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 10136 try { 10137 mRoutingCoordinatorService.addRoute(netId, route); 10138 } catch (Exception e) { 10139 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 10140 loge("Exception in addRoute for gateway: " + e); 10141 } 10142 } 10143 } 10144 10145 for (RouteInfo route : routeDiff.removed) { 10146 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); 10147 try { 10148 mRoutingCoordinatorService.removeRoute(netId, route); 10149 } catch (Exception e) { 10150 loge("Exception in removeRoute: " + e); 10151 } 10152 } 10153 10154 for (RouteInfo route : routeDiff.updated) { 10155 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId); 10156 try { 10157 mRoutingCoordinatorService.updateRoute(netId, route); 10158 } catch (Exception e) { 10159 loge("Exception in updateRoute: " + e); 10160 } 10161 } 10162 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty() 10163 || !routeDiff.updated.isEmpty(); 10164 } 10165 10166 private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 10167 int netId) { 10168 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 10169 return; // no updating necessary 10170 } 10171 10172 if (DBG) { 10173 final Collection<InetAddress> dnses = newLp.getDnsServers(); 10174 log("Setting DNS servers for network " + netId + " to " + dnses); 10175 } 10176 try { 10177 mDnsManager.noteDnsServersForNetwork(netId, newLp); 10178 mDnsManager.flushVmDnsCache(); 10179 } catch (Exception e) { 10180 loge("Exception in setDnsConfigurationForNetwork: " + e); 10181 } 10182 } 10183 10184 private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 10185 @NonNull NetworkAgentInfo nai) { 10186 final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp); 10187 final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp); 10188 final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface); 10189 final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface); 10190 10191 if (!wasFiltering && !needsFiltering) { 10192 // Nothing to do. 10193 return; 10194 } 10195 10196 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) { 10197 // Nothing changed. 10198 return; 10199 } 10200 10201 final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges(); 10202 if (ranges == null || ranges.isEmpty()) { 10203 return; 10204 } 10205 10206 final int vpnAppUid = nai.networkCapabilities.getOwnerUid(); 10207 // TODO: this create a window of opportunity for apps to receive traffic between the time 10208 // when the old rules are removed and the time when new rules are added. To fix this, 10209 // make eBPF support two allowlisted interfaces so here new rules can be added before the 10210 // old rules are being removed. 10211 if (wasFiltering) { 10212 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid); 10213 } 10214 if (needsFiltering) { 10215 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid); 10216 } 10217 } 10218 10219 /** 10220 * Returns ingress discard rules to drop packets to VPN addresses ingressing via non-VPN 10221 * interfaces. 10222 * Ingress discard rule is added to the address iff 10223 * 1. The address is not a link local address 10224 * 2. The address is used by a single interface of VPN whose VPN type is not LEGACY, OEM or 10225 * OEM_LEGACY and the address is not used by any other interfaces even non-VPN ones 10226 * Ingress discard rule is not be added to TYPE_VPN_LEGACY or TYPE_VPN_OEM VPN since these VPNs 10227 * might need to receive packet to VPN address via non-VPN interface. 10228 * This method can be called during network disconnects, when nai has already been removed from 10229 * mNetworkAgentInfos. 10230 * 10231 * @param nai This method generates rules assuming lp of this nai is the lp at the second 10232 * argument. 10233 * @param lp This method generates rules assuming lp of nai at the first argument is this lp. 10234 * Caller passes old lp to generate old rules and new lp to generate new rules. 10235 * @return ingress discard rules. Set of pairs of addresses and interface names 10236 */ 10237 private Set<Pair<InetAddress, String>> generateIngressDiscardRules( 10238 @NonNull final NetworkAgentInfo nai, @Nullable final LinkProperties lp) { 10239 Set<NetworkAgentInfo> nais = new ArraySet<>(mNetworkAgentInfos); 10240 nais.add(nai); 10241 // Determine how many networks each IP address is currently configured on. 10242 // Ingress rules are added only for IP addresses that are configured on single interface. 10243 final Map<InetAddress, Integer> addressOwnerCounts = new ArrayMap<>(); 10244 for (final NetworkAgentInfo agent : nais) { 10245 if (agent.isDestroyed()) { 10246 continue; 10247 } 10248 final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties; 10249 if (agentLp == null) { 10250 continue; 10251 } 10252 for (final InetAddress addr: agentLp.getAllAddresses()) { 10253 addressOwnerCounts.put(addr, addressOwnerCounts.getOrDefault(addr, 0) + 1); 10254 } 10255 } 10256 10257 // Iterates all networks instead of only generating rule for nai that was passed in since 10258 // lp of the nai change could cause/resolve address collision and result in affecting rule 10259 // for different network. 10260 final Set<Pair<InetAddress, String>> ingressDiscardRules = new ArraySet<>(); 10261 for (final NetworkAgentInfo agent : nais) { 10262 final int vpnType = getVpnType(agent); 10263 if (!agent.isVPN() || agent.isDestroyed() || !vpnSupportsInterfaceFiltering(agent)) { 10264 continue; 10265 } 10266 final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties; 10267 if (agentLp == null || agentLp.getInterfaceName() == null) { 10268 continue; 10269 } 10270 10271 for (final InetAddress addr: agentLp.getAllAddresses()) { 10272 if (addressOwnerCounts.get(addr) == 1 && !addr.isLinkLocalAddress()) { 10273 ingressDiscardRules.add(new Pair<>(addr, agentLp.getInterfaceName())); 10274 } 10275 } 10276 } 10277 return ingressDiscardRules; 10278 } 10279 10280 private void updateIngressToVpnAddressFiltering(@Nullable LinkProperties newLp, 10281 @Nullable LinkProperties oldLp, @NonNull NetworkAgentInfo nai) { 10282 // Having isAtleastT to avoid NewApi linter error (b/303382209) 10283 if (!mIngressToVpnAddressFiltering || !mDeps.isAtLeastT()) { 10284 return; 10285 } 10286 final CompareOrUpdateResult<InetAddress, Pair<InetAddress, String>> ruleDiff = 10287 new CompareOrUpdateResult<>( 10288 generateIngressDiscardRules(nai, oldLp), 10289 generateIngressDiscardRules(nai, newLp), 10290 (rule) -> rule.first); 10291 for (Pair<InetAddress, String> rule: ruleDiff.removed) { 10292 mBpfNetMaps.removeIngressDiscardRule(rule.first); 10293 } 10294 for (Pair<InetAddress, String> rule: ruleDiff.added) { 10295 mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second); 10296 } 10297 // setIngressDiscardRule overrides the existing rule 10298 for (Pair<InetAddress, String> rule: ruleDiff.updated) { 10299 mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second); 10300 } 10301 } 10302 10303 private void updateWakeOnLan(@NonNull LinkProperties lp) { 10304 if (mWolSupportedInterfaces == null) { 10305 mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray( 10306 R.array.config_wakeonlan_supported_interfaces)); 10307 } 10308 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName())); 10309 } 10310 10311 private int getNetworkPermission(NetworkCapabilities nc) { 10312 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 10313 return INetd.PERMISSION_SYSTEM; 10314 } 10315 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 10316 return INetd.PERMISSION_NETWORK; 10317 } 10318 return INetd.PERMISSION_NONE; 10319 } 10320 10321 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai, 10322 @NonNull final NetworkCapabilities newNc) { 10323 final int oldPermission = getNetworkPermission(nai.networkCapabilities); 10324 final int newPermission = getNetworkPermission(newNc); 10325 if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) { 10326 try { 10327 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission); 10328 } catch (RemoteException | ServiceSpecificException e) { 10329 loge("Exception in networkSetPermissionForNetwork: " + e); 10330 } 10331 } 10332 } 10333 10334 /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */ 10335 @VisibleForTesting 10336 void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, 10337 @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { 10338 underlyingNetworks = underlyingNetworksOrDefault( 10339 agentCaps.getOwnerUid(), underlyingNetworks); 10340 long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes()); 10341 int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 10342 int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 10343 // metered if any underlying is metered, or originally declared metered by the agent. 10344 boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 10345 boolean roaming = false; // roaming if any underlying is roaming 10346 boolean congested = false; // congested if any underlying is congested 10347 boolean suspended = true; // suspended if all underlying are suspended 10348 10349 boolean hadUnderlyingNetworks = false; 10350 ArrayList<Network> newUnderlyingNetworks = null; 10351 if (null != underlyingNetworks) { 10352 newUnderlyingNetworks = new ArrayList<>(); 10353 for (Network underlyingNetwork : underlyingNetworks) { 10354 final NetworkAgentInfo underlying = 10355 getNetworkAgentInfoForNetwork(underlyingNetwork); 10356 if (underlying == null) continue; 10357 10358 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; 10359 hadUnderlyingNetworks = true; 10360 for (int underlyingType : underlyingCaps.getTransportTypes()) { 10361 transportTypes |= 1L << underlyingType; 10362 } 10363 10364 // Merge capabilities of this underlying network. For bandwidth, assume the 10365 // worst case. 10366 downKbps = NetworkCapabilities.minBandwidth(downKbps, 10367 underlyingCaps.getLinkDownstreamBandwidthKbps()); 10368 upKbps = NetworkCapabilities.minBandwidth(upKbps, 10369 underlyingCaps.getLinkUpstreamBandwidthKbps()); 10370 // If this underlying network is metered, the VPN is metered (it may cost money 10371 // to send packets on this network). 10372 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 10373 // If this underlying network is roaming, the VPN is roaming (the billing structure 10374 // is different than the usual, local one). 10375 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); 10376 // If this underlying network is congested, the VPN is congested (the current 10377 // condition of the network affects the performance of this network). 10378 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 10379 // If this network is not suspended, the VPN is not suspended (the VPN 10380 // is able to transfer some data). 10381 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 10382 newUnderlyingNetworks.add(underlyingNetwork); 10383 } 10384 } 10385 if (!hadUnderlyingNetworks) { 10386 // No idea what the underlying networks are; assume reasonable defaults 10387 metered = true; 10388 roaming = false; 10389 congested = false; 10390 suspended = false; 10391 } 10392 10393 newNc.setTransportTypes(BitUtils.unpackBits(transportTypes)); 10394 newNc.setLinkDownstreamBandwidthKbps(downKbps); 10395 newNc.setLinkUpstreamBandwidthKbps(upKbps); 10396 newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered); 10397 newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); 10398 newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); 10399 newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); 10400 newNc.setUnderlyingNetworks(newUnderlyingNetworks); 10401 } 10402 10403 /** 10404 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 10405 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 10406 * and foreground status). 10407 */ 10408 @NonNull 10409 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 10410 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 10411 // Don't complain for VPNs since they're not driven by requests and there is no risk of 10412 // causing a connect/teardown loop. 10413 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to 10414 // avoid connect/teardown loops. 10415 if (nai.everConnected() 10416 && !nai.isVPN() 10417 && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 10418 // TODO: consider not complaining when a network agent degrades its capabilities if this 10419 // does not cause any request (that is not a listen) currently matching that agent to 10420 // stop being matched by the updated agent. 10421 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 10422 if (!TextUtils.isEmpty(diff)) { 10423 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 10424 } 10425 } 10426 10427 // Don't modify caller's NetworkCapabilities. 10428 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 10429 if (nai.isValidated()) { 10430 newNc.addCapability(NET_CAPABILITY_VALIDATED); 10431 } else { 10432 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 10433 } 10434 if (nai.captivePortalDetected()) { 10435 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 10436 } else { 10437 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 10438 } 10439 if (nai.isBackgroundNetwork()) { 10440 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 10441 } else { 10442 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 10443 } 10444 if (nai.partialConnectivity()) { 10445 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 10446 } else { 10447 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 10448 } 10449 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken()); 10450 10451 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING 10452 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) { 10453 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 10454 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING); 10455 } 10456 10457 if (nai.propagateUnderlyingCapabilities()) { 10458 applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, 10459 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator), 10460 newNc); 10461 } 10462 10463 return newNc; 10464 } 10465 10466 private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, 10467 NetworkCapabilities prevNc, NetworkCapabilities newNc) { 10468 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 10469 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 10470 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 10471 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 10472 if (prevSuspended != suspended) { 10473 // TODO (b/73132094) : remove this call once the few users of onSuspended and 10474 // onResumed have been removed. 10475 notifyNetworkCallbacks(nai, suspended ? CALLBACK_SUSPENDED : CALLBACK_RESUMED); 10476 } 10477 if (prevSuspended != suspended || prevRoaming != roaming) { 10478 // updateNetworkInfo will mix in the suspended info from the capabilities and 10479 // take appropriate action for the network having possibly changed state. 10480 updateNetworkInfo(nai, nai.networkInfo); 10481 } 10482 } 10483 10484 private void handleUidCarrierPrivilegesLost(int uid, int subId) { 10485 if (!mRequestRestrictedWifiEnabled) { 10486 return; 10487 } 10488 ensureRunningOnConnectivityServiceThread(); 10489 // A NetworkRequest needs to be revoked when all the conditions are met 10490 // 1. It requests restricted network 10491 // 2. The requestor uid matches the uid with the callback 10492 // 3. The app doesn't have Carrier Privileges 10493 // 4. The app doesn't have permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS 10494 for (final NetworkRequest nr : mNetworkRequests.keySet()) { 10495 if (nr.isRequest() 10496 && !nr.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 10497 && nr.getRequestorUid() == uid 10498 && getSubscriptionIdFromNetworkCaps(nr.networkCapabilities) == subId 10499 && !hasConnectivityRestrictedNetworksPermission(uid, true)) { 10500 declareNetworkRequestUnfulfillable(nr); 10501 } 10502 } 10503 10504 // A NetworkAgent's allowedUids may need to be updated if the app has lost 10505 // carrier config 10506 forEachNetworkAgentInfo(nai -> { 10507 if (nai.networkCapabilities.getAllowedUidsNoCopy().contains(uid) 10508 && getSubscriptionIdFromNetworkCaps(nai.networkCapabilities) == subId) { 10509 final NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities); 10510 NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent( 10511 nc, 10512 uid, 10513 false /* hasAutomotiveFeature (irrelevant) */, 10514 mDeps, 10515 mCarrierPrivilegeAuthenticator); 10516 updateCapabilities(nai.getScore(), nai, nc); 10517 } 10518 }); 10519 } 10520 10521 /** 10522 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 10523 * 10524 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 10525 * capabilities we manage and store in {@code nai}, such as validated status and captive 10526 * portal status) 10527 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 10528 * potentially triggers rematches. 10529 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 10530 * change.) 10531 * 10532 * @param oldScore score of the network before any of the changes that prompted us 10533 * to call this function. 10534 * @param nai the network having its capabilities updated. 10535 * @param nc the new network capabilities. 10536 */ 10537 private void updateCapabilities(final FullScore oldScore, @NonNull final NetworkAgentInfo nai, 10538 @NonNull final NetworkCapabilities nc) { 10539 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 10540 if (Objects.equals(nai.networkCapabilities, newNc)) return; 10541 final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities); 10542 if (null != differences) { 10543 Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences); 10544 } 10545 updateNetworkPermissions(nai, newNc); 10546 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc); 10547 10548 updateVpnUids(nai, prevNc, newNc); 10549 updateAllowedUids(nai, prevNc, newNc); 10550 nai.updateScoreForNetworkAgentUpdate(); 10551 10552 if (nai.getScore().equals(oldScore) && newNc.equalRequestableCapabilities(prevNc)) { 10553 // If the requestable capabilities haven't changed, and the score hasn't changed, then 10554 // the change we're processing can't affect any requests, it can only affect the listens 10555 // on this network. We might have been called by rematchNetworkAndRequests when a 10556 // network changed foreground state. 10557 processListenRequests(nai); 10558 } else { 10559 // If the requestable capabilities have changed or the score changed, we can't have been 10560 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 10561 rematchAllNetworksAndRequests(); 10562 notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED); 10563 } 10564 updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc); 10565 10566 final boolean oldMetered = prevNc.isMetered(); 10567 final boolean newMetered = newNc.isMetered(); 10568 final boolean meteredChanged = oldMetered != newMetered; 10569 10570 if (meteredChanged) { 10571 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, 10572 mVpnBlockedUidRanges, mVpnBlockedUidRanges); 10573 } 10574 10575 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) 10576 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 10577 10578 // Report changes that are interesting for network statistics tracking. 10579 if (meteredChanged || roamingChanged) { 10580 notifyIfacesChangedForNetworkStats(); 10581 } 10582 10583 // This network might have been underlying another network. Propagate its capabilities. 10584 propagateUnderlyingNetworkCapabilities(nai.network); 10585 10586 if (meteredChanged || !newNc.equalsTransportTypes(prevNc)) { 10587 mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), newNc); 10588 } 10589 10590 maybeSendProxyBroadcast(nai, prevNc, newNc); 10591 } 10592 10593 /** Convenience method to update the capabilities for a given network. */ 10594 private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) { 10595 updateCapabilities(nai.getScore(), nai, nai.networkCapabilities); 10596 } 10597 10598 private void maybeApplyMulticastRoutingConfig(@NonNull final NetworkAgentInfo nai, 10599 final LocalNetworkConfig oldConfig, 10600 final LocalNetworkConfig newConfig) { 10601 final MulticastRoutingConfig oldUpstreamConfig = 10602 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 10603 oldConfig.getUpstreamMulticastRoutingConfig(); 10604 final MulticastRoutingConfig oldDownstreamConfig = 10605 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 10606 oldConfig.getDownstreamMulticastRoutingConfig(); 10607 final MulticastRoutingConfig newUpstreamConfig = 10608 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 10609 newConfig.getUpstreamMulticastRoutingConfig(); 10610 final MulticastRoutingConfig newDownstreamConfig = 10611 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE : 10612 newConfig.getDownstreamMulticastRoutingConfig(); 10613 10614 if (oldUpstreamConfig.equals(newUpstreamConfig) && 10615 oldDownstreamConfig.equals(newDownstreamConfig)) { 10616 return; 10617 } 10618 10619 final String downstreamNetworkName = nai.linkProperties.getInterfaceName(); 10620 final LocalNetworkInfo lni = localNetworkInfoForNai(nai); 10621 final Network upstreamNetwork = lni.getUpstreamNetwork(); 10622 10623 if (upstreamNetwork != null) { 10624 final String upstreamNetworkName = 10625 getLinkProperties(upstreamNetwork).getInterfaceName(); 10626 applyMulticastRoutingConfig(downstreamNetworkName, upstreamNetworkName, newConfig); 10627 } 10628 } 10629 10630 private void applyMulticastRoutingConfig(@NonNull String localNetworkInterfaceName, 10631 @NonNull String upstreamNetworkInterfaceName, 10632 @NonNull final LocalNetworkConfig config) { 10633 if (mMulticastRoutingCoordinatorService == null) { 10634 if (config.getDownstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE || 10635 config.getUpstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE) { 10636 loge("Multicast routing is not supported, failed to configure " + config 10637 + " for " + localNetworkInterfaceName + " to " 10638 + upstreamNetworkInterfaceName); 10639 } 10640 return; 10641 } 10642 10643 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName, 10644 upstreamNetworkInterfaceName, config.getUpstreamMulticastRoutingConfig()); 10645 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig 10646 (upstreamNetworkInterfaceName, localNetworkInterfaceName, 10647 config.getDownstreamMulticastRoutingConfig()); 10648 } 10649 10650 private void disableMulticastRouting(@NonNull String localNetworkInterfaceName, 10651 @NonNull String upstreamNetworkInterfaceName) { 10652 if (mMulticastRoutingCoordinatorService == null) { 10653 return; 10654 } 10655 10656 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName, 10657 upstreamNetworkInterfaceName, MulticastRoutingConfig.CONFIG_FORWARD_NONE); 10658 mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig 10659 (upstreamNetworkInterfaceName, localNetworkInterfaceName, 10660 MulticastRoutingConfig.CONFIG_FORWARD_NONE); 10661 } 10662 10663 // oldConfig is null iff this is the original registration of the local network config 10664 private void handleUpdateLocalNetworkConfig(@NonNull final NetworkAgentInfo nai, 10665 @Nullable final LocalNetworkConfig oldConfig, 10666 @NonNull final LocalNetworkConfig newConfig) { 10667 if (!nai.isLocalNetwork()) { 10668 Log.wtf(TAG, "Ignoring update of a local network info on non-local network " + nai); 10669 return; 10670 } 10671 10672 if (VDBG) { 10673 Log.v(TAG, "Update local network config " + nai.network.netId + " : " + newConfig); 10674 } 10675 final LocalNetworkConfig.Builder configBuilder = new LocalNetworkConfig.Builder(); 10676 configBuilder.setUpstreamMulticastRoutingConfig( 10677 newConfig.getUpstreamMulticastRoutingConfig()); 10678 configBuilder.setDownstreamMulticastRoutingConfig( 10679 newConfig.getDownstreamMulticastRoutingConfig()); 10680 10681 final NetworkRequest oldRequest = 10682 (null == oldConfig) ? null : oldConfig.getUpstreamSelector(); 10683 final NetworkCapabilities oldCaps = 10684 (null == oldRequest) ? null : oldRequest.networkCapabilities; 10685 final NetworkRequestInfo oldNri = 10686 null == oldRequest ? null : mNetworkRequests.get(oldRequest); 10687 final NetworkAgentInfo oldSatisfier = 10688 null == oldNri ? null : oldNri.getSatisfier(); 10689 final NetworkRequest newRequest = newConfig.getUpstreamSelector(); 10690 final NetworkCapabilities newCaps = 10691 (null == newRequest) ? null : newRequest.networkCapabilities; 10692 final boolean requestUpdated = !Objects.equals(newCaps, oldCaps); 10693 if (null != oldRequest && requestUpdated) { 10694 handleRemoveNetworkRequest(mNetworkRequests.get(oldRequest)); 10695 if (null == newRequest && null != oldSatisfier) { 10696 // If there is an old satisfier, but no new request, then remove the old upstream. 10697 removeLocalNetworkUpstream(nai, oldSatisfier); 10698 nai.localNetworkConfig = configBuilder.build(); 10699 // When there is a new request, the rematch sees the new request and sends the 10700 // LOCAL_NETWORK_INFO_CHANGED callbacks accordingly. 10701 // But here there is no new request, so the rematch won't see anything. Send 10702 // callbacks to apps now to tell them about the loss of upstream. 10703 notifyNetworkCallbacks(nai, 10704 CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 10705 return; 10706 } 10707 } 10708 if (null != newRequest && requestUpdated) { 10709 // File the new request if : 10710 // - it has changed (requestUpdated), or 10711 // - it's the first time this local info (null == oldConfig) 10712 // is updated and the request has not been filed yet. 10713 // Requests for local info are always LISTEN_FOR_BEST, because they have at most one 10714 // upstream (the best) but never request it to be brought up. 10715 final NetworkRequest nr = new NetworkRequest(newCaps, ConnectivityManager.TYPE_NONE, 10716 nextNetworkRequestId(), LISTEN_FOR_BEST); 10717 configBuilder.setUpstreamSelector(nr); 10718 final NetworkRequestInfo nri = new NetworkRequestInfo( 10719 nai.creatorUid, nr, null /* messenger */, null /* binder */, 10720 0 /* callbackFlags */, null /* attributionTag */, 10721 DECLARED_METHODS_NONE); 10722 if (null != oldSatisfier) { 10723 // Set the old satisfier in the new NRI so that the rematch will see any changes 10724 nri.setSatisfier(oldSatisfier, nr); 10725 } 10726 nai.localNetworkConfig = configBuilder.build(); 10727 // handleRegisterNetworkRequest causes a rematch. The rematch must happen after 10728 // nai.localNetworkConfig is set, since it will base its callbacks on the old 10729 // satisfier and the new request. 10730 handleRegisterNetworkRequest(nri); 10731 } else { 10732 configBuilder.setUpstreamSelector(oldRequest); 10733 nai.localNetworkConfig = configBuilder.build(); 10734 } 10735 maybeApplyMulticastRoutingConfig(nai, oldConfig, newConfig); 10736 } 10737 10738 /** 10739 * Returns the interface which requires VPN isolation (ingress interface filtering). 10740 * 10741 * Ingress interface filtering enforces that all apps under the given network can only receive 10742 * packets from the network's interface (and loopback). This is important for VPNs because 10743 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any 10744 * non-VPN interfaces. 10745 * 10746 * As a result, this method should return Non-null interface iff 10747 * 1. the network is an app VPN (not legacy VPN) 10748 * 2. the VPN does not allow bypass 10749 * 3. the VPN is fully-routed 10750 * 4. the VPN interface is non-null 10751 * 10752 * @see INetd#firewallAddUidInterfaceRules 10753 * @see INetd#firewallRemoveUidInterfaceRules 10754 */ 10755 @Nullable 10756 private String getVpnIsolationInterface(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, 10757 LinkProperties lp) { 10758 if (nc == null || lp == null) return null; 10759 if (nai.isVPN() 10760 && !nai.networkAgentConfig.allowBypass 10761 && nc.getOwnerUid() != Process.SYSTEM_UID 10762 && lp.getInterfaceName() != null 10763 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute()) 10764 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()) 10765 && !lp.hasExcludeRoute()) { 10766 return lp.getInterfaceName(); 10767 } 10768 return null; 10769 } 10770 10771 /** 10772 * Returns whether we need to set interface filtering rule or not 10773 */ 10774 private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp, 10775 String isolationIface) { 10776 // Allow rules are always needed if VPN isolation is enabled. 10777 if (isolationIface != null) return true; 10778 10779 // On T and above, allow rules are needed for all VPNs. Allow rule with null iface is a 10780 // wildcard to allow apps to receive packets on all interfaces. This is required to accept 10781 // incoming traffic in Lockdown mode by overriding the Lockdown blocking rule. 10782 return mDeps.isAtLeastT() && nai.isVPN() && lp != null && lp.getInterfaceName() != null; 10783 } 10784 10785 private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 10786 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; 10787 int index = 0; 10788 for (UidRange range : ranges) { 10789 stableRanges[index] = new UidRangeParcel(range.start, range.stop); 10790 index++; 10791 } 10792 return stableRanges; 10793 } 10794 10795 private static UidRangeParcel[] intsToUidRangeStableParcels( 10796 final @NonNull ArraySet<Integer> uids) { 10797 final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()]; 10798 int index = 0; 10799 for (int uid : uids) { 10800 stableRanges[index] = new UidRangeParcel(uid, uid); 10801 index++; 10802 } 10803 return stableRanges; 10804 } 10805 10806 private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) { 10807 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 10808 for (int i = 0; i < ranges.length; i++) { 10809 stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop); 10810 } 10811 return stableRanges; 10812 } 10813 10814 private void maybeCloseSockets(NetworkAgentInfo nai, Set<UidRange> ranges, int[] exemptUids) { 10815 if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) { 10816 try { 10817 if (mDeps.isAtLeastU()) { 10818 final Set<Integer> exemptUidSet = new ArraySet<>(); 10819 for (final int uid: exemptUids) { 10820 exemptUidSet.add(uid); 10821 } 10822 mDeps.destroyLiveTcpSockets(UidRange.toIntRanges(ranges), exemptUidSet); 10823 } else { 10824 mNetd.socketDestroy(toUidRangeStableParcels(ranges), exemptUids); 10825 } 10826 } catch (Exception e) { 10827 loge("Exception in socket destroy: ", e); 10828 } 10829 } 10830 } 10831 10832 private void modifyNetworkUidRanges(boolean add, NetworkAgentInfo nai, UidRangeParcel[] ranges, 10833 int preference) throws RemoteException { 10834 // UID ranges can be added or removed to a network that has already been destroyed (e.g., if 10835 // the network disconnects, or a a multilayer request is filed after 10836 // unregisterAfterReplacement is called). 10837 if (nai.isDestroyed()) { 10838 return; 10839 } 10840 final NativeUidRangeConfig config = new NativeUidRangeConfig(nai.network.netId, 10841 ranges, preference); 10842 if (add) { 10843 mNetd.networkAddUidRangesParcel(config); 10844 } else { 10845 mNetd.networkRemoveUidRangesParcel(config); 10846 } 10847 } 10848 10849 private void modifyNetworkUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges, 10850 int preference) throws RemoteException { 10851 modifyNetworkUidRanges(add, nai, toUidRangeStableParcels(uidRanges), preference); 10852 } 10853 10854 private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) { 10855 int[] exemptUids = new int[2]; 10856 // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used 10857 // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when 10858 // starting a legacy VPN, and remove VPN_UID here. (b/176542831) 10859 exemptUids[0] = VPN_UID; 10860 exemptUids[1] = nai.networkCapabilities.getOwnerUid(); 10861 10862 // Close sockets before modifying uid ranges so that RST packets can reach to the server. 10863 maybeCloseSockets(nai, uidRanges, exemptUids); 10864 try { 10865 modifyNetworkUidRanges(add, nai, uidRanges, PREFERENCE_ORDER_VPN); 10866 } catch (Exception e) { 10867 loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges + 10868 " on netId " + nai.network.netId + ". " + e); 10869 } 10870 // Close sockets that established connection while requesting netd. 10871 maybeCloseSockets(nai, uidRanges, exemptUids); 10872 } 10873 10874 private boolean isProxySetOnAnyDefaultNetwork() { 10875 ensureRunningOnConnectivityServiceThread(); 10876 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 10877 final NetworkAgentInfo nai = nri.getSatisfier(); 10878 if (nai != null && nai.linkProperties.getHttpProxy() != null) { 10879 return true; 10880 } 10881 } 10882 return false; 10883 } 10884 10885 private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, 10886 NetworkCapabilities newNc) { 10887 // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that 10888 // the proxy might be changed since the default network satisfied by the apps might also 10889 // changed. 10890 // TODO: Try to track the default network that apps use and only send a proxy broadcast when 10891 // that happens to prevent false alarms. 10892 final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges(); 10893 final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges(); 10894 if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids) 10895 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) { 10896 mProxyTracker.sendProxyBroadcast(); 10897 } 10898 } 10899 10900 private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc, 10901 @Nullable NetworkCapabilities newNc) { 10902 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges(); 10903 Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges(); 10904 if (null == prevRanges) prevRanges = new ArraySet<>(); 10905 if (null == newRanges) newRanges = new ArraySet<>(); 10906 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 10907 10908 prevRanges.removeAll(newRanges); 10909 newRanges.removeAll(prevRangesCopy); 10910 10911 try { 10912 // When updating the VPN uid routing rules, add the new range first then remove the old 10913 // range. If old range were removed first, there would be a window between the old 10914 // range being removed and the new range being added, during which UIDs contained 10915 // in both ranges are not subject to any VPN routing rules. Adding new range before 10916 // removing old range works because, unlike the filtering rules below, it's possible to 10917 // add duplicate UID routing rules. 10918 // TODO: calculate the intersection of add & remove. Imagining that we are trying to 10919 // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is: 10920 // [1-5] & [1-2],[4-5] == [3] 10921 // Then we can do: 10922 // maybeCloseSockets([3]) 10923 // mNetd.networkAddUidRanges([1-2],[4-5]) 10924 // mNetd.networkRemoveUidRanges([1-5]) 10925 // maybeCloseSockets([3]) 10926 // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the 10927 // number of binder calls from 6 to 4. 10928 if (!newRanges.isEmpty()) { 10929 updateVpnUidRanges(true, nai, newRanges); 10930 } 10931 if (!prevRanges.isEmpty()) { 10932 updateVpnUidRanges(false, nai, prevRanges); 10933 } 10934 final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties); 10935 final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties); 10936 final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface); 10937 final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface); 10938 // For VPN uid interface filtering, old ranges need to be removed before new ranges can 10939 // be added, due to the range being expanded and stored as individual UIDs. For example 10940 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means 10941 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges 10942 // were added first and then newRanges got removed later, there would be only one uid 10943 // 10013 left. A consequence of removing old ranges before adding new ranges is that 10944 // there is now a window of opportunity when the UIDs are not subject to any filtering. 10945 // Note that this is in contrast with the (more robust) update of VPN routing rules 10946 // above, where the addition of new ranges happens before the removal of old ranges. 10947 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range 10948 // to be removed will never overlap with the new range to be added. 10949 if (wasFiltering && !prevRanges.isEmpty()) { 10950 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges, 10951 prevNc.getOwnerUid()); 10952 } 10953 if (shouldFilter && !newRanges.isEmpty()) { 10954 mPermissionMonitor.onVpnUidRangesAdded(newIface, newRanges, newNc.getOwnerUid()); 10955 } 10956 } catch (Exception e) { 10957 // Never crash! 10958 loge("Exception in updateVpnUids: ", e); 10959 } 10960 } 10961 10962 private void updateAllowedUids(@NonNull NetworkAgentInfo nai, 10963 @Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) { 10964 // In almost all cases both NC code for empty access UIDs. return as fast as possible. 10965 final boolean prevEmpty = null == prevNc || prevNc.getAllowedUidsNoCopy().isEmpty(); 10966 final boolean newEmpty = null == newNc || newNc.getAllowedUidsNoCopy().isEmpty(); 10967 if (prevEmpty && newEmpty) return; 10968 10969 final ArraySet<Integer> prevUids = 10970 null == prevNc ? new ArraySet<>() : prevNc.getAllowedUidsNoCopy(); 10971 final ArraySet<Integer> newUids = 10972 null == newNc ? new ArraySet<>() : newNc.getAllowedUidsNoCopy(); 10973 10974 if (prevUids.equals(newUids)) return; 10975 10976 // This implementation is very simple and vastly faster for sets of Integers than 10977 // CompareOrUpdateResult, which is tuned for sets that need to be compared based on 10978 // a key computed from the value and has storage for that. 10979 final ArraySet<Integer> toRemove = new ArraySet<>(prevUids); 10980 final ArraySet<Integer> toAdd = new ArraySet<>(newUids); 10981 toRemove.removeAll(newUids); 10982 toAdd.removeAll(prevUids); 10983 try { 10984 if (!toAdd.isEmpty()) { 10985 modifyNetworkUidRanges(true /* add */, nai, intsToUidRangeStableParcels(toAdd), 10986 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT); 10987 } 10988 if (!toRemove.isEmpty()) { 10989 modifyNetworkUidRanges(false /* add */, nai, intsToUidRangeStableParcels(toRemove), 10990 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT); 10991 } 10992 } catch (ServiceSpecificException e) { 10993 // Has the interface disappeared since the network was built ? 10994 Log.i(TAG, "Can't set access UIDs for network " + nai.network, e); 10995 } catch (RemoteException e) { 10996 // Netd died. This usually causes a runtime restart anyway. 10997 } 10998 } 10999 11000 public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai, 11001 @NonNull LinkProperties newLp) { 11002 ensureRunningOnConnectivityServiceThread(); 11003 11004 if (!mNetworkAgentInfos.contains(nai)) { 11005 // Ignore updates for disconnected networks 11006 return; 11007 } 11008 if (VDBG || DDBG) { 11009 log("Update of LinkProperties for " + nai.toShortString() 11010 + "; created=" + nai.getCreatedTime() 11011 + "; firstConnected=" + nai.getConnectedTime()); 11012 } 11013 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not 11014 // modify its oldLp parameter. 11015 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties)); 11016 } 11017 11018 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 11019 int notificationType) { 11020 if (notificationType == CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 11021 Intent intent = new Intent(); 11022 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 11023 // If apps could file multi-layer requests with PendingIntents, they'd need to know 11024 // which of the layer is satisfied alongside with some ID for the request. Hence, if 11025 // such an API is ever implemented, there is no doubt the right request to send in 11026 // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would 11027 // need to be sent as a separate extra. 11028 final NetworkRequest req = nri.isMultilayerRequest() 11029 ? nri.getActiveRequest() 11030 // Non-multilayer listen requests do not have an active request 11031 : nri.mRequests.get(0); 11032 if (req == null) { 11033 Log.wtf(TAG, "No request in NRI " + nri); 11034 } 11035 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req); 11036 nri.mPendingIntentSent = true; 11037 sendIntent(nri.mPendingIntent, intent); 11038 } 11039 // else not handled 11040 } 11041 11042 /** 11043 * A small class to manage releasing a lock exactly once even if releaseLock is called 11044 * multiple times. See b/390043283 11045 * PendingIntent#send throws CanceledException in various cases. In some of them it will 11046 * still call onSendFinished, in others it won't and the client can't know. This class 11047 * keeps a ref to the wakelock that it releases exactly once, thanks to Atomics semantics. 11048 */ 11049 private class WakeLockOnFinishedReceiver implements PendingIntent.OnFinished { 11050 private final AtomicReference<PowerManager.WakeLock> mLock; 11051 WakeLockOnFinishedReceiver(@NonNull final PowerManager.WakeLock lock) { 11052 mLock = new AtomicReference<>(lock); 11053 lock.acquire(); 11054 } 11055 11056 public void releaseLock() { 11057 final PowerManager.WakeLock lock = mLock.getAndSet(null); 11058 if (null != lock) lock.release(); 11059 } 11060 11061 @Override 11062 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 11063 String resultData, Bundle resultExtras) { 11064 if (DBG) log("Finished sending " + pendingIntent); 11065 releaseLock(); 11066 releasePendingNetworkRequestWithDelay(pendingIntent); 11067 } 11068 } 11069 11070 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 11071 @SuppressLint("NewApi") 11072 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 11073 // Since the receiver will take the lock exactly once and release it exactly once, it 11074 // is safe to pass the same wakelock to all receivers and avoid creating a new lock 11075 // every time. 11076 final WakeLockOnFinishedReceiver receiver = 11077 new WakeLockOnFinishedReceiver(mPendingIntentWakeLock); 11078 try { 11079 if (DBG) log("Sending " + pendingIntent); 11080 final BroadcastOptions options = BroadcastOptions.makeBasic(); 11081 if (mDeps.isAtLeastT()) { 11082 // Explicitly disallow the receiver from starting activities, to prevent apps from 11083 // utilizing the PendingIntent as a backdoor to do this. 11084 options.setPendingIntentBackgroundActivityLaunchAllowed(false); 11085 } 11086 pendingIntent.send(mContext, 0, intent, receiver, null /* Handler */, 11087 null /* requiredPermission */, 11088 mDeps.isAtLeastT() ? options.toBundle() : null); 11089 } catch (PendingIntent.CanceledException e) { 11090 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 11091 receiver.releaseLock(); 11092 releasePendingNetworkRequest(pendingIntent); 11093 } 11094 } 11095 11096 @Nullable 11097 private LocalNetworkInfo localNetworkInfoForNai(@NonNull final NetworkAgentInfo nai) { 11098 if (!nai.isLocalNetwork()) return null; 11099 final Network upstream; 11100 final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector(); 11101 if (null == selector) { 11102 upstream = null; 11103 } else { 11104 final NetworkRequestInfo upstreamNri = mNetworkRequests.get(selector); 11105 final NetworkAgentInfo satisfier = upstreamNri.getSatisfier(); 11106 upstream = (null == satisfier) ? null : satisfier.network; 11107 } 11108 return new LocalNetworkInfo.Builder().setUpstreamNetwork(upstream).build(); 11109 } 11110 11111 private Bundle makeCommonBundleForCallback(@NonNull final NetworkRequestInfo nri, 11112 @Nullable Network network) { 11113 final Bundle bundle = new Bundle(); 11114 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 11115 // TODO: check if defensive copies of data is needed. 11116 putParcelable(bundle, nri.getNetworkRequestForCallback()); 11117 if (network != null) { 11118 putParcelable(bundle, network); 11119 } 11120 return bundle; 11121 } 11122 11123 // networkAgent is only allowed to be null if notificationType is CALLBACK_UNAVAIL or 11124 // CALLBACK_RESERVED. This is because, per definition, no network is available for UNAVAIL, and 11125 // RESERVED callbacks happen when a NetworkOffer is created in response to a reservation. 11126 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, 11127 @Nullable final NetworkAgentInfo networkAgent, final int notificationType, 11128 final int arg1) { 11129 if (nri.mMessenger == null) { 11130 // Default request has no msgr. Also prevents callbacks from being invoked for 11131 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks 11132 // are Type.LISTEN, but should not have NetworkCallbacks invoked. 11133 return; 11134 } 11135 // Even if a callback ends up not being sent, it may affect other callbacks in the queue, so 11136 // queue callbacks before checking the declared methods flags. 11137 // UNAVAIL and RESERVED callbacks are safe not to be queued, because RESERVED must always be 11138 // the first callback. In addition, RESERVED cannot be sent more than once and is only 11139 // cancelled by UNVAIL. 11140 // TODO: evaluate whether it makes sense to queue RESERVED callbacks. 11141 if (networkAgent != null && nri.maybeQueueCallback(networkAgent, notificationType)) { 11142 return; 11143 } 11144 if (!nri.isCallbackOverridden(notificationType)) { 11145 // No need to send the notification as the recipient method is not overridden 11146 return; 11147 } 11148 // networkAgent is only null for UNAVAIL and RESERVED. 11149 final Network bundleNetwork = (networkAgent != null) ? networkAgent.network : null; 11150 final Bundle bundle = makeCommonBundleForCallback(nri, bundleNetwork); 11151 final boolean includeLocationSensitiveInfo = 11152 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0; 11153 final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); 11154 switch (notificationType) { 11155 case CALLBACK_RESERVED: { 11156 final NetworkCapabilities nc = 11157 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11158 networkCapabilitiesRestrictedForCallerPermissions( 11159 nri.getReservedCapabilities(), nri.mPid, nri.mUid), 11160 includeLocationSensitiveInfo, nri.mPid, nri.mUid, 11161 nrForCallback.getRequestorPackageName(), 11162 nri.mCallingAttributionTag); 11163 putParcelable(bundle, nc); 11164 break; 11165 } 11166 case CALLBACK_AVAILABLE: { 11167 final NetworkCapabilities nc = 11168 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11169 networkCapabilitiesRestrictedForCallerPermissions( 11170 networkAgent.networkCapabilities, nri.mPid, nri.mUid), 11171 includeLocationSensitiveInfo, nri.mPid, nri.mUid, 11172 nrForCallback.getRequestorPackageName(), 11173 nri.mCallingAttributionTag); 11174 putParcelable(bundle, nc); 11175 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 11176 networkAgent.linkProperties, nri.mPid, nri.mUid)); 11177 // The local network info is often null, so can't use the static putParcelable 11178 // method here. 11179 bundle.putParcelable(LocalNetworkInfo.class.getSimpleName(), 11180 localNetworkInfoForNai(networkAgent)); 11181 break; 11182 } 11183 case CALLBACK_CAP_CHANGED: { 11184 // networkAgent can't be null as it has been accessed a few lines above. 11185 final NetworkCapabilities netCap = 11186 networkCapabilitiesRestrictedForCallerPermissions( 11187 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 11188 putParcelable( 11189 bundle, 11190 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11191 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid, 11192 nrForCallback.getRequestorPackageName(), 11193 nri.mCallingAttributionTag)); 11194 break; 11195 } 11196 case CALLBACK_IP_CHANGED: { 11197 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 11198 networkAgent.linkProperties, nri.mPid, nri.mUid)); 11199 break; 11200 } 11201 case CALLBACK_BLK_CHANGED: { 11202 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1); 11203 break; 11204 } 11205 case CALLBACK_LOCAL_NETWORK_INFO_CHANGED: { 11206 if (!networkAgent.isLocalNetwork()) { 11207 Log.wtf(TAG, "Callback for local info for a non-local network"); 11208 return; 11209 } 11210 putParcelable(bundle, localNetworkInfoForNai(networkAgent)); 11211 break; 11212 } 11213 } 11214 callCallbackForRequest(nri, notificationType, bundle, arg1); 11215 } 11216 11217 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, int notificationType, 11218 Bundle bundle, int arg1) { 11219 Message msg = Message.obtain(); 11220 msg.arg1 = arg1; 11221 msg.what = notificationType; 11222 msg.setData(bundle); 11223 try { 11224 if (VDBG) { 11225 String notification = ConnectivityManager.getCallbackName(notificationType); 11226 log("sending notification " + notification + " for " 11227 + nri.getNetworkRequestForCallback()); 11228 } 11229 nri.mMessenger.send(msg); 11230 } catch (RemoteException e) { 11231 // may occur naturally in the race of binder death. 11232 loge("RemoteException caught trying to send a callback msg for " 11233 + nri.getNetworkRequestForCallback()); 11234 } 11235 } 11236 11237 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 11238 bundle.putParcelable(t.getClass().getSimpleName(), t); 11239 } 11240 11241 /** 11242 * Returns whether reassigning a request from an NAI to another can be done gracefully. 11243 * 11244 * When a request should be assigned to a new network, it is normally lingered to give 11245 * time for apps to gracefully migrate their connections. When both networks are on the same 11246 * radio, but that radio can't do time-sharing efficiently, this may end up being 11247 * counter-productive because any traffic on the old network may drastically reduce the 11248 * performance of the new network. 11249 * The stack supports a configuration to let modem vendors state that their radio can't 11250 * do time-sharing efficiently. If this configuration is set, the stack assumes moving 11251 * from one cell network to another can't be done gracefully. 11252 * 11253 * @param oldNai the old network serving the request 11254 * @param newNai the new network serving the request 11255 * @return whether the switch can be graceful 11256 */ 11257 private boolean canSupportGracefulNetworkSwitch(@NonNull final NetworkAgentInfo oldSatisfier, 11258 @NonNull final NetworkAgentInfo newSatisfier) { 11259 if (mCellularRadioTimesharingCapable) return true; 11260 return !oldSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 11261 || !newSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 11262 || !newSatisfier.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY); 11263 } 11264 11265 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 11266 if (nai.numRequestNetworkRequests() != 0) { 11267 for (int i = 0; i < nai.numNetworkRequests(); i++) { 11268 NetworkRequest nr = nai.requestAt(i); 11269 // Ignore listening and track default requests. 11270 if (!nr.isRequest()) continue; 11271 loge("Dead network still had at least " + nr); 11272 break; 11273 } 11274 } 11275 if (mQueueNetworkAgentEventsInSystemServer) { 11276 disconnectAndDestroyNetwork(nai); 11277 } else { 11278 nai.disconnect(); 11279 } 11280 } 11281 11282 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 11283 if (oldNetwork == null) { 11284 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 11285 return; 11286 } 11287 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString()); 11288 11289 // If we get here it means that the last linger timeout for this network expired. So there 11290 // must be no other active linger timers, and we must stop lingering. 11291 oldNetwork.clearInactivityState(); 11292 11293 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 11294 // Tear the network down. 11295 teardownUnneededNetwork(oldNetwork); 11296 } else { 11297 // Put the network in the background if it doesn't satisfy any foreground request. 11298 updateCapabilitiesForNetwork(oldNetwork); 11299 } 11300 } 11301 11302 private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) { 11303 boolean isDefaultChanged = false; 11304 for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) { 11305 final NetworkReassignment.RequestReassignment reassignment = 11306 changes.getReassignment(defaultRequestInfo); 11307 if (null == reassignment) { 11308 continue; 11309 } 11310 // reassignment only contains those instances where the satisfying network changed. 11311 isDefaultChanged = true; 11312 // Notify system services of the new default. 11313 makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork); 11314 } 11315 11316 if (isDefaultChanged) { 11317 // Hold a wakelock for a short time to help apps in migrating to a new default. 11318 scheduleReleaseNetworkTransitionWakelock(); 11319 } 11320 } 11321 11322 private void resetHttpProxyForNonDefaultNetwork(NetworkAgentInfo oldDefaultNetwork) { 11323 if (null == oldDefaultNetwork) return; 11324 // The network stopped being the default. If it was using a PAC proxy, then the 11325 // proxy needs to be reset, otherwise HTTP requests on this network may be sent 11326 // to the local proxy server, which would forward them over the newly default network. 11327 final ProxyInfo proxyInfo = oldDefaultNetwork.linkProperties.getHttpProxy(); 11328 if (null == proxyInfo || !proxyInfo.isPacProxy()) return; 11329 oldDefaultNetwork.linkProperties.setHttpProxy(new ProxyInfo(proxyInfo.getPacFileUrl())); 11330 notifyNetworkCallbacks(oldDefaultNetwork, CALLBACK_IP_CHANGED); 11331 } 11332 11333 private void makeDefault(@NonNull final NetworkRequestInfo nri, 11334 @Nullable final NetworkAgentInfo oldDefaultNetwork, 11335 @Nullable final NetworkAgentInfo newDefaultNetwork) { 11336 if (DBG) { 11337 log("Switching to new default network for: " + nri + " using " + newDefaultNetwork); 11338 } 11339 11340 // Fix up the NetworkCapabilities of any networks that have this network as underlying. 11341 if (newDefaultNetwork != null) { 11342 propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network); 11343 } 11344 11345 // Set an app level managed default and return since further processing only applies to the 11346 // default network. 11347 if (mDefaultRequest != nri) { 11348 makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork); 11349 return; 11350 } 11351 11352 makeDefaultNetwork(newDefaultNetwork); 11353 11354 if (oldDefaultNetwork != null) { 11355 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork); 11356 } 11357 mNetworkActivityTracker.updateDefaultNetwork(newDefaultNetwork, oldDefaultNetwork); 11358 maybeDestroyPendingSockets(newDefaultNetwork, oldDefaultNetwork); 11359 mProxyTracker.setDefaultProxy(null != newDefaultNetwork 11360 ? newDefaultNetwork.linkProperties.getHttpProxy() : null); 11361 resetHttpProxyForNonDefaultNetwork(oldDefaultNetwork); 11362 updateTcpBufferSizes(null != newDefaultNetwork 11363 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null); 11364 notifyIfacesChangedForNetworkStats(); 11365 } 11366 11367 private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri, 11368 @Nullable final NetworkAgentInfo oldDefaultNetwork, 11369 @Nullable final NetworkAgentInfo newDefaultNetwork) { 11370 try { 11371 if (VDBG) { 11372 log("Setting default network for " + nri 11373 + " using UIDs " + nri.getUids() 11374 + " with old network " + (oldDefaultNetwork != null 11375 ? oldDefaultNetwork.network().getNetId() : "null") 11376 + " and new network " + (newDefaultNetwork != null 11377 ? newDefaultNetwork.network().getNetId() : "null")); 11378 } 11379 if (nri.getUids().isEmpty()) { 11380 throw new IllegalStateException("makeDefaultForApps called without specifying" 11381 + " any applications to set as the default." + nri); 11382 } 11383 if (null != newDefaultNetwork) { 11384 modifyNetworkUidRanges(true /* add */, newDefaultNetwork, nri.getUids(), 11385 nri.getPreferenceOrderForNetd()); 11386 } 11387 if (null != oldDefaultNetwork) { 11388 modifyNetworkUidRanges(false /* add */, oldDefaultNetwork, nri.getUids(), 11389 nri.getPreferenceOrderForNetd()); 11390 } 11391 } catch (RemoteException | ServiceSpecificException e) { 11392 loge("Exception setting app default network", e); 11393 } 11394 } 11395 11396 /** 11397 * Collect restricted uid ranges for the given network and UserHandle, these uids 11398 * are not restricted for matched enterprise networks but being restricted for non-matched 11399 * enterprise networks and non-enterprise networks. 11400 */ 11401 @NonNull 11402 private ArraySet<UidRange> getRestrictedUidRangesForEnterpriseBlocking( 11403 @NonNull NetworkAgentInfo nai, @NonNull UserHandle user) { 11404 final ArraySet<UidRange> restrictedUidRanges = new ArraySet<>(); 11405 for (final ProfileNetworkPreferenceInfo pref : mProfileNetworkPreferences) { 11406 if (!pref.user.equals(user) || !pref.blockingNonEnterprise) continue; 11407 11408 if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_ENTERPRISE)) { 11409 // The NC is built from a `ProfileNetworkPreference` which has only one 11410 // enterprise ID, so it's guaranteed to have exactly one. 11411 final int prefId = pref.capabilities.getEnterpriseIds()[0]; 11412 if (nai.networkCapabilities.hasEnterpriseId(prefId)) { 11413 continue; 11414 } 11415 } 11416 11417 if (UidRangeUtils.doesRangeSetOverlap(restrictedUidRanges, 11418 pref.capabilities.getUidRanges())) { 11419 throw new IllegalArgumentException( 11420 "Overlapping uid range in preference: " + pref); 11421 } 11422 restrictedUidRanges.addAll(pref.capabilities.getUidRanges()); 11423 } 11424 return restrictedUidRanges; 11425 } 11426 11427 private void updateProfileAllowedNetworks() { 11428 // Netd command is not implemented before U. 11429 if (!mDeps.isAtLeastU()) return; 11430 11431 ensureRunningOnConnectivityServiceThread(); 11432 final ArrayList<NativeUidRangeConfig> configs = new ArrayList<>(); 11433 final List<UserHandle> users = mContext.getSystemService(UserManager.class) 11434 .getUserHandles(true /* excludeDying */); 11435 if (users.isEmpty()) { 11436 throw new IllegalStateException("No user is available"); 11437 } 11438 11439 forEachNetworkAgentInfo(nai -> { 11440 ArraySet<UidRange> allowedUidRanges = new ArraySet<>(); 11441 for (final UserHandle user : users) { 11442 final ArraySet<UidRange> restrictedUidRanges = 11443 getRestrictedUidRangesForEnterpriseBlocking(nai, user); 11444 allowedUidRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 11445 UidRange.createForUser(user), restrictedUidRanges)); 11446 } 11447 11448 final UidRangeParcel[] rangesParcel = toUidRangeStableParcels(allowedUidRanges); 11449 configs.add(new NativeUidRangeConfig( 11450 nai.network.netId, rangesParcel, 0 /* subPriority */)); 11451 }); 11452 11453 // The netd API replaces the previous configs with the current configs. 11454 // Thus, for network disconnection or preference removal, no need to 11455 // unset previous config. Instead, collecting all currently needed 11456 // configs and issue to netd. 11457 try { 11458 mNetd.setNetworkAllowlist(configs.toArray(new NativeUidRangeConfig[0])); 11459 } catch (ServiceSpecificException e) { 11460 // Has the interface disappeared since the network was built? 11461 Log.wtf(TAG, "Unexpected ServiceSpecificException", e); 11462 } catch (RemoteException e) { 11463 // Netd died. This will cause a runtime restart anyway. 11464 Log.wtf(TAG, "Unexpected RemoteException", e); 11465 } 11466 } 11467 11468 private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) { 11469 try { 11470 if (null != newDefaultNetwork) { 11471 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId()); 11472 } else { 11473 mNetd.networkClearDefault(); 11474 } 11475 } catch (RemoteException | ServiceSpecificException e) { 11476 loge("Exception setting default network :" + e); 11477 } 11478 } 11479 11480 private void processListenRequests(@NonNull final NetworkAgentInfo nai) { 11481 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 11482 processNewlyLostListenRequests(nai); 11483 notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED); 11484 processNewlySatisfiedListenRequests(nai); 11485 } 11486 11487 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) { 11488 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 11489 if (nri.isMultilayerRequest()) { 11490 continue; 11491 } 11492 final NetworkRequest nr = nri.mRequests.get(0); 11493 if (!nr.isListen()) continue; 11494 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 11495 nai.removeRequest(nr.requestId); 11496 callCallbackForRequest(nri, nai, CALLBACK_LOST, 0); 11497 } 11498 } 11499 } 11500 11501 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) { 11502 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 11503 if (nri.isMultilayerRequest()) { 11504 continue; 11505 } 11506 final NetworkRequest nr = nri.mRequests.get(0); 11507 if (!nr.isListen()) continue; 11508 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 11509 nai.addRequest(nr); 11510 notifyNetworkAvailable(nai, nri); 11511 } 11512 } 11513 } 11514 11515 // An accumulator class to gather the list of changes that result from a rematch. 11516 private static class NetworkReassignment { 11517 static class RequestReassignment { 11518 @NonNull public final NetworkRequestInfo mNetworkRequestInfo; 11519 @Nullable public final NetworkRequest mOldNetworkRequest; 11520 @Nullable public final NetworkRequest mNewNetworkRequest; 11521 @Nullable public final NetworkAgentInfo mOldNetwork; 11522 @Nullable public final NetworkAgentInfo mNewNetwork; 11523 RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo, 11524 @Nullable final NetworkRequest oldNetworkRequest, 11525 @Nullable final NetworkRequest newNetworkRequest, 11526 @Nullable final NetworkAgentInfo oldNetwork, 11527 @Nullable final NetworkAgentInfo newNetwork) { 11528 mNetworkRequestInfo = networkRequestInfo; 11529 mOldNetworkRequest = oldNetworkRequest; 11530 mNewNetworkRequest = newNetworkRequest; 11531 mOldNetwork = oldNetwork; 11532 mNewNetwork = newNetwork; 11533 } 11534 11535 public String toString() { 11536 final NetworkRequest requestToShow = null != mNewNetworkRequest 11537 ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0); 11538 return requestToShow.requestId + " : " 11539 + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null") 11540 + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null"); 11541 } 11542 } 11543 11544 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>(); 11545 11546 @NonNull Iterable<RequestReassignment> getRequestReassignments() { 11547 return mReassignments; 11548 } 11549 11550 void addRequestReassignment(@NonNull final RequestReassignment reassignment) { 11551 if (Build.isDebuggable()) { 11552 // The code is never supposed to add two reassignments of the same request. Make 11553 // sure this stays true, but without imposing this expensive check on all 11554 // reassignments on all user devices. 11555 for (final RequestReassignment existing : mReassignments) { 11556 if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) { 11557 throw new IllegalStateException("Trying to reassign [" 11558 + reassignment + "] but already have [" 11559 + existing + "]"); 11560 } 11561 } 11562 } 11563 mReassignments.add(reassignment); 11564 } 11565 11566 // Will return null if this reassignment does not change the network assigned to 11567 // the passed request. 11568 @Nullable 11569 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) { 11570 for (final RequestReassignment event : getRequestReassignments()) { 11571 if (nri == event.mNetworkRequestInfo) return event; 11572 } 11573 return null; 11574 } 11575 11576 public String toString() { 11577 final StringJoiner sj = new StringJoiner(", " /* delimiter */, 11578 "NetReassign [" /* prefix */, "]" /* suffix */); 11579 if (mReassignments.isEmpty()) return sj.add("no changes").toString(); 11580 for (final RequestReassignment rr : getRequestReassignments()) { 11581 sj.add(rr.toString()); 11582 } 11583 return sj.toString(); 11584 } 11585 11586 public String debugString() { 11587 final StringBuilder sb = new StringBuilder(); 11588 sb.append("NetworkReassignment :"); 11589 if (mReassignments.isEmpty()) return sb.append(" no changes").toString(); 11590 for (final RequestReassignment rr : getRequestReassignments()) { 11591 sb.append("\n ").append(rr); 11592 } 11593 return sb.append("\n").toString(); 11594 } 11595 } 11596 11597 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri, 11598 @Nullable final NetworkRequest previousRequest, 11599 @Nullable final NetworkRequest newRequest, 11600 @Nullable final NetworkAgentInfo previousSatisfier, 11601 @Nullable final NetworkAgentInfo newSatisfier, 11602 final long now) { 11603 if (null != newSatisfier && mNoServiceNetwork != newSatisfier) { 11604 if (VDBG) log("rematch for " + newSatisfier.toShortString()); 11605 if (null != previousRequest && null != previousSatisfier) { 11606 if (VDBG || DDBG) { 11607 log(" accepting network in place of " + previousSatisfier.toShortString() 11608 + " for " + newRequest); 11609 } 11610 previousSatisfier.removeRequest(previousRequest.requestId); 11611 if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier) 11612 && !previousSatisfier.isDestroyed()) { 11613 // If this network switch can't be supported gracefully, the request is not 11614 // lingered. This allows letting go of the network sooner to reclaim some 11615 // performance on the new network, since the radio can't do both at the same 11616 // time while preserving good performance. 11617 // 11618 // Also don't linger the request if the old network has been destroyed. 11619 // A destroyed network does not provide actual network connectivity, so 11620 // lingering it is not useful. In particular this ensures that a destroyed 11621 // network is outscored by its replacement, 11622 // then it is torn down immediately instead of being lingered, and any apps that 11623 // were using it immediately get onLost and can connect using the new network. 11624 previousSatisfier.lingerRequest(previousRequest.requestId, now); 11625 } 11626 } else { 11627 if (VDBG || DDBG) log(" accepting network in place of null for " + newRequest); 11628 } 11629 11630 // To prevent constantly CPU wake up for nascent timer, if a network comes up 11631 // and immediately satisfies a request then remove the timer. This will happen for 11632 // all networks except in the case of an underlying network for a VCN. 11633 if (newSatisfier.isNascent()) { 11634 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE); 11635 newSatisfier.unsetInactive(); 11636 } 11637 11638 // if newSatisfier is not null, then newRequest may not be null. 11639 newSatisfier.unlingerRequest(newRequest.requestId); 11640 if (!newSatisfier.addRequest(newRequest)) { 11641 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has " 11642 + newRequest); 11643 } 11644 } else if (null != previousRequest && null != previousSatisfier) { 11645 if (DBG) { 11646 log("Network " + previousSatisfier.toShortString() + " stopped satisfying" 11647 + " request " + previousRequest.requestId); 11648 } 11649 previousSatisfier.removeRequest(previousRequest.requestId); 11650 } 11651 nri.setSatisfier(newSatisfier, newRequest); 11652 } 11653 11654 /** 11655 * This function is triggered when something can affect what network should satisfy what 11656 * request, and it computes the network reassignment from the passed collection of requests to 11657 * network match to the one that the system should now have. That data is encoded in an 11658 * object that is a list of changes, each of them having an NRI, and old satisfier, and a new 11659 * satisfier. 11660 * 11661 * After the reassignment is computed, it is applied to the state objects. 11662 * 11663 * @param networkRequests the nri objects to evaluate for possible network reassignment 11664 * @return NetworkReassignment listing of proposed network assignment changes 11665 */ 11666 @NonNull 11667 private NetworkReassignment computeNetworkReassignment( 11668 @NonNull final Collection<NetworkRequestInfo> networkRequests) { 11669 final NetworkReassignment changes = new NetworkReassignment(); 11670 11671 // Gather the list of all relevant agents. 11672 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>(); 11673 forEachNetworkAgentInfo(nai -> nais.add(nai)); 11674 11675 for (final NetworkRequestInfo nri : networkRequests) { 11676 // Non-multilayer listen requests can be ignored. 11677 if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) { 11678 continue; 11679 } 11680 NetworkAgentInfo bestNetwork = null; 11681 NetworkRequest bestRequest = null; 11682 for (final NetworkRequest req : nri.mRequests) { 11683 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier()); 11684 // Stop evaluating as the highest possible priority request is satisfied. 11685 if (null != bestNetwork) { 11686 bestRequest = req; 11687 break; 11688 } 11689 } 11690 if (null == bestNetwork && isDefaultBlocked(nri)) { 11691 // Remove default networking if disallowed for managed default requests. 11692 bestNetwork = mNoServiceNetwork; 11693 } 11694 if (nri.getSatisfier() != bestNetwork) { 11695 // bestNetwork may be null if no network can satisfy this request. 11696 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( 11697 nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork)); 11698 } 11699 } 11700 return changes; 11701 } 11702 11703 private Set<NetworkRequestInfo> getNrisFromGlobalRequests() { 11704 return new HashSet<>(mNetworkRequests.values()); 11705 } 11706 11707 /** 11708 * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks 11709 * being disconnected. 11710 */ 11711 private void rematchAllNetworksAndRequests() { 11712 rematchNetworksAndRequests(getNrisFromGlobalRequests()); 11713 } 11714 11715 /** 11716 * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks 11717 * being disconnected. 11718 */ 11719 private void rematchNetworksAndRequests( 11720 @NonNull final Set<NetworkRequestInfo> networkRequests) { 11721 ensureRunningOnConnectivityServiceThread(); 11722 // TODO: This may be slow, and should be optimized. 11723 final long start = SystemClock.elapsedRealtime(); 11724 final NetworkReassignment changes = computeNetworkReassignment(networkRequests); 11725 final long computed = SystemClock.elapsedRealtime(); 11726 applyNetworkReassignment(changes, start); 11727 final long applied = SystemClock.elapsedRealtime(); 11728 issueNetworkNeeds(); 11729 final long end = SystemClock.elapsedRealtime(); 11730 if (VDBG || DDBG) { 11731 log(String.format("Rematched networks [computed %dms] [applied %dms] [issued %d]", 11732 computed - start, applied - computed, end - applied)); 11733 log(changes.debugString()); 11734 } else if (DBG) { 11735 // Shorter form, only one line of log 11736 log(String.format("%s [c %d] [a %d] [i %d]", changes.toString(), 11737 computed - start, applied - computed, end - applied)); 11738 } 11739 } 11740 11741 private boolean hasSameInterfaceName(@Nullable final NetworkAgentInfo nai1, 11742 @Nullable final NetworkAgentInfo nai2) { 11743 if (null == nai1) return null == nai2; 11744 if (null == nai2) return false; 11745 return nai1.linkProperties.getInterfaceName() 11746 .equals(nai2.linkProperties.getInterfaceName()); 11747 } 11748 11749 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes, 11750 final long now) { 11751 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos; 11752 11753 // Since most of the time there are only 0 or 1 background networks, it would probably 11754 // be more efficient to just use an ArrayList here. TODO : measure performance 11755 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>(); 11756 for (final NetworkAgentInfo nai : nais) { 11757 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai); 11758 } 11759 11760 // First, update the lists of satisfied requests in the network agents. This is necessary 11761 // because some code later depends on this state to be correct, most prominently computing 11762 // the linger status. 11763 for (final NetworkReassignment.RequestReassignment event : 11764 changes.getRequestReassignments()) { 11765 updateSatisfiersForRematchRequest(event.mNetworkRequestInfo, 11766 event.mOldNetworkRequest, event.mNewNetworkRequest, 11767 event.mOldNetwork, event.mNewNetwork, 11768 now); 11769 } 11770 11771 // Process default network changes if applicable. 11772 processDefaultNetworkChanges(changes); 11773 11774 // Update forwarding rules for the upstreams of local networks. Do this before sending 11775 // onAvailable so that by the time onAvailable is sent the forwarding rules are set up. 11776 // Don't send CALLBACK_LOCAL_NETWORK_INFO_CHANGED yet though : they should be sent after 11777 // onAvailable so clients know what network the change is about. Store such changes in 11778 // an array that's only allocated if necessary (because it's almost never necessary). 11779 final ArrayList<NetworkAgentInfo> localInfoChangedAgents = new ArrayList<>(); 11780 forEachNetworkAgentInfo(nai -> { 11781 if (!nai.isLocalNetwork()) return; // return@forEach 11782 final NetworkRequest nr = nai.localNetworkConfig.getUpstreamSelector(); 11783 if (null == nr) return; // return@forEach, no upstream for this local network 11784 final NetworkRequestInfo nri = mNetworkRequests.get(nr); 11785 final NetworkReassignment.RequestReassignment change = changes.getReassignment(nri); 11786 if (null == change) return; // return@forEach, no change in upstreams for this network 11787 final String fromIface = nai.linkProperties.getInterfaceName(); 11788 if (!hasSameInterfaceName(change.mOldNetwork, change.mNewNetwork) 11789 || change.mOldNetwork.isDestroyed()) { 11790 // There can be a change with the same interface name if the new network is the 11791 // replacement for the old network that was unregisteredAfterReplacement. 11792 try { 11793 if (null != change.mOldNetwork) { 11794 mRoutingCoordinatorService.removeInterfaceForward(fromIface, 11795 change.mOldNetwork.linkProperties.getInterfaceName()); 11796 disableMulticastRouting(fromIface, 11797 change.mOldNetwork.linkProperties.getInterfaceName()); 11798 } 11799 // If the new upstream is already destroyed, there is no point in setting up 11800 // a forward (in fact, it might forward to the interface for some new network !) 11801 // Later when the upstream disconnects CS will try to remove the forward, which 11802 // is ignored with a benign log by RoutingCoordinatorService. 11803 if (null != change.mNewNetwork && !change.mNewNetwork.isDestroyed()) { 11804 mRoutingCoordinatorService.addInterfaceForward(fromIface, 11805 change.mNewNetwork.linkProperties.getInterfaceName()); 11806 applyMulticastRoutingConfig(fromIface, 11807 change.mNewNetwork.linkProperties.getInterfaceName(), 11808 nai.localNetworkConfig); 11809 } 11810 } catch (final RemoteException e) { 11811 loge("Can't update forwarding rules", e); 11812 } 11813 } 11814 localInfoChangedAgents.add(nai); 11815 }); 11816 11817 // Notify requested networks are available after the default net is switched, but 11818 // before LegacyTypeTracker sends legacy broadcasts 11819 for (final NetworkReassignment.RequestReassignment event : 11820 changes.getRequestReassignments()) { 11821 if (null != event.mNewNetwork) { 11822 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo); 11823 } else { 11824 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork, 11825 CALLBACK_LOST, 0); 11826 } 11827 } 11828 11829 // Update the inactivity state before processing listen callbacks, because the background 11830 // computation depends on whether the network is inactive. Don't send the LOSING callbacks 11831 // just yet though, because they have to be sent after the listens are processed to keep 11832 // backward compatibility. 11833 final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>(); 11834 for (final NetworkAgentInfo nai : nais) { 11835 // Rematching may have altered the inactivity state of some networks, so update all 11836 // inactivity timers. updateInactivityState reads the state from the network agent 11837 // and does nothing if the state has not changed : the source of truth is controlled 11838 // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which 11839 // have been called while rematching the individual networks above. 11840 if (updateInactivityState(nai, now)) { 11841 inactiveNetworks.add(nai); 11842 } 11843 } 11844 11845 for (final NetworkAgentInfo nai : nais) { 11846 final boolean oldBackground = oldBgNetworks.contains(nai); 11847 // Process listen requests and update capabilities if the background state has 11848 // changed for this network. For consistency with previous behavior, send onLost 11849 // callbacks before onAvailable. 11850 processNewlyLostListenRequests(nai); 11851 if (oldBackground != nai.isBackgroundNetwork()) { 11852 applyBackgroundChangeForRematch(nai); 11853 } 11854 processNewlySatisfiedListenRequests(nai); 11855 } 11856 11857 for (final NetworkAgentInfo nai : inactiveNetworks) { 11858 // For nascent networks, if connecting with no foreground request, skip broadcasting 11859 // LOSING for backward compatibility. This is typical when mobile data connected while 11860 // wifi connected with mobile data always-on enabled. 11861 if (nai.isNascent()) continue; 11862 notifyNetworkLosing(nai, now); 11863 } 11864 11865 // Send LOCAL_NETWORK_INFO_CHANGED callbacks now that onAvailable and onLost have been sent. 11866 for (final NetworkAgentInfo nai : localInfoChangedAgents) { 11867 notifyNetworkCallbacks(nai, CALLBACK_LOCAL_NETWORK_INFO_CHANGED); 11868 } 11869 11870 updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais); 11871 11872 // Tear down all unneeded networks. 11873 forEachNetworkAgentInfo(nai -> { 11874 if (unneeded(nai, UnneededFor.TEARDOWN)) { 11875 if (nai.getInactivityExpiry() > 0) { 11876 // This network has active linger timers and no requests, but is not 11877 // lingering. Linger it. 11878 // 11879 // One way (the only way?) this can happen if this network is unvalidated 11880 // and became unneeded due to another network improving its score to the 11881 // point where this network will no longer be able to satisfy any requests 11882 // even if it validates. 11883 if (updateInactivityState(nai, now)) { 11884 notifyNetworkLosing(nai, now); 11885 } 11886 } else { 11887 if (DBG) log("Reaping " + nai.toShortString()); 11888 teardownUnneededNetwork(nai); 11889 } 11890 } 11891 }); 11892 } 11893 11894 /** 11895 * Apply a change in background state resulting from rematching networks with requests. 11896 * 11897 * During rematch, a network may change background states by starting to satisfy or stopping 11898 * to satisfy a foreground request. Listens don't count for this. When a network changes 11899 * background states, its capabilities need to be updated and callbacks fired for the 11900 * capability change. 11901 * 11902 * @param nai The network that changed background states 11903 */ 11904 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) { 11905 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities); 11906 if (Objects.equals(nai.networkCapabilities, newNc)) return; 11907 updateNetworkPermissions(nai, newNc); 11908 nai.getAndSetNetworkCapabilities(newNc); 11909 notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED); 11910 } 11911 11912 private void updateLegacyTypeTrackerAndVpnLockdownForRematch( 11913 @NonNull final NetworkReassignment changes, 11914 @NonNull final Collection<NetworkAgentInfo> nais) { 11915 final NetworkReassignment.RequestReassignment reassignmentOfDefault = 11916 changes.getReassignment(mDefaultRequest); 11917 final NetworkAgentInfo oldDefaultNetwork = 11918 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null; 11919 final NetworkAgentInfo newDefaultNetwork = 11920 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null; 11921 11922 if (oldDefaultNetwork != newDefaultNetwork) { 11923 // Maintain the illusion : since the legacy API only understands one network at a time, 11924 // if the default network changed, apps should see a disconnected broadcast for the 11925 // old default network before they see a connected broadcast for the new one. 11926 if (oldDefaultNetwork != null) { 11927 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 11928 oldDefaultNetwork, true); 11929 } 11930 if (newDefaultNetwork != null) { 11931 // The new default network can be newly null if and only if the old default 11932 // network doesn't satisfy the default request any more because it lost a 11933 // capability. 11934 mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0; 11935 mLegacyTypeTracker.add( 11936 newDefaultNetwork.networkInfo.getType(), newDefaultNetwork); 11937 } 11938 } 11939 11940 // Now that all the callbacks have been sent, send the legacy network broadcasts 11941 // as needed. This is necessary so that legacy requests correctly bind dns 11942 // requests to this network. The legacy users are listening for this broadcast 11943 // and will generally do a dns request so they can ensureRouteToHost and if 11944 // they do that before the callbacks happen they'll use the default network. 11945 // 11946 // TODO: Is there still a race here? The legacy broadcast will be sent after sending 11947 // callbacks, but if apps can receive the broadcast before the callback, they still might 11948 // have an inconsistent view of networking. 11949 // 11950 // This *does* introduce a race where if the user uses the new api 11951 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 11952 // they may get old info. Reverse this after the old startUsing api is removed. 11953 // This is on top of the multiple intent sequencing referenced in the todo above. 11954 for (NetworkAgentInfo nai : nais) { 11955 if (nai.everConnected()) { 11956 addNetworkToLegacyTypeTracker(nai); 11957 } 11958 } 11959 } 11960 11961 private void issueNetworkNeeds() { 11962 ensureRunningOnConnectivityServiceThread(); 11963 for (final NetworkOfferInfo noi : mNetworkOffers) { 11964 issueNetworkNeeds(noi); 11965 } 11966 } 11967 11968 private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) { 11969 ensureRunningOnConnectivityServiceThread(); 11970 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 11971 informOffer(nri, noi.offer, mNetworkRanker); 11972 } 11973 } 11974 11975 /** 11976 * Inform a NetworkOffer about any new situation of a request. 11977 * 11978 * This function handles updates to offers. A number of events may happen that require 11979 * updating the registrant for this offer about the situation : 11980 * • The offer itself was updated. This may lead the offer to no longer being able 11981 * to satisfy a request or beat a satisfier (and therefore be no longer needed), 11982 * or conversely being strengthened enough to beat the satisfier (and therefore 11983 * start being needed) 11984 * • The network satisfying a request changed (including cases where the request 11985 * starts or stops being satisfied). The new network may be a stronger or weaker 11986 * match than the old one, possibly affecting whether the offer is needed. 11987 * • The network satisfying a request updated their score. This may lead the offer 11988 * to no longer be able to beat it if the current satisfier got better, or 11989 * conversely start being a good choice if the current satisfier got weaker. 11990 * 11991 * @param nri The request 11992 * @param offer The offer. This may be an updated offer. 11993 */ 11994 private static void informOffer(@NonNull NetworkRequestInfo nri, 11995 @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) { 11996 final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null; 11997 final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null; 11998 11999 // Multi-layer requests have a currently active request, the one being satisfied. 12000 // Since the system will try to bring up a better network than is currently satisfying 12001 // the request, NetworkProviders need to be told the offers matching the requests *above* 12002 // the currently satisfied one are needed, that the ones *below* the satisfied one are 12003 // not needed, and the offer is needed for the active request iff the offer can beat 12004 // the satisfier. 12005 // For non-multilayer requests, the logic above gracefully degenerates to only the 12006 // last case. 12007 // To achieve this, the loop below will proceed in three steps. In a first phase, inform 12008 // providers that the offer is needed for this request, until the active request is found. 12009 // In a second phase, deal with the currently active request. In a third phase, inform 12010 // the providers that offer is unneeded for the remaining requests. 12011 12012 // First phase : inform providers of all requests above the active request. 12013 int i; 12014 for (i = 0; nri.mRequests.size() > i; ++i) { 12015 final NetworkRequest request = nri.mRequests.get(i); 12016 if (activeRequest == request) break; // Found the active request : go to phase 2 12017 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 12018 // Since this request is higher-priority than the one currently satisfied, if the 12019 // offer can satisfy it, the provider should try and bring up the network for sure ; 12020 // no need to even ask the ranker – an offer that can satisfy is always better than 12021 // no network. Hence tell the provider so unless it already knew. 12022 if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) { 12023 offer.onNetworkNeeded(request); 12024 } 12025 } 12026 12027 // Second phase : deal with the active request (if any) 12028 if (null != activeRequest && activeRequest.isRequest()) { 12029 final boolean oldNeeded = offer.neededFor(activeRequest); 12030 // If an offer can satisfy the request, it is considered needed if it is currently 12031 // served by this provider or if this offer can beat the current satisfier. 12032 final boolean currentlyServing = satisfier != null 12033 && satisfier.factorySerialNumber == offer.providerId 12034 && activeRequest.canBeSatisfiedBy(offer.caps); 12035 final boolean newNeeded = currentlyServing 12036 || networkRanker.mightBeat(activeRequest, satisfier, offer); 12037 if (newNeeded != oldNeeded) { 12038 if (newNeeded) { 12039 offer.onNetworkNeeded(activeRequest); 12040 } else { 12041 // The offer used to be able to beat the satisfier. Now it can't. 12042 offer.onNetworkUnneeded(activeRequest); 12043 } 12044 } 12045 } 12046 12047 // Third phase : inform the providers that the offer isn't needed for any request 12048 // below the active one. 12049 for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) { 12050 final NetworkRequest request = nri.mRequests.get(i); 12051 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 12052 // Since this request is lower-priority than the one currently satisfied, if the 12053 // offer can satisfy it, the provider should not try and bring up the network. 12054 // Hence tell the provider so unless it already knew. 12055 if (offer.neededFor(request)) { 12056 offer.onNetworkUnneeded(request); 12057 } 12058 } 12059 } 12060 12061 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) { 12062 for (int i = 0; i < nai.numNetworkRequests(); i++) { 12063 NetworkRequest nr = nai.requestAt(i); 12064 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 12065 // legacy type tracker filters out repeat adds 12066 mLegacyTypeTracker.add(nr.legacyType, nai); 12067 } 12068 } 12069 12070 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 12071 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 12072 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 12073 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 12074 if (nai.isVPN()) { 12075 mLegacyTypeTracker.add(TYPE_VPN, nai); 12076 } 12077 } 12078 12079 private void updateInetCondition(NetworkAgentInfo nai) { 12080 // Don't bother updating until we've graduated to validated at least once. 12081 if (!nai.everValidated()) return; 12082 // For now only update icons for the default connection. 12083 // TODO: Update WiFi and cellular icons separately. b/17237507 12084 if (!isDefaultNetwork(nai)) return; 12085 12086 int newInetCondition = nai.isValidated() ? 100 : 0; 12087 // Don't repeat publish. 12088 if (newInetCondition == mDefaultInetConditionPublished) return; 12089 12090 mDefaultInetConditionPublished = newInetCondition; 12091 sendInetConditionBroadcast(nai.networkInfo); 12092 } 12093 12094 @NonNull 12095 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) { 12096 final NetworkInfo newInfo = new NetworkInfo(info); 12097 // The suspended and roaming bits are managed in NetworkCapabilities. 12098 final boolean suspended = 12099 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 12100 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) { 12101 // Only override the state with SUSPENDED if the network is currently in CONNECTED 12102 // state. This is because the network could have been suspended before connecting, 12103 // or it could be disconnecting while being suspended, and in both these cases 12104 // the state should not be overridden. Note that the only detailed state that 12105 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to 12106 // worry about multiple different substates of CONNECTED. 12107 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(), 12108 info.getExtraInfo()); 12109 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) { 12110 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the 12111 // network agent is created, then goes to suspended, then goes out of suspended without 12112 // ever setting connected. Check if network agent is ever connected to update the state. 12113 newInfo.setDetailedState(nai.everConnected() 12114 ? NetworkInfo.DetailedState.CONNECTED 12115 : NetworkInfo.DetailedState.CONNECTING, 12116 info.getReason(), 12117 info.getExtraInfo()); 12118 } 12119 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 12120 return newInfo; 12121 } 12122 12123 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) { 12124 final NetworkInfo newInfo = mixInInfo(networkAgent, info); 12125 12126 final NetworkInfo.State state = newInfo.getState(); 12127 NetworkInfo oldInfo = null; 12128 synchronized (networkAgent) { 12129 oldInfo = networkAgent.networkInfo; 12130 networkAgent.networkInfo = newInfo; 12131 } 12132 12133 if (DBG) { 12134 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from " 12135 + oldInfo.getState() + " to " + state); 12136 } 12137 12138 if (shouldCreateNativeNetwork(networkAgent, state)) { 12139 // A network that has just connected has zero requests and is thus a foreground network. 12140 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 12141 12142 if (!createNativeNetwork(networkAgent)) return; 12143 12144 networkAgent.setCreated(); 12145 12146 // If the network is created immediately on register, then apply the LinkProperties now. 12147 // Otherwise, this is done further down when the network goes into connected state. 12148 // Applying the LinkProperties means that the network is ready to carry traffic - 12149 // interfaces and routing rules have been added, DNS servers programmed, etc. 12150 // For VPNs, this must be done before the capabilities are updated, because as soon as 12151 // that happens, UIDs are routed to the network. 12152 if (shouldCreateNetworksImmediately(networkAgent.getCapsNoCopy())) { 12153 applyInitialLinkProperties(networkAgent); 12154 } 12155 12156 // TODO: should this move earlier? It doesn't seem to have anything to do with whether 12157 // a network is created or not. 12158 if (networkAgent.propagateUnderlyingCapabilities()) { 12159 // Initialize the network's capabilities to their starting values according to the 12160 // underlying networks. This ensures that the capabilities are correct before 12161 // anything happens to the network. 12162 updateCapabilitiesForNetwork(networkAgent); 12163 } 12164 networkAgent.onNetworkCreated(); 12165 updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities); 12166 updateProfileAllowedNetworks(); 12167 } 12168 12169 if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) { 12170 networkAgent.setConnected(); 12171 12172 // NetworkCapabilities need to be set before sending the private DNS config to 12173 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required. 12174 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities); 12175 12176 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 12177 if (!shouldCreateNetworksImmediately(networkAgent.getCapsNoCopy())) { 12178 applyInitialLinkProperties(networkAgent); 12179 } else { 12180 // The network was created when the agent registered, and the LinkProperties are 12181 // already up-to-date. However, updateLinkProperties also makes some changes only 12182 // when the network connects. Apply those changes here. On T and below these are 12183 // handled by the applyInitialLinkProperties call just above. 12184 // TODO: stop relying on updateLinkProperties(..., null) to do this. 12185 // If something depends on both LinkProperties and connected state, it should be in 12186 // this method as well. 12187 networkAgent.clatd.update(); 12188 updateProxy(networkAgent.linkProperties, null); 12189 } 12190 12191 // If a rate limit has been configured and is applicable to this network (network 12192 // provides internet connectivity), apply it. The tc police filter cannot be attached 12193 // before the clsact qdisc is added which happens as part of updateLinkProperties -> 12194 // updateInterfaces -> RoutingCoordinatorManager#addInterfaceToNetwork 12195 // Note: in case of a system server crash, the NetworkController constructor in netd 12196 // (called when netd starts up) deletes the clsact qdisc of all interfaces. 12197 if (canNetworkBeRateLimited(networkAgent) && mIngressRateLimit >= 0) { 12198 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 12199 mIngressRateLimit); 12200 } 12201 12202 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect 12203 // command must be sent after updating LinkProperties to maximize chances of 12204 // NetworkMonitor seeing the correct LinkProperties when starting. 12205 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call. 12206 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) { 12207 networkAgent.networkMonitor().setAcceptPartialConnectivity(); 12208 } 12209 final NetworkMonitorParameters params = new NetworkMonitorParameters(); 12210 params.networkAgentConfig = networkAgent.networkAgentConfig; 12211 params.networkCapabilities = networkAgent.networkCapabilities; 12212 params.linkProperties = new LinkProperties(networkAgent.linkProperties, 12213 true /* parcelSensitiveFields */); 12214 // isAtLeastT() is conservative here, as recent versions of NetworkStack support the 12215 // newer callback even before T. However getInterfaceVersion is a synchronized binder 12216 // call that would cause a Log.wtf to be emitted from the system_server process, and 12217 // in the absence of a satisfactory, scalable solution which follows an easy/standard 12218 // process to check the interface version, just use an SDK check. NetworkStack will 12219 // always be new enough when running on T+. 12220 if (mDeps.isAtLeastT()) { 12221 networkAgent.networkMonitor().notifyNetworkConnected(params); 12222 } else { 12223 networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties, 12224 params.networkCapabilities); 12225 } 12226 final long evaluationDelay; 12227 if (!networkAgent.networkCapabilities.hasSingleTransport(TRANSPORT_WIFI)) { 12228 // If the network is anything other than pure wifi, use the default timeout. 12229 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 12230 } else if (networkAgent.networkAgentConfig.isExplicitlySelected()) { 12231 // If the network is explicitly selected, use the default timeout because it's 12232 // shorter and the user is likely staring at the screen expecting it to validate 12233 // right away. 12234 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 12235 } else if (avoidBadWifi() || !activelyPreferBadWifi()) { 12236 // If avoiding bad wifi, or if not avoiding but also not preferring bad wifi 12237 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 12238 } else { 12239 // It's wifi, automatically connected, and bad wifi is preferred : use the 12240 // longer timeout to avoid the device switching to captive portals with bad 12241 // signal or very slow response. 12242 evaluationDelay = ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS; 12243 } 12244 scheduleEvaluationTimeout(networkAgent.network, evaluationDelay); 12245 12246 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 12247 // be communicated to a particular NetworkAgent depends only on the network's immutable, 12248 // capabilities, so it only needs to be done once on initial connect, not every time the 12249 // network's capabilities change. Note that we do this before rematching the network, 12250 // so we could decide to tear it down immediately afterwards. That's fine though - on 12251 // disconnection NetworkAgents should stop any signal strength monitoring they have been 12252 // doing. 12253 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 12254 12255 // Before first rematching networks, put an inactivity timer without any request, this 12256 // allows {@code updateInactivityState} to update the state accordingly and prevent 12257 // tearing down for any {@code unneeded} evaluation in this period. 12258 // Note that the timer will not be rescheduled since the expiry time is 12259 // fixed after connection regardless of the network satisfying other requests or not. 12260 // But it will be removed as soon as the network satisfies a request for the first time. 12261 networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE, 12262 SystemClock.elapsedRealtime(), mNascentDelayMs); 12263 networkAgent.setInactive(); 12264 12265 if (mTrackMultiNetworkActivities) { 12266 // Start tracking activity of this network. 12267 // This must be called before rematchAllNetworksAndRequests since the network 12268 // should be tracked when the network becomes the default network. 12269 // This method does not trigger any callbacks or broadcasts. Callbacks or broadcasts 12270 // can be triggered later if this network becomes the default network. 12271 mNetworkActivityTracker.setupDataActivityTracking(networkAgent); 12272 } 12273 12274 // Consider network even though it is not yet validated. 12275 rematchAllNetworksAndRequests(); 12276 12277 // This has to happen after matching the requests, because callbacks are just requests. 12278 notifyNetworkCallbacks(networkAgent, CALLBACK_PRECHECK); 12279 } else if (state == NetworkInfo.State.DISCONNECTED) { 12280 if (!mQueueNetworkAgentEventsInSystemServer) { 12281 networkAgent.disconnect(); 12282 } 12283 if (networkAgent.isVPN()) { 12284 updateVpnUids(networkAgent, networkAgent.networkCapabilities, null); 12285 } 12286 disconnectAndDestroyNetwork(networkAgent); 12287 if (networkAgent.isVPN()) { 12288 // As the active or bound network changes for apps, broadcast the default proxy, as 12289 // apps may need to update their proxy data. This is called after disconnecting from 12290 // VPN to make sure we do not broadcast the old proxy data. 12291 // TODO(b/122649188): send the broadcast only to VPN users. 12292 mProxyTracker.sendProxyBroadcast(); 12293 } 12294 } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED 12295 || state == NetworkInfo.State.SUSPENDED)) { 12296 mLegacyTypeTracker.update(networkAgent); 12297 } 12298 } 12299 12300 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { 12301 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); 12302 nai.setScore(score); 12303 rematchAllNetworksAndRequests(); 12304 } 12305 12306 // Notify only this one new request of the current state. Transfer all the 12307 // current state by calling NetworkCapabilities and LinkProperties callbacks 12308 // so that callers can be guaranteed to have as close to atomicity in state 12309 // transfer as can be supported by this current API. 12310 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 12311 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 12312 if (nri.mPendingIntent != null) { 12313 sendPendingIntentForRequest(nri, nai, CALLBACK_AVAILABLE); 12314 // Attempt no subsequent state pushes where intents are involved. 12315 return; 12316 } 12317 12318 callCallbackForRequest(nri, nai, CALLBACK_AVAILABLE, getBlockedState(nai, nri.mAsUid)); 12319 } 12320 12321 // Notify the requests on this NAI that the network is now lingered. 12322 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) { 12323 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 12324 notifyNetworkCallbacks(nai, CALLBACK_LOSING, lingerTime); 12325 } 12326 12327 private int getPermissionBlockedState(final int uid, final int reasons) { 12328 // Before V, the blocked reasons come from NPMS, and that code already behaves as if the 12329 // change was disabled: apps without the internet permission will never be told they are 12330 // blocked. 12331 if (!mDeps.isAtLeastV()) return reasons; 12332 12333 if (hasInternetPermission(uid)) return reasons; 12334 12335 return mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid) 12336 ? reasons | BLOCKED_REASON_NETWORK_RESTRICTED 12337 : BLOCKED_REASON_NONE; 12338 } 12339 12340 private int getBlockedState(int uid, int reasons, boolean metered, boolean vpnBlocked) { 12341 reasons = getPermissionBlockedState(uid, reasons); 12342 if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK; 12343 return vpnBlocked 12344 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN 12345 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN; 12346 } 12347 12348 private int getBlockedState(@NonNull NetworkAgentInfo nai, int uid) { 12349 final boolean metered = nai.networkCapabilities.isMetered(); 12350 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); 12351 final int blockedReasons = mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE); 12352 return getBlockedState(uid, blockedReasons, metered, vpnBlocked); 12353 } 12354 12355 private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) { 12356 if (blockedReasons == BLOCKED_REASON_NONE) { 12357 mUidBlockedReasons.delete(uid); 12358 } else { 12359 mUidBlockedReasons.put(uid, blockedReasons); 12360 } 12361 } 12362 12363 /** 12364 * Notify of the blocked state apps with a registered callback matching a given NAI. 12365 * 12366 * Unlike other callbacks, blocked status is different between each individual uid. So for 12367 * any given nai, all requests need to be considered according to the uid who filed it. 12368 * 12369 * @param nai The target NetworkAgentInfo. 12370 * @param oldMetered True if the previous network capabilities were metered. 12371 * @param newMetered True if the current network capabilities are metered. 12372 * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN. 12373 * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN. 12374 */ 12375 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, 12376 boolean newMetered, List<UidRange> oldBlockedUidRanges, 12377 List<UidRange> newBlockedUidRanges) { 12378 12379 for (int i = 0; i < nai.numNetworkRequests(); i++) { 12380 NetworkRequest nr = nai.requestAt(i); 12381 NetworkRequestInfo nri = mNetworkRequests.get(nr); 12382 12383 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 12384 final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges); 12385 final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges) 12386 ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges) 12387 : oldVpnBlocked; 12388 12389 final int oldBlockedState = getBlockedState( 12390 nri.mAsUid, blockedReasons, oldMetered, oldVpnBlocked); 12391 final int newBlockedState = getBlockedState( 12392 nri.mAsUid, blockedReasons, newMetered, newVpnBlocked); 12393 if (oldBlockedState != newBlockedState) { 12394 callCallbackForRequest(nri, nai, CALLBACK_BLK_CHANGED, 12395 newBlockedState); 12396 } 12397 } 12398 } 12399 12400 /** 12401 * Notify apps with a given UID of the new blocked state according to new uid state. 12402 * @param uid The uid for which the rules changed. 12403 * @param blockedReasons The reasons for why an uid is blocked. 12404 */ 12405 private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) { 12406 forEachNetworkAgentInfo(nai -> { 12407 final boolean metered = nai.networkCapabilities.isMetered(); 12408 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); 12409 12410 final int oldBlockedState = getBlockedState( 12411 uid, mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked); 12412 final int newBlockedState = 12413 getBlockedState(uid, blockedReasons, metered, vpnBlocked); 12414 if (oldBlockedState == newBlockedState) return; // return@forEach 12415 for (int i = 0; i < nai.numNetworkRequests(); i++) { 12416 NetworkRequest nr = nai.requestAt(i); 12417 NetworkRequestInfo nri = mNetworkRequests.get(nr); 12418 if (nri != null && nri.mAsUid == uid) { 12419 callCallbackForRequest(nri, nai, CALLBACK_BLK_CHANGED, 12420 newBlockedState); 12421 } 12422 } 12423 }); 12424 } 12425 12426 @VisibleForTesting 12427 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 12428 // The NetworkInfo we actually send out has no bearing on the real 12429 // state of affairs. For example, if the default connection is mobile, 12430 // and a request for HIPRI has just gone away, we need to pretend that 12431 // HIPRI has just disconnected. So we need to set the type to HIPRI and 12432 // the state to DISCONNECTED, even though the network is of type MOBILE 12433 // and is still connected. 12434 NetworkInfo info = new NetworkInfo(nai.networkInfo); 12435 info.setType(type); 12436 filterForLegacyLockdown(info); 12437 if (state != DetailedState.DISCONNECTED) { 12438 info.setDetailedState(state, null, info.getExtraInfo()); 12439 sendConnectedBroadcast(info); 12440 } else { 12441 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 12442 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 12443 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 12444 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 12445 if (info.isFailover()) { 12446 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 12447 nai.networkInfo.setFailover(false); 12448 } 12449 if (info.getReason() != null) { 12450 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 12451 } 12452 if (info.getExtraInfo() != null) { 12453 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 12454 } 12455 NetworkAgentInfo newDefaultAgent = null; 12456 if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { 12457 newDefaultAgent = mDefaultRequest.getSatisfier(); 12458 if (newDefaultAgent != null) { 12459 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 12460 newDefaultAgent.networkInfo); 12461 } else { 12462 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 12463 } 12464 } 12465 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 12466 mDefaultInetConditionPublished); 12467 sendStickyBroadcast(intent); 12468 if (newDefaultAgent != null) { 12469 sendConnectedBroadcast(newDefaultAgent.networkInfo); 12470 } 12471 } 12472 } 12473 12474 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 12475 if (VDBG || DDBG) { 12476 String notification = ConnectivityManager.getCallbackName(notifyType); 12477 log("notifyType " + notification + " for " + networkAgent.toShortString()); 12478 } 12479 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 12480 NetworkRequest nr = networkAgent.requestAt(i); 12481 NetworkRequestInfo nri = mNetworkRequests.get(nr); 12482 if (VDBG) log(" sending notification for " + nr); 12483 if (nri.mPendingIntent == null) { 12484 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 12485 } else { 12486 sendPendingIntentForRequest(nri, networkAgent, notifyType); 12487 } 12488 } 12489 } 12490 12491 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 12492 notifyNetworkCallbacks(networkAgent, notifyType, 0); 12493 } 12494 12495 /** 12496 * Returns the list of all interfaces that could be used by network traffic that does not 12497 * explicitly specify a network. This includes the default network, but also all VPNs that are 12498 * currently connected. 12499 * 12500 * Must be called on the handler thread. 12501 */ 12502 @NonNull 12503 private ArrayList<Network> getDefaultNetworks() { 12504 ensureRunningOnConnectivityServiceThread(); 12505 final ArrayList<Network> defaultNetworks = new ArrayList<>(); 12506 final Set<Integer> activeNetIds = new ArraySet<>(); 12507 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 12508 if (nri.isBeingSatisfied()) { 12509 activeNetIds.add(nri.getSatisfier().network().netId); 12510 } 12511 } 12512 forEachNetworkAgentInfo(nai -> { 12513 if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) { 12514 defaultNetworks.add(nai.network); 12515 } 12516 }); 12517 return defaultNetworks; 12518 } 12519 12520 /** 12521 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 12522 * active iface's tracked properties has changed. 12523 */ 12524 private void notifyIfacesChangedForNetworkStats() { 12525 ensureRunningOnConnectivityServiceThread(); 12526 String activeIface = null; 12527 LinkProperties activeLinkProperties = getActiveLinkProperties(); 12528 if (activeLinkProperties != null) { 12529 activeIface = activeLinkProperties.getInterfaceName(); 12530 } 12531 12532 final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo(); 12533 try { 12534 final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>(); 12535 snapshots.addAll(getAllNetworkStateSnapshots()); 12536 mStatsManager.notifyNetworkStatus(getDefaultNetworks(), 12537 snapshots, activeIface, Arrays.asList(underlyingNetworkInfos)); 12538 } catch (Exception ignored) { 12539 } 12540 } 12541 12542 @Override 12543 public String getCaptivePortalServerUrl() { 12544 enforceNetworkStackOrSettingsPermission(); 12545 String settingUrl = mResources.get().getString( 12546 R.string.config_networkCaptivePortalServerUrl); 12547 12548 if (!TextUtils.isEmpty(settingUrl)) { 12549 return settingUrl; 12550 } 12551 12552 settingUrl = Settings.Global.getString(mContext.getContentResolver(), 12553 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL); 12554 if (!TextUtils.isEmpty(settingUrl)) { 12555 return settingUrl; 12556 } 12557 12558 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL; 12559 } 12560 12561 @Override 12562 public void startNattKeepalive(Network network, int intervalSeconds, 12563 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { 12564 enforceKeepalivePermission(); 12565 mKeepaliveTracker.startNattKeepalive( 12566 getNetworkAgentInfoForNetwork(network), null /* fd */, 12567 intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT, 12568 // Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to 12569 // false and set the underpinned network to null because there is no way and no 12570 // plan to configure automaticOnOffKeepalives or underpinnedNetwork in this 12571 // deprecated method. 12572 false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */); 12573 } 12574 12575 @Override 12576 public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, 12577 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, 12578 String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) { 12579 try { 12580 final FileDescriptor fd = pfd.getFileDescriptor(); 12581 mKeepaliveTracker.startNattKeepalive( 12582 getNetworkAgentInfoForNetwork(network), fd, resourceId, 12583 intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT, 12584 automaticOnOffKeepalives, underpinnedNetwork); 12585 } finally { 12586 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 12587 // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately. 12588 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 12589 IoUtils.closeQuietly(pfd); 12590 } 12591 } 12592 } 12593 12594 @Override 12595 public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, 12596 ISocketKeepaliveCallback cb) { 12597 try { 12598 enforceKeepalivePermission(); 12599 final FileDescriptor fd = pfd.getFileDescriptor(); 12600 mKeepaliveTracker.startTcpKeepalive( 12601 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); 12602 } finally { 12603 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 12604 // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately. 12605 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 12606 IoUtils.closeQuietly(pfd); 12607 } 12608 } 12609 } 12610 12611 @Override 12612 public void stopKeepalive(@NonNull final ISocketKeepaliveCallback cb) { 12613 mHandler.sendMessage(mHandler.obtainMessage( 12614 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, 0, SocketKeepalive.SUCCESS, 12615 Objects.requireNonNull(cb).asBinder())); 12616 } 12617 12618 @Override 12619 public int[] getSupportedKeepalives() { 12620 enforceAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS, 12621 // Backwards compatibility with CTS 13 12622 android.Manifest.permission.QUERY_ALL_PACKAGES); 12623 12624 return BinderUtils.withCleanCallingIdentity(() -> 12625 KeepaliveResourceUtil.getSupportedKeepalives(mContext)); 12626 } 12627 12628 @Override 12629 public void factoryReset() { 12630 enforceSettingsPermission(); 12631 12632 final int uid = mDeps.getCallingUid(); 12633 final long token = Binder.clearCallingIdentity(); 12634 try { 12635 if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET, 12636 UserHandle.getUserHandleForUid(uid))) { 12637 return; 12638 } 12639 12640 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext); 12641 ipMemoryStore.factoryReset(); 12642 12643 // Turn airplane mode off 12644 setAirplaneMode(false); 12645 12646 // restore private DNS settings to default mode (opportunistic) 12647 if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, 12648 UserHandle.getUserHandleForUid(uid))) { 12649 ConnectivitySettingsManager.setPrivateDnsMode(mContext, 12650 PRIVATE_DNS_MODE_OPPORTUNISTIC); 12651 } 12652 12653 Settings.Global.putString(mContext.getContentResolver(), 12654 ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 12655 } finally { 12656 Binder.restoreCallingIdentity(token); 12657 } 12658 } 12659 12660 @Override 12661 public byte[] getNetworkWatchlistConfigHash() { 12662 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 12663 if (nwm == null) { 12664 loge("Unable to get NetworkWatchlistManager"); 12665 return null; 12666 } 12667 // Redirect it to network watchlist service to access watchlist file and calculate hash. 12668 return nwm.getWatchlistConfigHash(); 12669 } 12670 12671 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 12672 int[] transports = nai.networkCapabilities.getTransportTypes(); 12673 mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype)); 12674 } 12675 12676 private static boolean toBool(int encodedBoolean) { 12677 return encodedBoolean != 0; // Only 0 means false. 12678 } 12679 12680 private static int encodeBool(boolean b) { 12681 return b ? 1 : 0; 12682 } 12683 12684 @Override 12685 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 12686 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 12687 @NonNull String[] args) { 12688 return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 12689 err.getFileDescriptor(), args); 12690 } 12691 12692 private class ShellCmd extends BasicShellCommandHandler { 12693 12694 private Boolean parseBooleanArgument(final String arg) { 12695 if ("true".equals(arg)) { 12696 return true; 12697 } else if ("false".equals(arg)) { 12698 return false; 12699 } else { 12700 getOutPrintWriter().println("Invalid boolean argument: " + arg); 12701 return null; 12702 } 12703 } 12704 12705 private Integer parseIntegerArgument(final String arg) { 12706 try { 12707 return Integer.valueOf(arg); 12708 } catch (NumberFormatException ne) { 12709 getOutPrintWriter().println("Invalid integer argument: " + arg); 12710 return null; 12711 } 12712 } 12713 12714 @Override 12715 public int onCommand(String cmd) { 12716 if (cmd == null) { 12717 return handleDefaultCommands(cmd); 12718 } 12719 final PrintWriter pw = getOutPrintWriter(); 12720 try { 12721 switch (cmd) { 12722 case "airplane-mode": 12723 // Usage : adb shell cmd connectivity airplane-mode [enable|disable] 12724 // If no argument, get and display the current status 12725 final String action = getNextArg(); 12726 if ("enable".equals(action)) { 12727 setAirplaneMode(true); 12728 return 0; 12729 } else if ("disable".equals(action)) { 12730 setAirplaneMode(false); 12731 return 0; 12732 } else if (action == null) { 12733 final ContentResolver cr = mContext.getContentResolver(); 12734 final int enabled = Settings.Global.getInt(cr, 12735 Settings.Global.AIRPLANE_MODE_ON); 12736 pw.println(enabled == 0 ? "disabled" : "enabled"); 12737 return 0; 12738 } else { 12739 onHelp(); 12740 return -1; 12741 } 12742 case "set-chain3-enabled": { 12743 final Boolean enabled = parseBooleanArgument(getNextArg()); 12744 if (null == enabled) { 12745 onHelp(); 12746 return -1; 12747 } 12748 Log.i(TAG, (enabled ? "En" : "Dis") + "abled FIREWALL_CHAIN_OEM_DENY_3"); 12749 setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, 12750 enabled); 12751 return 0; 12752 } 12753 case "get-chain3-enabled": { 12754 final boolean chainEnabled = getFirewallChainEnabled( 12755 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3); 12756 pw.println("chain:" + (chainEnabled ? "enabled" : "disabled")); 12757 return 0; 12758 } 12759 case "set-package-networking-enabled": { 12760 final Boolean enabled = parseBooleanArgument(getNextArg()); 12761 final String packageName = getNextArg(); 12762 if (null == enabled || null == packageName) { 12763 onHelp(); 12764 return -1; 12765 } 12766 // Throws NameNotFound if the package doesn't exist. 12767 final int appId = setPackageFirewallRule( 12768 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, 12769 packageName, enabled ? FIREWALL_RULE_DEFAULT : FIREWALL_RULE_DENY); 12770 final String msg = (enabled ? "Enabled" : "Disabled") 12771 + " networking for " + packageName + ", appId " + appId; 12772 Log.i(TAG, msg); 12773 pw.println(msg); 12774 return 0; 12775 } 12776 case "get-package-networking-enabled": { 12777 if (!mDeps.isAtLeastT()) { 12778 throw new UnsupportedOperationException( 12779 "This command is not supported on T-"); 12780 } 12781 final String packageName = getNextArg(); 12782 final int rule = getPackageFirewallRule( 12783 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, packageName); 12784 if (FIREWALL_RULE_ALLOW == rule || FIREWALL_RULE_DEFAULT == rule) { 12785 pw.println(packageName + ":" + "allow"); 12786 } else if (FIREWALL_RULE_DENY == rule) { 12787 pw.println(packageName + ":" + "deny"); 12788 } else { 12789 throw new IllegalStateException("Unknown rule " + rule + " for package " 12790 + packageName); 12791 } 12792 return 0; 12793 } 12794 case "set-background-networking-enabled-for-uid": { 12795 final Integer uid = parseIntegerArgument(getNextArg()); 12796 final Boolean enabled = parseBooleanArgument(getNextArg()); 12797 if (null == enabled || null == uid) { 12798 onHelp(); 12799 return -1; 12800 } 12801 final int rule = enabled ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DEFAULT; 12802 setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, rule); 12803 final String msg = (enabled ? "Enabled" : "Disabled") 12804 + " background networking for uid " + uid; 12805 Log.i(TAG, msg); 12806 pw.println(msg); 12807 return 0; 12808 } 12809 case "get-background-networking-enabled-for-uid": { 12810 if (!mDeps.isAtLeastT()) { 12811 throw new UnsupportedOperationException( 12812 "This command is not supported on T-"); 12813 } 12814 final Integer uid = parseIntegerArgument(getNextArg()); 12815 if (null == uid) { 12816 onHelp(); 12817 return -1; 12818 } 12819 final int rule = getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid); 12820 if (FIREWALL_RULE_ALLOW == rule) { 12821 pw.println(uid + ": allow"); 12822 } else if (FIREWALL_RULE_DENY == rule || FIREWALL_RULE_DEFAULT == rule) { 12823 pw.println(uid + ": deny"); 12824 } else { 12825 throw new IllegalStateException( 12826 "Unknown rule " + rule + " for uid " + uid); 12827 } 12828 return 0; 12829 } 12830 case "reevaluate": 12831 // Usage : adb shell cmd connectivity reevaluate <netId> 12832 // If netId is omitted, then reevaluate the default network 12833 final String netId = getNextArg(); 12834 final NetworkAgentInfo nai; 12835 if (null == netId) { 12836 // Note that the command is running on the wrong thread to call this, 12837 // so this could in principle return stale data. But it can't crash. 12838 nai = getDefaultNetwork(); 12839 } else { 12840 // If netId can't be parsed, this throws NumberFormatException, which 12841 // is passed back to adb who prints it. 12842 nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId)); 12843 } 12844 if (null == nai) { 12845 pw.println("Unknown network (net ID not found or no default network)"); 12846 return 0; 12847 } 12848 Log.d(TAG, "Reevaluating network " + nai.network); 12849 reportNetworkConnectivity(nai.network, !nai.isValidated()); 12850 return 0; 12851 case "bpf-get-cgroup-program-id": { 12852 // Usage : adb shell cmd connectivity bpf-get-cgroup-program-id <type> 12853 // Get cgroup bpf program Id for the given type. See BpfUtils#getProgramId 12854 // for more detail. 12855 // If type can't be parsed, this throws NumberFormatException, which 12856 // is passed back to adb who prints it. 12857 final int type = Integer.parseInt(getNextArg()); 12858 final int ret = BpfUtils.getProgramId(type); 12859 pw.println(ret); 12860 return 0; 12861 } 12862 default: 12863 return handleDefaultCommands(cmd); 12864 } 12865 } catch (Exception e) { 12866 pw.println(e); 12867 } 12868 return -1; 12869 } 12870 12871 @Override 12872 public void onHelp() { 12873 PrintWriter pw = getOutPrintWriter(); 12874 pw.println("Connectivity service commands:"); 12875 pw.println(" help"); 12876 pw.println(" Print this help text."); 12877 pw.println(" airplane-mode [enable|disable]"); 12878 pw.println(" Turn airplane mode on or off."); 12879 pw.println(" airplane-mode"); 12880 pw.println(" Get airplane mode."); 12881 pw.println(" set-chain3-enabled [true|false]"); 12882 pw.println(" Enable or disable FIREWALL_CHAIN_OEM_DENY_3 for debugging."); 12883 pw.println(" get-chain3-enabled"); 12884 pw.println(" Returns whether FIREWALL_CHAIN_OEM_DENY_3 is enabled."); 12885 pw.println(" set-package-networking-enabled [true|false] [package name]"); 12886 pw.println(" Set the deny bit in FIREWALL_CHAIN_OEM_DENY_3 to package. This has\n" 12887 + " no effect if the chain is disabled."); 12888 pw.println(" get-package-networking-enabled [package name]"); 12889 pw.println(" Get the deny bit in FIREWALL_CHAIN_OEM_DENY_3 for package."); 12890 pw.println(" set-background-networking-enabled-for-uid [uid] [true|false]"); 12891 pw.println(" Set the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); 12892 pw.println(" get-background-networking-enabled-for-uid [uid]"); 12893 pw.println(" Get the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); 12894 } 12895 } 12896 12897 private int getVpnType(@Nullable NetworkAgentInfo vpn) { 12898 if (vpn == null) return VpnManager.TYPE_VPN_NONE; 12899 final TransportInfo ti = vpn.networkCapabilities.getTransportInfo(); 12900 if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE; 12901 return ((VpnTransportInfo) ti).getType(); 12902 } 12903 12904 private boolean isVpnServiceVpn(NetworkAgentInfo nai) { 12905 final int vpnType = getVpnType(nai); 12906 return vpnType == VpnManager.TYPE_VPN_SERVICE || vpnType == VpnManager.TYPE_VPN_OEM_SERVICE; 12907 } 12908 12909 private boolean isLegacyVpn(NetworkAgentInfo nai) { 12910 final int vpnType = getVpnType(nai); 12911 return vpnType == VpnManager.TYPE_VPN_LEGACY || vpnType == VpnManager.TYPE_VPN_OEM_LEGACY; 12912 } 12913 12914 private boolean vpnSupportsInterfaceFiltering(NetworkAgentInfo vpn) { 12915 final int vpnType = getVpnType(vpn); 12916 return vpnType != VpnManager.TYPE_VPN_LEGACY 12917 && vpnType != VpnManager.TYPE_VPN_OEM 12918 && vpnType != VpnManager.TYPE_VPN_OEM_LEGACY; 12919 } 12920 12921 private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai, 12922 @NonNull NetworkCapabilities nc) { 12923 final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo(); 12924 final TransportInfo newInfo = nc.getTransportInfo(); 12925 if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) { 12926 return; 12927 } 12928 if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) { 12929 nai.lastRoamTime = SystemClock.elapsedRealtime(); 12930 } 12931 } 12932 12933 /** 12934 * @param connectionInfo the connection to resolve. 12935 * @return {@code uid} if the connection is found and the app has permission to observe it 12936 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the 12937 * connection is not found. 12938 */ 12939 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { 12940 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { 12941 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); 12942 } 12943 12944 final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol, 12945 connectionInfo.local, connectionInfo.remote); 12946 12947 if (uid == INVALID_UID) return uid; // Not found. 12948 12949 // Connection owner UIDs are visible only to the network stack and to the VpnService-based 12950 // VPN, if any, that applies to the UID that owns the connection. 12951 if (hasNetworkStackPermission()) return uid; 12952 12953 final NetworkAgentInfo vpn = getVpnForUid(uid); 12954 if (vpn == null || !isVpnServiceVpn(vpn) 12955 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) { 12956 return INVALID_UID; 12957 } 12958 12959 return uid; 12960 } 12961 12962 /** 12963 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. 12964 * 12965 * <p>The TestNetworkService must be run in the system server due to TUN creation. 12966 */ 12967 @Override 12968 public IBinder startOrGetTestNetworkService() { 12969 synchronized (mTNSLock) { 12970 TestNetworkService.enforceTestNetworkPermissions(mContext); 12971 12972 if (mTNS == null) { 12973 mTNS = new TestNetworkService(mContext); 12974 } 12975 12976 return mTNS; 12977 } 12978 } 12979 12980 /** 12981 * Handler used for managing all Connectivity Diagnostics related functions. 12982 * 12983 * @see android.net.ConnectivityDiagnosticsManager 12984 * 12985 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file 12986 */ 12987 @VisibleForTesting 12988 class ConnectivityDiagnosticsHandler extends Handler { 12989 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName(); 12990 12991 /** 12992 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link 12993 * android.net.ConnectivityDiagnosticsManager}. 12994 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and 12995 * NetworkRequestInfo to be registered 12996 */ 12997 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1; 12998 12999 /** 13000 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link 13001 * android.net.ConnectivityDiagnosticsManager}. 13002 * obj = the IConnectivityDiagnosticsCallback to be unregistered 13003 * arg1 = the uid of the caller 13004 */ 13005 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2; 13006 13007 /** 13008 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks 13009 * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events. 13010 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from 13011 * NetworkMonitor. 13012 * data = PersistableBundle of extras passed from NetworkMonitor. 13013 */ 13014 private static final int CMD_SEND_CONNECTIVITY_REPORT = 3; 13015 13016 /** 13017 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has 13018 * been detected on the network. 13019 * obj = Long the timestamp (in millis) for when the suspected data stall was detected. 13020 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method. 13021 * arg2 = NetID. 13022 * data = PersistableBundle of extras passed from NetworkMonitor. 13023 */ 13024 private static final int EVENT_DATA_STALL_SUSPECTED = 4; 13025 13026 /** 13027 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to 13028 * the platform. This event will invoke {@link 13029 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned 13030 * callbacks. 13031 * obj = ReportedNetworkConnectivityInfo with info on reported Network connectivity. 13032 */ 13033 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5; 13034 13035 private ConnectivityDiagnosticsHandler(Looper looper) { 13036 super(looper); 13037 } 13038 13039 @Override 13040 public void handleMessage(Message msg) { 13041 switch (msg.what) { 13042 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 13043 handleRegisterConnectivityDiagnosticsCallback( 13044 (ConnectivityDiagnosticsCallbackInfo) msg.obj); 13045 break; 13046 } 13047 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 13048 handleUnregisterConnectivityDiagnosticsCallback( 13049 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1); 13050 break; 13051 } 13052 case CMD_SEND_CONNECTIVITY_REPORT: { 13053 final ConnectivityReportEvent reportEvent = 13054 (ConnectivityReportEvent) msg.obj; 13055 13056 handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras); 13057 break; 13058 } 13059 case EVENT_DATA_STALL_SUSPECTED: { 13060 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 13061 final Pair<Long, PersistableBundle> arg = 13062 (Pair<Long, PersistableBundle>) msg.obj; 13063 if (nai == null) break; 13064 13065 handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second); 13066 break; 13067 } 13068 case EVENT_NETWORK_CONNECTIVITY_REPORTED: { 13069 handleNetworkConnectivityReported((ReportedNetworkConnectivityInfo) msg.obj); 13070 break; 13071 } 13072 default: { 13073 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what); 13074 } 13075 } 13076 } 13077 } 13078 13079 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */ 13080 @VisibleForTesting 13081 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient { 13082 @NonNull private final IConnectivityDiagnosticsCallback mCb; 13083 @NonNull private final NetworkRequestInfo mRequestInfo; 13084 @NonNull private final String mCallingPackageName; 13085 13086 @VisibleForTesting 13087 ConnectivityDiagnosticsCallbackInfo( 13088 @NonNull IConnectivityDiagnosticsCallback cb, 13089 @NonNull NetworkRequestInfo nri, 13090 @NonNull String callingPackageName) { 13091 mCb = cb; 13092 mRequestInfo = nri; 13093 mCallingPackageName = callingPackageName; 13094 } 13095 13096 @Override 13097 public void binderDied() { 13098 log("ConnectivityDiagnosticsCallback IBinder died."); 13099 unregisterConnectivityDiagnosticsCallback(mCb); 13100 } 13101 } 13102 13103 /** 13104 * Class used for sending information from {@link 13105 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it. 13106 */ 13107 private static class NetworkTestedResults { 13108 private final int mNetId; 13109 private final int mTestResult; 13110 @Nullable private final String mRedirectUrl; 13111 13112 private NetworkTestedResults( 13113 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) { 13114 mNetId = netId; 13115 mTestResult = testResult; 13116 mRedirectUrl = redirectUrl; 13117 } 13118 } 13119 13120 /** 13121 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link 13122 * ConnectivityDiagnosticsHandler}. 13123 */ 13124 private static class ConnectivityReportEvent { 13125 private final long mTimestampMillis; 13126 @NonNull private final NetworkAgentInfo mNai; 13127 private final PersistableBundle mExtras; 13128 13129 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, 13130 PersistableBundle p) { 13131 mTimestampMillis = timestampMillis; 13132 mNai = nai; 13133 mExtras = p; 13134 } 13135 } 13136 13137 /** 13138 * Class used for sending info for a call to {@link #reportNetworkConnectivity()} to {@link 13139 * ConnectivityDiagnosticsHandler}. 13140 */ 13141 private static class ReportedNetworkConnectivityInfo { 13142 public final boolean hasConnectivity; 13143 public final boolean isNetworkRevalidating; 13144 public final int reporterUid; 13145 @NonNull public final NetworkAgentInfo nai; 13146 13147 private ReportedNetworkConnectivityInfo( 13148 boolean hasConnectivity, 13149 boolean isNetworkRevalidating, 13150 int reporterUid, 13151 @NonNull NetworkAgentInfo nai) { 13152 this.hasConnectivity = hasConnectivity; 13153 this.isNetworkRevalidating = isNetworkRevalidating; 13154 this.reporterUid = reporterUid; 13155 this.nai = nai; 13156 } 13157 } 13158 13159 private void handleRegisterConnectivityDiagnosticsCallback( 13160 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) { 13161 ensureRunningOnConnectivityServiceThread(); 13162 13163 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb; 13164 final IBinder iCb = cb.asBinder(); 13165 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 13166 13167 // Connectivity Diagnostics are meant to be used with a single network request. It would be 13168 // confusing for these networks to change when an NRI is satisfied in another layer. 13169 if (nri.isMultilayerRequest()) { 13170 throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer " 13171 + "network requests."); 13172 } 13173 13174 // This means that the client registered the same callback multiple times. Do 13175 // not override the previous entry, and exit silently. 13176 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) { 13177 if (VDBG) log("Diagnostics callback is already registered"); 13178 13179 // Decrement the reference count for this NetworkRequestInfo. The reference count is 13180 // incremented when the NetworkRequestInfo is created as part of 13181 // enforceRequestCountLimit(). 13182 nri.mPerUidCounter.decrementCount(nri.mUid); 13183 return; 13184 } 13185 13186 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo); 13187 13188 try { 13189 iCb.linkToDeath(cbInfo, 0); 13190 } catch (RemoteException e) { 13191 cbInfo.binderDied(); 13192 return; 13193 } 13194 13195 // Once registered, provide ConnectivityReports for matching Networks 13196 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>(); 13197 synchronized (mNetworkForNetId) { 13198 for (int i = 0; i < mNetworkForNetId.size(); i++) { 13199 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 13200 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0) 13201 if (nai.satisfies(nri.mRequests.get(0))) { 13202 matchingNetworks.add(nai); 13203 } 13204 } 13205 } 13206 for (final NetworkAgentInfo nai : matchingNetworks) { 13207 final ConnectivityReport report = nai.getConnectivityReport(); 13208 if (report == null) { 13209 continue; 13210 } 13211 if (!hasConnectivityDiagnosticsPermissions( 13212 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 13213 continue; 13214 } 13215 13216 try { 13217 cb.onConnectivityReportAvailable(report); 13218 } catch (RemoteException e) { 13219 // Exception while sending the ConnectivityReport. Move on to the next network. 13220 } 13221 } 13222 } 13223 13224 private void handleUnregisterConnectivityDiagnosticsCallback( 13225 @NonNull IConnectivityDiagnosticsCallback cb, int uid) { 13226 ensureRunningOnConnectivityServiceThread(); 13227 final IBinder iCb = cb.asBinder(); 13228 13229 final ConnectivityDiagnosticsCallbackInfo cbInfo = 13230 mConnectivityDiagnosticsCallbacks.remove(iCb); 13231 if (cbInfo == null) { 13232 if (VDBG) log("Removing diagnostics callback that is not currently registered"); 13233 return; 13234 } 13235 13236 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 13237 13238 // Caller's UID must either be the registrants (if they are unregistering) or the System's 13239 // (if the Binder died) 13240 if (uid != nri.mUid && uid != Process.SYSTEM_UID) { 13241 if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's"); 13242 return; 13243 } 13244 13245 // Decrement the reference count for this NetworkRequestInfo. The reference count is 13246 // incremented when the NetworkRequestInfo is created as part of 13247 // enforceRequestCountLimit(). 13248 nri.mPerUidCounter.decrementCount(nri.mUid); 13249 13250 iCb.unlinkToDeath(cbInfo, 0); 13251 } 13252 13253 private void handleNetworkTestedWithExtras( 13254 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) { 13255 final NetworkAgentInfo nai = reportEvent.mNai; 13256 final NetworkCapabilities networkCapabilities = 13257 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 13258 final ConnectivityReport report = 13259 new ConnectivityReport( 13260 reportEvent.mNai.network, 13261 reportEvent.mTimestampMillis, 13262 nai.linkProperties, 13263 networkCapabilities, 13264 extras); 13265 nai.setConnectivityReport(report); 13266 13267 final List<IConnectivityDiagnosticsCallback> results = 13268 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 13269 for (final IConnectivityDiagnosticsCallback cb : results) { 13270 try { 13271 cb.onConnectivityReportAvailable(report); 13272 } catch (RemoteException ex) { 13273 loge("Error invoking onConnectivityReportAvailable", ex); 13274 } 13275 } 13276 } 13277 13278 private void handleDataStallSuspected( 13279 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, 13280 @NonNull PersistableBundle extras) { 13281 final NetworkCapabilities networkCapabilities = 13282 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 13283 final DataStallReport report = 13284 new DataStallReport( 13285 nai.network, 13286 timestampMillis, 13287 detectionMethod, 13288 nai.linkProperties, 13289 networkCapabilities, 13290 extras); 13291 final List<IConnectivityDiagnosticsCallback> results = 13292 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 13293 for (final IConnectivityDiagnosticsCallback cb : results) { 13294 try { 13295 cb.onDataStallSuspected(report); 13296 } catch (RemoteException ex) { 13297 loge("Error invoking onDataStallSuspected", ex); 13298 } 13299 } 13300 } 13301 13302 private void handleNetworkConnectivityReported( 13303 @NonNull ReportedNetworkConnectivityInfo reportedNetworkConnectivityInfo) { 13304 final NetworkAgentInfo nai = reportedNetworkConnectivityInfo.nai; 13305 final ConnectivityReport cachedReport = nai.getConnectivityReport(); 13306 13307 // If the Network is being re-validated as a result of this call to 13308 // reportNetworkConnectivity(), notify all permissioned callbacks. Otherwise, only notify 13309 // permissioned callbacks registered by the reporter. 13310 final List<IConnectivityDiagnosticsCallback> results = 13311 getMatchingPermissionedCallbacks( 13312 nai, 13313 reportedNetworkConnectivityInfo.isNetworkRevalidating 13314 ? Process.INVALID_UID 13315 : reportedNetworkConnectivityInfo.reporterUid); 13316 13317 for (final IConnectivityDiagnosticsCallback cb : results) { 13318 try { 13319 cb.onNetworkConnectivityReported( 13320 nai.network, reportedNetworkConnectivityInfo.hasConnectivity); 13321 } catch (RemoteException ex) { 13322 loge("Error invoking onNetworkConnectivityReported", ex); 13323 } 13324 13325 // If the Network isn't re-validating, also provide the cached report. If there is no 13326 // cached report, the Network is still being validated and a report will be sent once 13327 // validation is complete. Note that networks which never undergo validation will still 13328 // have a cached ConnectivityReport with RESULT_SKIPPED. 13329 if (!reportedNetworkConnectivityInfo.isNetworkRevalidating && cachedReport != null) { 13330 try { 13331 cb.onConnectivityReportAvailable(cachedReport); 13332 } catch (RemoteException ex) { 13333 loge("Error invoking onConnectivityReportAvailable", ex); 13334 } 13335 } 13336 } 13337 } 13338 13339 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) { 13340 final NetworkCapabilities sanitized = new NetworkCapabilities(nc, 13341 NetworkCapabilities.REDACT_ALL); 13342 sanitized.setUids(null); 13343 sanitized.setAdministratorUids(new int[0]); 13344 sanitized.setOwnerUid(Process.INVALID_UID); 13345 return sanitized; 13346 } 13347 13348 /** 13349 * Gets a list of ConnectivityDiagnostics callbacks that match the specified Network and uid. 13350 * 13351 * <p>If Process.INVALID_UID is specified, all matching callbacks will be returned. 13352 */ 13353 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks( 13354 @NonNull NetworkAgentInfo nai, int uid) { 13355 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); 13356 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry : 13357 mConnectivityDiagnosticsCallbacks.entrySet()) { 13358 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue(); 13359 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 13360 13361 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0). 13362 if (!nai.satisfies(nri.mRequests.get(0))) { 13363 continue; 13364 } 13365 13366 // UID for this callback must either be: 13367 // - INVALID_UID (which sends callbacks to all UIDs), or 13368 // - The callback's owner (the owner called reportNetworkConnectivity() and is being 13369 // notified as a result) 13370 if (uid != Process.INVALID_UID && uid != nri.mUid) { 13371 continue; 13372 } 13373 13374 if (!hasConnectivityDiagnosticsPermissions( 13375 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 13376 continue; 13377 } 13378 13379 results.add(entry.getValue().mCb); 13380 } 13381 return results; 13382 } 13383 13384 private boolean isLocationPermissionRequiredForConnectivityDiagnostics( 13385 @NonNull NetworkAgentInfo nai) { 13386 // TODO(b/188483916): replace with a transport-agnostic location-aware check 13387 return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI); 13388 } 13389 13390 private boolean hasLocationPermission(String packageName, int uid) { 13391 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid 13392 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the 13393 // call in a try-catch. 13394 try { 13395 if (!mLocationPermissionChecker.checkLocationPermission( 13396 packageName, null /* featureId */, uid, null /* message */)) { 13397 return false; 13398 } 13399 } catch (SecurityException e) { 13400 return false; 13401 } 13402 13403 return true; 13404 } 13405 13406 private boolean ownsVpnRunningOverNetwork(int uid, Network network) { 13407 return anyNetworkAgentInfo(virtual -> 13408 virtual.propagateUnderlyingCapabilities() 13409 && virtual.networkCapabilities.getOwnerUid() == uid 13410 && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)); 13411 } 13412 13413 @CheckResult 13414 @VisibleForTesting 13415 boolean hasConnectivityDiagnosticsPermissions( 13416 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) { 13417 if (hasNetworkStackPermission(callbackPid, callbackUid)) { 13418 return true; 13419 } 13420 if (mAllowSysUiConnectivityReports 13421 && hasSystemBarServicePermission(callbackPid, callbackUid)) { 13422 return true; 13423 } 13424 13425 // Administrator UIDs also contains the Owner UID 13426 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); 13427 if (!CollectionUtils.contains(administratorUids, callbackUid) 13428 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) { 13429 return false; 13430 } 13431 13432 return !isLocationPermissionRequiredForConnectivityDiagnostics(nai) 13433 || hasLocationPermission(callbackPackageName, callbackUid); 13434 } 13435 13436 @Override 13437 public void registerConnectivityDiagnosticsCallback( 13438 @NonNull IConnectivityDiagnosticsCallback callback, 13439 @NonNull NetworkRequest request, 13440 @NonNull String callingPackageName) { 13441 Objects.requireNonNull(callback, "callback must not be null"); 13442 Objects.requireNonNull(request, "request must not be null"); 13443 Objects.requireNonNull(callingPackageName, "callingPackageName must not be null"); 13444 13445 if (request.legacyType != TYPE_NONE) { 13446 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." 13447 + " Please use NetworkCapabilities instead."); 13448 } 13449 final int callingUid = mDeps.getCallingUid(); 13450 mAppOpsManager.checkPackage(callingUid, callingPackageName); 13451 13452 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid 13453 // and administrator uids to be safe. 13454 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); 13455 restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName); 13456 13457 final NetworkRequest requestWithId = 13458 new NetworkRequest( 13459 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); 13460 13461 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit. 13462 // 13463 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in 13464 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the 13465 // callback's binder death. 13466 final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId); 13467 nri.mPerUidCounter.incrementCountOrThrow(nri.mUid); 13468 final ConnectivityDiagnosticsCallbackInfo cbInfo = 13469 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName); 13470 13471 mConnectivityDiagnosticsHandler.sendMessage( 13472 mConnectivityDiagnosticsHandler.obtainMessage( 13473 ConnectivityDiagnosticsHandler 13474 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 13475 cbInfo)); 13476 } 13477 13478 @Override 13479 public void unregisterConnectivityDiagnosticsCallback( 13480 @NonNull IConnectivityDiagnosticsCallback callback) { 13481 Objects.requireNonNull(callback, "callback must be non-null"); 13482 mConnectivityDiagnosticsHandler.sendMessage( 13483 mConnectivityDiagnosticsHandler.obtainMessage( 13484 ConnectivityDiagnosticsHandler 13485 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 13486 mDeps.getCallingUid(), 13487 0, 13488 callback)); 13489 } 13490 13491 private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) { 13492 final List<Network> underlyingNetworks = nc.getUnderlyingNetworks(); 13493 if (underlyingNetworks == null) return false; 13494 13495 for (Network network : underlyingNetworks) { 13496 if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) { 13497 return true; 13498 } 13499 } 13500 return false; 13501 } 13502 13503 @Override 13504 public void simulateDataStall(int detectionMethod, long timestampMillis, 13505 @NonNull Network network, @NonNull PersistableBundle extras) { 13506 Objects.requireNonNull(network, "network must not be null"); 13507 Objects.requireNonNull(extras, "extras must not be null"); 13508 13509 enforceAnyPermissionOf(mContext, 13510 android.Manifest.permission.MANAGE_TEST_NETWORKS, 13511 android.Manifest.permission.NETWORK_STACK); 13512 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 13513 if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) { 13514 throw new SecurityException( 13515 "Data Stall simulation is only possible for test networks or networks built on" 13516 + " top of test networks"); 13517 } 13518 13519 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 13520 if (nai == null 13521 || (nai.creatorUid != mDeps.getCallingUid() 13522 && nai.creatorUid != Process.SYSTEM_UID)) { 13523 throw new SecurityException( 13524 "Data Stall simulation is only possible for network " + "creators"); 13525 } 13526 13527 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat 13528 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the 13529 // Data Stall information as a DataStallReportParcelable and passing to 13530 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are 13531 // still passed to ConnectivityDiagnostics (with new detection methods masked). 13532 final DataStallReportParcelable p = new DataStallReportParcelable(); 13533 p.timestampMillis = timestampMillis; 13534 p.detectionMethod = detectionMethod; 13535 13536 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 13537 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS); 13538 } 13539 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 13540 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE); 13541 p.tcpMetricsCollectionPeriodMillis = extras.getInt( 13542 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS); 13543 } 13544 13545 notifyDataStallSuspected(p, network.getNetId()); 13546 } 13547 13548 /** 13549 * Class to hold the information for network activity change event from idle timers 13550 * {@link NetdCallback#onInterfaceClassActivityChanged(boolean, int, long, int)} 13551 */ 13552 private static final class NetworkActivityParams { 13553 public final boolean isActive; 13554 // If TrackMultiNetworkActivities is enabled, idleTimer label is netid. 13555 // If TrackMultiNetworkActivities is disabled, idleTimer label is transport type. 13556 public final int label; 13557 public final long timestampNs; 13558 // Uid represents the uid that was responsible for waking the radio. 13559 // -1 for no uid and uid is -1 if isActive is false. 13560 public final int uid; 13561 13562 NetworkActivityParams(boolean isActive, int label, long timestampNs, int uid) { 13563 this.isActive = isActive; 13564 this.label = label; 13565 this.timestampNs = timestampNs; 13566 this.uid = uid; 13567 } 13568 } 13569 13570 private class NetdCallback extends BaseNetdUnsolicitedEventListener { 13571 @Override 13572 public void onInterfaceClassActivityChanged(boolean isActive, int label, 13573 long timestampNs, int uid) { 13574 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY, 13575 new NetworkActivityParams(isActive, label, timestampNs, uid))); 13576 } 13577 13578 @Override 13579 public void onInterfaceLinkStateChanged(@NonNull String iface, boolean up) { 13580 mHandler.post(() -> { 13581 forEachNetworkAgentInfo(nai -> 13582 nai.clatd.handleInterfaceLinkStateChanged(iface, up)); 13583 }); 13584 } 13585 13586 @Override 13587 public void onInterfaceRemoved(@NonNull String iface) { 13588 mHandler.post(() -> { 13589 forEachNetworkAgentInfo(nai -> 13590 nai.clatd.handleInterfaceRemoved(iface)); 13591 }); 13592 } 13593 } 13594 13595 private final boolean mTrackMultiNetworkActivities; 13596 private final LegacyNetworkActivityTracker mNetworkActivityTracker; 13597 13598 /** 13599 * Class used for updating network activity tracking with netd and notify network activity 13600 * changes. 13601 */ 13602 @VisibleForTesting 13603 public static final class LegacyNetworkActivityTracker { 13604 private static final int NO_UID = -1; 13605 private final Context mContext; 13606 private final INetd mNetd; 13607 private final Handler mHandler; 13608 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 13609 new RemoteCallbackList<>(); 13610 // Indicate the current system default network activity is active or not. 13611 // This needs to be volatile to allow non handler threads to read this value without lock. 13612 // If there is no default network, default network is considered active to keep the existing 13613 // behavior. Initial value is used until first connect to the default network. 13614 private volatile boolean mIsDefaultNetworkActive = true; 13615 private Network mDefaultNetwork; 13616 // Key is netId. Value is configured idle timer information. 13617 private final SparseArray<IdleTimerParams> mActiveIdleTimers = new SparseArray<>(); 13618 private final boolean mTrackMultiNetworkActivities; 13619 private final int mDefaultCellularDataInactivityTimeout; 13620 private final int mDefaultWifiDataInactivityTimeout; 13621 // Store netIds of Wi-Fi networks whose idletimers report that they are active 13622 private final Set<Integer> mActiveWifiNetworks = new ArraySet<>(); 13623 // Store netIds of cellular networks whose idletimers report that they are active 13624 private final Set<Integer> mActiveCellularNetworks = new ArraySet<>(); 13625 13626 private static class IdleTimerParams { 13627 public final int timeout; 13628 public final int transportType; 13629 13630 IdleTimerParams(int timeout, int transport) { 13631 this.timeout = timeout; 13632 this.transportType = transport; 13633 } 13634 } 13635 13636 LegacyNetworkActivityTracker(@NonNull Context context, @NonNull INetd netd, 13637 @NonNull Handler handler, boolean trackMultiNetworkActivities, 13638 int defaultCellularDataInactivityTimeout, int defaultWifiDataInactivityTimeout) { 13639 mContext = context; 13640 mNetd = netd; 13641 mHandler = handler; 13642 mTrackMultiNetworkActivities = trackMultiNetworkActivities; 13643 mDefaultCellularDataInactivityTimeout = defaultCellularDataInactivityTimeout; 13644 mDefaultWifiDataInactivityTimeout = defaultWifiDataInactivityTimeout; 13645 } 13646 13647 private void ensureRunningOnConnectivityServiceThread() { 13648 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 13649 } 13650 13651 /** 13652 * Update network activity and call BatteryStats to update radio power state if the 13653 * mobile or Wi-Fi activity is changed. 13654 * LegacyNetworkActivityTracker considers the mobile network is active if at least one 13655 * mobile network is active since BatteryStatsService only maintains a single power state 13656 * for the mobile network. 13657 * The Wi-Fi network is also the same. 13658 * 13659 * {@link #setupDataActivityTracking} and {@link #removeDataActivityTracking} use 13660 * TRANSPORT_CELLULAR as the transportType argument if the network has both cell and Wi-Fi 13661 * transports. 13662 */ 13663 private void maybeUpdateRadioPowerState(final int netId, final int transportType, 13664 final boolean isActive, final int uid) { 13665 if (transportType != TRANSPORT_WIFI && transportType != TRANSPORT_CELLULAR) { 13666 Log.e(TAG, "Unexpected transportType in maybeUpdateRadioPowerState: " 13667 + transportType); 13668 return; 13669 } 13670 final Set<Integer> activeNetworks = transportType == TRANSPORT_WIFI 13671 ? mActiveWifiNetworks : mActiveCellularNetworks; 13672 13673 final boolean wasEmpty = activeNetworks.isEmpty(); 13674 if (isActive) { 13675 activeNetworks.add(netId); 13676 } else { 13677 activeNetworks.remove(netId); 13678 } 13679 13680 if (wasEmpty != activeNetworks.isEmpty()) { 13681 updateRadioPowerState(isActive, transportType, uid); 13682 } 13683 } 13684 13685 private void handleDefaultNetworkActivity(final int transportType, 13686 final boolean isActive, final long timestampNs) { 13687 mIsDefaultNetworkActive = isActive; 13688 sendDataActivityBroadcast(transportTypeToLegacyType(transportType), 13689 isActive, timestampNs); 13690 if (isActive) { 13691 reportNetworkActive(); 13692 } 13693 } 13694 13695 private void handleReportNetworkActivityWithNetIdLabel( 13696 NetworkActivityParams activityParams) { 13697 final int netId = activityParams.label; 13698 final IdleTimerParams idleTimerParams = mActiveIdleTimers.get(netId); 13699 if (idleTimerParams == null) { 13700 // This network activity change is not tracked anymore 13701 // This can happen if netd callback post activity change event message but idle 13702 // timer is removed before processing this message. 13703 return; 13704 } 13705 // TODO: if a network changes transports, storing the transport type in the 13706 // IdleTimerParams is not correct. Consider getting it from the network's 13707 // NetworkCapabilities instead. 13708 final int transportType = idleTimerParams.transportType; 13709 maybeUpdateRadioPowerState(netId, transportType, 13710 activityParams.isActive, activityParams.uid); 13711 13712 if (mDefaultNetwork == null || mDefaultNetwork.netId != netId) { 13713 // This activity change is not for the default network. 13714 return; 13715 } 13716 13717 handleDefaultNetworkActivity(transportType, activityParams.isActive, 13718 activityParams.timestampNs); 13719 } 13720 13721 private void handleReportNetworkActivityWithTransportTypeLabel( 13722 NetworkActivityParams activityParams) { 13723 if (mActiveIdleTimers.size() == 0) { 13724 // This activity change is not for the current default network. 13725 // This can happen if netd callback post activity change event message but 13726 // the default network is lost before processing this message. 13727 return; 13728 } 13729 handleDefaultNetworkActivity(activityParams.label, activityParams.isActive, 13730 activityParams.timestampNs); 13731 } 13732 13733 /** 13734 * Handle network activity change 13735 */ 13736 public void handleReportNetworkActivity(NetworkActivityParams activityParams) { 13737 ensureRunningOnConnectivityServiceThread(); 13738 if (mTrackMultiNetworkActivities) { 13739 handleReportNetworkActivityWithNetIdLabel(activityParams); 13740 } else { 13741 handleReportNetworkActivityWithTransportTypeLabel(activityParams); 13742 } 13743 } 13744 13745 private void reportNetworkActive() { 13746 final int length = mNetworkActivityListeners.beginBroadcast(); 13747 if (DDBG) log("reportNetworkActive, notify " + length + " listeners"); 13748 try { 13749 for (int i = 0; i < length; i++) { 13750 try { 13751 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 13752 } catch (RemoteException | RuntimeException e) { 13753 loge("Fail to send network activity to listener " + e); 13754 } 13755 } 13756 } finally { 13757 mNetworkActivityListeners.finishBroadcast(); 13758 } 13759 } 13760 13761 // This is deprecated and only to support legacy use cases. 13762 private int transportTypeToLegacyType(int type) { 13763 switch (type) { 13764 case NetworkCapabilities.TRANSPORT_CELLULAR: 13765 return TYPE_MOBILE; 13766 case NetworkCapabilities.TRANSPORT_WIFI: 13767 return TYPE_WIFI; 13768 case NetworkCapabilities.TRANSPORT_BLUETOOTH: 13769 return TYPE_BLUETOOTH; 13770 case NetworkCapabilities.TRANSPORT_ETHERNET: 13771 return TYPE_ETHERNET; 13772 default: 13773 loge("Unexpected transport in transportTypeToLegacyType: " + type); 13774 } 13775 return ConnectivityManager.TYPE_NONE; 13776 } 13777 13778 public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 13779 final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 13780 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 13781 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 13782 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 13783 final long ident = Binder.clearCallingIdentity(); 13784 try { 13785 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 13786 RECEIVE_DATA_ACTIVITY_CHANGE, 13787 null /* resultReceiver */, 13788 null /* scheduler */, 13789 0 /* initialCode */, 13790 null /* initialData */, 13791 null /* initialExtra */); 13792 } finally { 13793 Binder.restoreCallingIdentity(ident); 13794 } 13795 } 13796 13797 /** 13798 * Get idle timer label 13799 */ 13800 @VisibleForTesting 13801 public static int getIdleTimerLabel(final boolean trackMultiNetworkActivities, 13802 final int netId, final int transportType) { 13803 return trackMultiNetworkActivities ? netId : transportType; 13804 } 13805 13806 private boolean maybeCreateIdleTimer( 13807 String iface, int netId, int timeout, int transportType) { 13808 if (timeout <= 0 || iface == null) return false; 13809 try { 13810 final String label = Integer.toString(getIdleTimerLabel( 13811 mTrackMultiNetworkActivities, netId, transportType)); 13812 mNetd.idletimerAddInterface(iface, timeout, label); 13813 mActiveIdleTimers.put(netId, new IdleTimerParams(timeout, transportType)); 13814 return true; 13815 } catch (Exception e) { 13816 loge("Exception in createIdleTimer", e); 13817 return false; 13818 } 13819 } 13820 13821 /** 13822 * Setup data activity tracking for the given network. 13823 * 13824 * Every {@code setupDataActivityTracking} should be paired with a 13825 * {@link #removeDataActivityTracking} for cleanup. 13826 * 13827 * @return true if the idleTimer is added to the network, false otherwise 13828 */ 13829 private boolean setupDataActivityTracking(NetworkAgentInfo networkAgent) { 13830 ensureRunningOnConnectivityServiceThread(); 13831 final String iface = networkAgent.linkProperties.getInterfaceName(); 13832 final int netId = networkAgent.network().netId; 13833 13834 final int timeout; 13835 final int type; 13836 13837 if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) { 13838 // Do not track VPN network. 13839 return false; 13840 } else if (networkAgent.networkCapabilities.hasTransport( 13841 NetworkCapabilities.TRANSPORT_CELLULAR)) { 13842 timeout = Settings.Global.getInt(mContext.getContentResolver(), 13843 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE, 13844 mDefaultCellularDataInactivityTimeout); 13845 type = NetworkCapabilities.TRANSPORT_CELLULAR; 13846 } else if (networkAgent.networkCapabilities.hasTransport( 13847 NetworkCapabilities.TRANSPORT_WIFI)) { 13848 timeout = Settings.Global.getInt(mContext.getContentResolver(), 13849 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI, 13850 mDefaultWifiDataInactivityTimeout); 13851 type = NetworkCapabilities.TRANSPORT_WIFI; 13852 } else { 13853 return false; // do not track any other networks 13854 } 13855 13856 final boolean hasIdleTimer = maybeCreateIdleTimer(iface, netId, timeout, type); 13857 if (hasIdleTimer || !mTrackMultiNetworkActivities) { 13858 // If trackMultiNetwork is disabled, NetworkActivityTracker updates radio power 13859 // state in all cases. If trackMultiNetwork is enabled, it updates radio power 13860 // state only about a network that has an idletimer. 13861 maybeUpdateRadioPowerState(netId, type, true /* isActive */, NO_UID); 13862 } 13863 return hasIdleTimer; 13864 } 13865 13866 /** 13867 * Remove data activity tracking when network disconnects. 13868 */ 13869 public void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 13870 ensureRunningOnConnectivityServiceThread(); 13871 final String iface = networkAgent.linkProperties.getInterfaceName(); 13872 final int netId = networkAgent.network().netId; 13873 final NetworkCapabilities caps = networkAgent.networkCapabilities; 13874 13875 if (iface == null) return; 13876 13877 final int type; 13878 if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) { 13879 // Do not track VPN network. 13880 return; 13881 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { 13882 type = NetworkCapabilities.TRANSPORT_CELLULAR; 13883 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 13884 type = NetworkCapabilities.TRANSPORT_WIFI; 13885 } else { 13886 return; // do not track any other networks 13887 } 13888 13889 try { 13890 maybeUpdateRadioPowerState(netId, type, false /* isActive */, NO_UID); 13891 final IdleTimerParams params = mActiveIdleTimers.get(netId); 13892 if (params == null) { 13893 // IdleTimer is not added if the configured timeout is 0 or negative value 13894 return; 13895 } 13896 mActiveIdleTimers.remove(netId); 13897 final String label = Integer.toString(getIdleTimerLabel( 13898 mTrackMultiNetworkActivities, netId, params.transportType)); 13899 // The call fails silently if no idle timer setup for this interface 13900 mNetd.idletimerRemoveInterface(iface, params.timeout, label); 13901 } catch (Exception e) { 13902 // You shall not crash! 13903 loge("Exception in removeDataActivityTracking " + e); 13904 } 13905 } 13906 13907 private void updateDefaultNetworkActivity(NetworkAgentInfo defaultNetwork, 13908 boolean hasIdleTimer) { 13909 if (defaultNetwork != null) { 13910 mDefaultNetwork = defaultNetwork.network(); 13911 mIsDefaultNetworkActive = true; 13912 // If only the default network is tracked, callbacks are called only when the 13913 // network has the idle timer. 13914 if (mTrackMultiNetworkActivities || hasIdleTimer) { 13915 reportNetworkActive(); 13916 } 13917 } else { 13918 mDefaultNetwork = null; 13919 // If there is no default network, default network is considered active to keep the 13920 // existing behavior. 13921 mIsDefaultNetworkActive = true; 13922 } 13923 } 13924 13925 /** 13926 * Update the default network this class tracks the activity of. 13927 */ 13928 public void updateDefaultNetwork(NetworkAgentInfo newNetwork, 13929 NetworkAgentInfo oldNetwork) { 13930 ensureRunningOnConnectivityServiceThread(); 13931 // If TrackMultiNetworkActivities is enabled, devices add idleTimer when the network is 13932 // first connected and remove when the network is disconnected. 13933 // If TrackMultiNetworkActivities is disabled, devices add idleTimer when the network 13934 // becomes the default network and remove when the network becomes no longer the default 13935 // network. 13936 boolean hasIdleTimer = false; 13937 if (!mTrackMultiNetworkActivities && newNetwork != null) { 13938 hasIdleTimer = setupDataActivityTracking(newNetwork); 13939 } 13940 updateDefaultNetworkActivity(newNetwork, hasIdleTimer); 13941 if (!mTrackMultiNetworkActivities && oldNetwork != null) { 13942 removeDataActivityTracking(oldNetwork); 13943 } 13944 } 13945 13946 private void updateRadioPowerState(boolean isActive, int transportType, int uid) { 13947 final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class); 13948 switch (transportType) { 13949 case NetworkCapabilities.TRANSPORT_CELLULAR: 13950 bs.reportMobileRadioPowerState(isActive, uid); 13951 break; 13952 case NetworkCapabilities.TRANSPORT_WIFI: 13953 bs.reportWifiRadioPowerState(isActive, uid); 13954 break; 13955 default: 13956 logw("Untracked transport type:" + transportType); 13957 } 13958 } 13959 13960 public boolean isDefaultNetworkActive() { 13961 return mIsDefaultNetworkActive; 13962 } 13963 13964 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 13965 mNetworkActivityListeners.register(l); 13966 } 13967 13968 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 13969 mNetworkActivityListeners.unregister(l); 13970 } 13971 13972 public void dump(IndentingPrintWriter pw) { 13973 pw.print("mTrackMultiNetworkActivities="); pw.println(mTrackMultiNetworkActivities); 13974 13975 pw.print("mDefaultCellularDataInactivityTimeout="); 13976 pw.println(mDefaultCellularDataInactivityTimeout); 13977 pw.print("mDefaultWifiDataInactivityTimeout="); 13978 pw.println(mDefaultWifiDataInactivityTimeout); 13979 13980 pw.print("mIsDefaultNetworkActive="); pw.println(mIsDefaultNetworkActive); 13981 pw.print("mDefaultNetwork="); pw.println(mDefaultNetwork); 13982 pw.println("Idle timers:"); 13983 try { 13984 for (int i = 0; i < mActiveIdleTimers.size(); i++) { 13985 pw.print(" "); pw.print(mActiveIdleTimers.keyAt(i)); pw.println(":"); 13986 final IdleTimerParams params = mActiveIdleTimers.valueAt(i); 13987 pw.print(" timeout="); pw.print(params.timeout); 13988 pw.print(" type="); pw.println(params.transportType); 13989 } 13990 pw.println("WiFi active networks: " + mActiveWifiNetworks); 13991 pw.println("Cellular active networks: " + mActiveCellularNetworks); 13992 } catch (Exception e) { 13993 // mActiveIdleTimers, mActiveWifiNetworks, and mActiveCellularNetworks should only 13994 // be accessed from handler thread, except dump(). As dump() is never called in 13995 // normal usage, it would be needlessly expensive to lock the collection only for 13996 // its benefit. Also, they are not expected to be updated frequently. 13997 // So catching the exception and logging. 13998 pw.println("Failed to dump NetworkActivityTracker: " + e); 13999 } 14000 } 14001 } 14002 14003 /** 14004 * Registers {@link QosSocketFilter} with {@link IQosCallback}. 14005 * 14006 * @param socketInfo the socket information 14007 * @param callback the callback to register 14008 */ 14009 @Override 14010 public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo, 14011 @NonNull final IQosCallback callback) { 14012 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork()); 14013 if (nai == null || nai.networkCapabilities == null) { 14014 try { 14015 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); 14016 } catch (final RemoteException ex) { 14017 loge("registerQosCallbackInternal: RemoteException", ex); 14018 } 14019 return; 14020 } 14021 registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai); 14022 } 14023 14024 /** 14025 * Register a {@link IQosCallback} with base {@link QosFilter}. 14026 * 14027 * @param filter the filter to register 14028 * @param callback the callback to register 14029 * @param nai the agent information related to the filter's network 14030 */ 14031 @VisibleForTesting 14032 public void registerQosCallbackInternal(@NonNull final QosFilter filter, 14033 @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) { 14034 Objects.requireNonNull(filter, "filter must be non-null"); 14035 Objects.requireNonNull(callback, "callback must be non-null"); 14036 14037 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 14038 // TODO: Check allowed list here and ensure that either a) any QoS callback registered 14039 // on this network is unregistered when the app loses permission or b) no QoS 14040 // callbacks are sent for restricted networks unless the app currently has permission 14041 // to access restricted networks. 14042 enforceConnectivityRestrictedNetworksPermission(false /* checkUidsAllowedList */); 14043 } 14044 mQosCallbackTracker.registerCallback(callback, filter, nai); 14045 } 14046 14047 /** 14048 * Unregisters the given callback. 14049 * 14050 * @param callback the callback to unregister 14051 */ 14052 @Override 14053 public void unregisterQosCallback(@NonNull final IQosCallback callback) { 14054 Objects.requireNonNull(callback, "callback must be non-null"); 14055 mQosCallbackTracker.unregisterCallback(callback); 14056 } 14057 14058 private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) { 14059 // UserManager.isManagedProfile returns true for all apps in managed user profiles. 14060 // Enterprise device can be fully managed like device owner and such use case 14061 // also should be supported. Calling app check for work profile and fully managed device 14062 // is already done in DevicePolicyManager. 14063 // This check is an extra caution to be sure device is fully managed or not. 14064 final UserManager um = mContext.getSystemService(UserManager.class); 14065 final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); 14066 if (um.isManagedProfile(profile.getIdentifier())) { 14067 return true; 14068 } 14069 14070 return mDeps.isAtLeastT() && dpm.getDeviceOwnerComponentOnAnyUser() != null; 14071 } 14072 14073 /** 14074 * Set a list of default network selection policies for a user profile or device owner. 14075 * 14076 * See the documentation for the individual preferences for a description of the supported 14077 * behaviors. 14078 * 14079 * @param profile If the device owner is set, any profile is allowed. 14080 Otherwise, the given profile can only be managed profile. 14081 * @param preferences the list of profile network preferences for the 14082 * provided profile. 14083 * @param listener an optional listener to listen for completion of the operation. 14084 */ 14085 @Override 14086 public void setProfileNetworkPreferences( 14087 @NonNull final UserHandle profile, 14088 @NonNull List<ProfileNetworkPreference> preferences, 14089 @Nullable final IOnCompleteListener listener) { 14090 Objects.requireNonNull(preferences); 14091 Objects.requireNonNull(profile); 14092 14093 if (preferences.size() == 0) { 14094 final ProfileNetworkPreference pref = new ProfileNetworkPreference.Builder() 14095 .setPreference(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT) 14096 .build(); 14097 preferences.add(pref); 14098 } 14099 14100 enforceNetworkStackPermission(mContext); 14101 if (DBG) { 14102 log("setProfileNetworkPreferences " + profile + " to " + preferences); 14103 } 14104 if (profile.getIdentifier() < 0) { 14105 throw new IllegalArgumentException("Must explicitly specify a user handle (" 14106 + "UserHandle.CURRENT not supported)"); 14107 } 14108 if (!isNetworkPreferenceAllowedForProfile(profile)) { 14109 throw new IllegalArgumentException("Profile must be a managed profile " 14110 + "or the device owner must be set. "); 14111 } 14112 14113 final List<ProfileNetworkPreferenceInfo> preferenceList = new ArrayList<>(); 14114 boolean hasDefaultPreference = false; 14115 for (final ProfileNetworkPreference preference : preferences) { 14116 final NetworkCapabilities nc; 14117 boolean allowFallback = true; 14118 boolean blockingNonEnterprise = false; 14119 switch (preference.getPreference()) { 14120 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT: 14121 nc = null; 14122 hasDefaultPreference = true; 14123 if (preference.getPreferenceEnterpriseId() != 0) { 14124 throw new IllegalArgumentException( 14125 "Invalid enterprise identifier in setProfileNetworkPreferences"); 14126 } 14127 break; 14128 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING: 14129 blockingNonEnterprise = true; 14130 // continue to process the enterprise preference. 14131 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK: 14132 allowFallback = false; 14133 // continue to process the enterprise preference. 14134 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE: 14135 // This code is needed even though there is a check later on, 14136 // because isRangeAlreadyInPreferenceList assumes that every preference 14137 // has a UID list. 14138 if (hasDefaultPreference) { 14139 throw new IllegalArgumentException( 14140 "Default profile preference should not be set along with other " 14141 + "preference"); 14142 } 14143 if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) { 14144 throw new IllegalArgumentException( 14145 "Invalid enterprise identifier in setProfileNetworkPreferences"); 14146 } 14147 final Set<UidRange> uidRangeSet = 14148 getUidListToBeAppliedForNetworkPreference(profile, preference); 14149 if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) { 14150 nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet); 14151 } else { 14152 throw new IllegalArgumentException( 14153 "Overlapping uid range in setProfileNetworkPreferences"); 14154 } 14155 nc.addCapability(NET_CAPABILITY_ENTERPRISE); 14156 nc.addEnterpriseId( 14157 preference.getPreferenceEnterpriseId()); 14158 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14159 break; 14160 default: 14161 throw new IllegalArgumentException( 14162 "Invalid preference in setProfileNetworkPreferences"); 14163 } 14164 preferenceList.add(new ProfileNetworkPreferenceInfo( 14165 profile, nc, allowFallback, blockingNonEnterprise)); 14166 if (hasDefaultPreference && preferenceList.size() > 1) { 14167 throw new IllegalArgumentException( 14168 "Default profile preference should not be set along with other preference"); 14169 } 14170 } 14171 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE, 14172 new Pair<>(preferenceList, listener))); 14173 } 14174 14175 private Set<UidRange> getUidListToBeAppliedForNetworkPreference( 14176 @NonNull final UserHandle profile, 14177 @NonNull final ProfileNetworkPreference profileNetworkPreference) { 14178 final UidRange profileUids = UidRange.createForUser(profile); 14179 Set<UidRange> uidRangeSet = UidRangeUtils.convertArrayToUidRange( 14180 profileNetworkPreference.getIncludedUids()); 14181 14182 if (uidRangeSet.size() > 0) { 14183 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) { 14184 throw new IllegalArgumentException( 14185 "Allow uid range is outside the uid range of profile."); 14186 } 14187 } else { 14188 ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertArrayToUidRange( 14189 profileNetworkPreference.getExcludedUids()); 14190 if (disallowUidRangeSet.size() > 0) { 14191 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) { 14192 throw new IllegalArgumentException( 14193 "disallow uid range is outside the uid range of profile."); 14194 } 14195 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids, 14196 disallowUidRangeSet); 14197 } else { 14198 uidRangeSet = new ArraySet<>(); 14199 uidRangeSet.add(profileUids); 14200 } 14201 } 14202 return uidRangeSet; 14203 } 14204 14205 private boolean isEnterpriseIdentifierValid( 14206 @NetworkCapabilities.EnterpriseId int identifier) { 14207 if ((identifier >= NET_ENTERPRISE_ID_1) && (identifier <= NET_ENTERPRISE_ID_5)) { 14208 return true; 14209 } 14210 return false; 14211 } 14212 14213 private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences( 14214 @NonNull final NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> prefs) { 14215 final ArraySet<NetworkRequestInfo> result = new ArraySet<>(); 14216 for (final ProfileNetworkPreferenceInfo pref : prefs) { 14217 // The NRI for a user should contain the request for capabilities. 14218 // If fallback to default network is needed then NRI should include 14219 // the request for the default network. Create an image of it to 14220 // have the correct UIDs in it (also a request can only be part of one NRI, because 14221 // of lookups in 1:1 associations like mNetworkRequests). 14222 final ArrayList<NetworkRequest> nrs = new ArrayList<>(); 14223 nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities)); 14224 if (pref.allowFallback) { 14225 nrs.add(createDefaultInternetRequestForTransport( 14226 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 14227 } 14228 if (VDBG) { 14229 loge("pref.capabilities.getUids():" + UidRange.fromIntRanges( 14230 pref.capabilities.getUids())); 14231 } 14232 14233 setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids())); 14234 final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs, 14235 PREFERENCE_ORDER_PROFILE); 14236 result.add(nri); 14237 } 14238 return result; 14239 } 14240 14241 /** 14242 * Compare if the given UID range sets have the same UIDs. 14243 * 14244 */ 14245 private boolean isRangeAlreadyInPreferenceList( 14246 @NonNull List<ProfileNetworkPreferenceInfo> preferenceList, 14247 @NonNull Set<UidRange> uidRangeSet) { 14248 if (uidRangeSet.size() == 0 || preferenceList.size() == 0) { 14249 return false; 14250 } 14251 for (ProfileNetworkPreferenceInfo pref : preferenceList) { 14252 if (UidRangeUtils.doesRangeSetOverlap( 14253 UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) { 14254 return true; 14255 } 14256 } 14257 return false; 14258 } 14259 14260 private void handleSetProfileNetworkPreference( 14261 @NonNull final List<ProfileNetworkPreferenceInfo> preferenceList, 14262 @Nullable final IOnCompleteListener listener) { 14263 /* 14264 * handleSetProfileNetworkPreference is always called for single user. 14265 * preferenceList only contains preferences for different uids within the same user 14266 * (enforced by getUidListToBeAppliedForNetworkPreference). 14267 * Clear all the existing preferences for the user before applying new preferences. 14268 * 14269 */ 14270 mProfileNetworkPreferences = mProfileNetworkPreferences.minus(preferenceList.get(0).user); 14271 for (final ProfileNetworkPreferenceInfo preference : preferenceList) { 14272 mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference); 14273 } 14274 14275 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_PROFILE); 14276 addPerAppDefaultNetworkRequests( 14277 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences)); 14278 updateProfileAllowedNetworks(); 14279 14280 // Finally, rematch. 14281 rematchAllNetworksAndRequests(); 14282 14283 if (null != listener) { 14284 try { 14285 listener.onComplete(); 14286 } catch (RemoteException e) { 14287 loge("Listener for setProfileNetworkPreference has died"); 14288 } 14289 } 14290 } 14291 14292 @VisibleForTesting 14293 @NonNull 14294 ArraySet<NetworkRequestInfo> createNrisForPreferenceOrder(@NonNull final Set<Integer> uids, 14295 @NonNull final List<NetworkRequest> requests, 14296 final int preferenceOrder) { 14297 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 14298 if (uids.size() == 0) { 14299 // Should not create NetworkRequestInfo if no preferences. Without uid range in 14300 // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI. 14301 return nris; 14302 } 14303 14304 final Set<UidRange> ranges = new ArraySet<>(); 14305 for (final int uid : uids) { 14306 ranges.add(new UidRange(uid, uid)); 14307 } 14308 setNetworkRequestUids(requests, ranges); 14309 nris.add(new NetworkRequestInfo(Process.myUid(), requests, preferenceOrder)); 14310 return nris; 14311 } 14312 14313 ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids( 14314 @NonNull final Set<Integer> uids) { 14315 final List<NetworkRequest> requests = new ArrayList<>(); 14316 // The NRI should be comprised of two layers: 14317 // - The request for the mobile network preferred. 14318 // - The request for the default network, for fallback. 14319 requests.add(createDefaultInternetRequestForTransport( 14320 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST)); 14321 requests.add(createDefaultInternetRequestForTransport( 14322 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 14323 return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED 14324 ); 14325 } 14326 14327 ArraySet<NetworkRequestInfo> createMultiLayerNrisFromSatelliteNetworkFallbackUids( 14328 @NonNull final Set<Integer> uids) { 14329 final List<NetworkRequest> requests = new ArrayList<>(); 14330 14331 // request: track default(unrestricted internet network) 14332 requests.add(createDefaultInternetRequestForTransport( 14333 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 14334 14335 // request: Satellite internet, satellite network could be restricted or constrained 14336 final NetworkCapabilities cap = new NetworkCapabilities.Builder() 14337 .addCapability(NET_CAPABILITY_INTERNET) 14338 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 14339 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 14340 .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) 14341 .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE) 14342 .build(); 14343 requests.add(createNetworkRequest(NetworkRequest.Type.REQUEST, cap)); 14344 14345 return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_SATELLITE_FALLBACK); 14346 } 14347 14348 private void handleMobileDataPreferredUidsChanged() { 14349 mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext); 14350 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 14351 addPerAppDefaultNetworkRequests( 14352 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids)); 14353 // Finally, rematch. 14354 rematchAllNetworksAndRequests(); 14355 } 14356 14357 private void handleSetSatelliteNetworkPreference( 14358 @NonNull final Set<Integer> satelliteNetworkPreferredUids) { 14359 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_SATELLITE_FALLBACK); 14360 addPerAppDefaultNetworkRequests( 14361 createMultiLayerNrisFromSatelliteNetworkFallbackUids(satelliteNetworkPreferredUids) 14362 ); 14363 // Finally, rematch. 14364 rematchAllNetworksAndRequests(); 14365 } 14366 14367 private void handleIngressRateLimitChanged() { 14368 final long oldIngressRateLimit = mIngressRateLimit; 14369 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 14370 mContext); 14371 forEachNetworkAgentInfo(networkAgent -> { 14372 if (canNetworkBeRateLimited(networkAgent)) { 14373 // If rate limit has previously been enabled, remove the old limit first. 14374 if (oldIngressRateLimit >= 0) { 14375 mDeps.disableIngressRateLimit(networkAgent.linkProperties.getInterfaceName()); 14376 } 14377 if (mIngressRateLimit >= 0) { 14378 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 14379 mIngressRateLimit); 14380 } 14381 } 14382 }); 14383 } 14384 14385 private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) { 14386 // Rate-limiting cannot run correctly before T because the BPF program is not loaded. 14387 if (!mDeps.isAtLeastT()) return false; 14388 14389 final NetworkCapabilities agentCaps = networkAgent.networkCapabilities; 14390 // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide 14391 // internet connectivity can be rate limited. 14392 if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport( 14393 TRANSPORT_TEST)) { 14394 return false; 14395 } 14396 14397 final String iface = networkAgent.linkProperties.getInterfaceName(); 14398 if (iface == null) { 14399 // This may happen in tests, but if there is no interface then there is nothing that 14400 // can be rate limited. 14401 loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null"); 14402 return false; 14403 } 14404 return true; 14405 } 14406 14407 private void enforceAutomotiveDevice() { 14408 PermissionUtils.enforceSystemFeature(mContext, PackageManager.FEATURE_AUTOMOTIVE, 14409 "setOemNetworkPreference() is only available on automotive devices."); 14410 } 14411 14412 /** 14413 * Used by automotive devices to set the network preferences used to direct traffic at an 14414 * application level as per the given OemNetworkPreferences. An example use-case would be an 14415 * automotive OEM wanting to provide connectivity for applications critical to the usage of a 14416 * vehicle via a particular network. 14417 * 14418 * Calling this will overwrite the existing preference. 14419 * 14420 * @param preference {@link OemNetworkPreferences} The application network preference to be set. 14421 * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used 14422 * to communicate completion of setOemNetworkPreference(); 14423 */ 14424 @Override 14425 public void setOemNetworkPreference( 14426 @NonNull final OemNetworkPreferences preference, 14427 @Nullable final IOnCompleteListener listener) { 14428 14429 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 14430 // Only bypass the permission/device checks if this is a valid test request. 14431 if (isValidTestOemNetworkPreference(preference)) { 14432 enforceManageTestNetworksPermission(); 14433 } else { 14434 enforceAutomotiveDevice(); 14435 enforceOemNetworkPreferencesPermission(); 14436 validateOemNetworkPreferences(preference); 14437 } 14438 14439 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE, 14440 new Pair<>(preference, listener))); 14441 } 14442 14443 /** 14444 * Sets the specified UIDs to get/receive the VPN as the only default network. 14445 * 14446 * Calling this will overwrite the existing network preference for this session, and the 14447 * specified UIDs won't get any default network when no VPN is connected. 14448 * 14449 * @param session The VPN session which manages the passed UIDs. 14450 * @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the 14451 * setting for this session if the array is empty. Null is not allowed, the 14452 * method will use {@link Objects#requireNonNull(Object)} to check this variable. 14453 * @hide 14454 */ 14455 @Override 14456 public void setVpnNetworkPreference(String session, UidRange[] ranges) { 14457 Objects.requireNonNull(ranges); 14458 enforceNetworkStackOrSettingsPermission(); 14459 final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges); 14460 if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) { 14461 throw new IllegalArgumentException( 14462 "setVpnNetworkPreference: Passed UID ranges overlap"); 14463 } 14464 14465 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE, 14466 new VpnNetworkPreferenceInfo(session, 14467 new ArraySet<UidRange>(Arrays.asList(ranges))))); 14468 } 14469 14470 private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) { 14471 Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo); 14472 14473 mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey()); 14474 mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo); 14475 14476 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN); 14477 addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences)); 14478 // Finally, rematch. 14479 rematchAllNetworksAndRequests(); 14480 } 14481 14482 private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference( 14483 @NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) { 14484 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 14485 for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) { 14486 final List<NetworkRequest> requests = new ArrayList<>(); 14487 // Request VPN only, so other networks won't be the fallback options when VPN is not 14488 // connected temporarily. 14489 requests.add(createVpnRequest()); 14490 final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy()); 14491 setNetworkRequestUids(requests, uidRanges); 14492 nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN)); 14493 } 14494 return nris; 14495 } 14496 14497 /** 14498 * Check the validity of an OEM network preference to be used for testing purposes. 14499 * @param preference the preference to validate 14500 * @return true if this is a valid OEM network preference test request. 14501 */ 14502 private boolean isValidTestOemNetworkPreference( 14503 @NonNull final OemNetworkPreferences preference) { 14504 // Allow for clearing of an existing OemNetworkPreference used for testing. 14505 // This isn't called on the handler thread so it is possible that mOemNetworkPreferences 14506 // changes after this check is complete. This is an unlikely scenario as calling of this API 14507 // is controlled by the OEM therefore the added complexity is not worth adding given those 14508 // circumstances. That said, it is an edge case to be aware of hence this comment. 14509 final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0 14510 && isTestOemNetworkPreference(mOemNetworkPreferences); 14511 return isTestOemNetworkPreference(preference) || isValidTestClearPref; 14512 } 14513 14514 private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) { 14515 final Map<String, Integer> prefMap = preference.getNetworkPreferences(); 14516 return prefMap.size() == 1 14517 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST) 14518 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY)); 14519 } 14520 14521 private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) { 14522 for (@OemNetworkPreferences.OemNetworkPreference final int pref 14523 : preference.getNetworkPreferences().values()) { 14524 if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) { 14525 throw new IllegalArgumentException( 14526 OemNetworkPreferences.oemNetworkPreferenceToString(pref) 14527 + " is an invalid value."); 14528 } 14529 } 14530 } 14531 14532 private void handleSetOemNetworkPreference( 14533 @NonNull final OemNetworkPreferences preference, 14534 @Nullable final IOnCompleteListener listener) { 14535 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 14536 if (DBG) { 14537 log("set OEM network preferences :" + preference.toString()); 14538 } 14539 14540 mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference); 14541 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_OEM); 14542 addPerAppDefaultNetworkRequests(new OemNetworkRequestFactory() 14543 .createNrisFromOemNetworkPreferences(preference)); 14544 mOemNetworkPreferences = preference; 14545 14546 if (null != listener) { 14547 try { 14548 listener.onComplete(); 14549 } catch (RemoteException e) { 14550 loge("Can't send onComplete in handleSetOemNetworkPreference", e); 14551 } 14552 } 14553 } 14554 14555 private void removeDefaultNetworkRequestsForPreference(final int preferenceOrder) { 14556 // Skip the requests which are set by other network preference. Because the uid range rules 14557 // should stay in netd. 14558 final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests); 14559 requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder); 14560 handleRemoveNetworkRequests(requests); 14561 } 14562 14563 private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 14564 ensureRunningOnConnectivityServiceThread(); 14565 mDefaultNetworkRequests.addAll(nris); 14566 final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate = 14567 getPerAppCallbackRequestsToUpdate(); 14568 final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris); 14569 // This method does not need to modify perUidCounter and mBlockedStatusTrackingUids because: 14570 // - |nris| only contains per-app network requests created by ConnectivityService which 14571 // are internal requests and have no messenger and are not associated with any callbacks, 14572 // and so do not need to be tracked in perUidCounter and mBlockedStatusTrackingUids. 14573 // - The requests in perAppCallbackRequestsToUpdate are removed, modified, and re-added, 14574 // but the same number of requests is removed and re-added, and none of the requests 14575 // changes mUid and mAsUid, so the perUidCounter and mBlockedStatusTrackingUids before 14576 // and after this method remains the same. Re-adding the requests does not modify 14577 // perUidCounter and mBlockedStatusTrackingUids (that is done when the app registers the 14578 // request), so removing them must not modify perUidCounter and mBlockedStatusTrackingUids 14579 // either. 14580 // TODO(b/341228979): Modify nris in place instead of removing them and re-adding them 14581 handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate, 14582 false /* untrackUids */); 14583 nrisToRegister.addAll( 14584 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate)); 14585 handleRegisterNetworkRequests(nrisToRegister); 14586 } 14587 14588 /** 14589 * All current requests that are tracking the default network need to be assessed as to whether 14590 * or not the current set of per-application default requests will be changing their default 14591 * network. If so, those requests will need to be updated so that they will send callbacks for 14592 * default network changes at the appropriate time. Additionally, those requests tracking the 14593 * default that were previously updated by this flow will need to be reassessed. 14594 * @return the nris which will need to be updated. 14595 */ 14596 private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() { 14597 final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>(); 14598 // Get the distinct nris to check since for multilayer requests, it is possible to have the 14599 // same nri in the map's values for each of its NetworkRequest objects. 14600 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values()); 14601 for (final NetworkRequestInfo nri : nris) { 14602 // Include this nri if it is currently being tracked. 14603 if (isPerAppTrackedNri(nri)) { 14604 defaultCallbackRequests.add(nri); 14605 continue; 14606 } 14607 // We only track callbacks for requests tracking the default. 14608 if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) { 14609 continue; 14610 } 14611 // Include this nri if it will be tracked by the new per-app default requests. 14612 final boolean isNriGoingToBeTracked = 14613 getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest; 14614 if (isNriGoingToBeTracked) { 14615 defaultCallbackRequests.add(nri); 14616 } 14617 } 14618 return defaultCallbackRequests; 14619 } 14620 14621 /** 14622 * Create nris for those network requests that are currently tracking the default network that 14623 * are being controlled by a per-application default. 14624 * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the 14625 * foundation when creating the nri. Important items include the calling uid's original 14626 * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These 14627 * requests are assumed to have already been validated as needing to be updated. 14628 * @return the Set of nris to use when registering network requests. 14629 */ 14630 private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister( 14631 @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) { 14632 final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>(); 14633 for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) { 14634 final NetworkRequestInfo trackingNri = 14635 getDefaultRequestTrackingUid(callbackRequest.mAsUid); 14636 14637 // If this nri is not being tracked, then change it back to an untracked nri. 14638 if (trackingNri == mDefaultRequest) { 14639 callbackRequestsToRegister.add(new NetworkRequestInfo( 14640 callbackRequest, 14641 Collections.singletonList(callbackRequest.getNetworkRequestForCallback()))); 14642 continue; 14643 } 14644 14645 final NetworkRequest request = callbackRequest.mRequests.get(0); 14646 callbackRequestsToRegister.add(new NetworkRequestInfo( 14647 callbackRequest, 14648 copyNetworkRequestsForUid( 14649 trackingNri.mRequests, callbackRequest.mAsUid, 14650 callbackRequest.mUid, request.getRequestorPackageName()))); 14651 } 14652 return callbackRequestsToRegister; 14653 } 14654 14655 private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests, 14656 @NonNull final Set<UidRange> uids) { 14657 for (final NetworkRequest req : requests) { 14658 req.networkCapabilities.setUids(UidRange.toIntRanges(uids)); 14659 } 14660 } 14661 14662 /** 14663 * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}. 14664 */ 14665 @VisibleForTesting 14666 final class OemNetworkRequestFactory { 14667 ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences( 14668 @NonNull final OemNetworkPreferences preference) { 14669 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 14670 final SparseArray<Set<Integer>> uids = 14671 createUidsFromOemNetworkPreferences(preference); 14672 for (int i = 0; i < uids.size(); i++) { 14673 final int key = uids.keyAt(i); 14674 final Set<Integer> value = uids.valueAt(i); 14675 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value); 14676 // No need to add an nri without any requests. 14677 if (0 == nri.mRequests.size()) { 14678 continue; 14679 } 14680 nris.add(nri); 14681 } 14682 14683 return nris; 14684 } 14685 14686 private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences( 14687 @NonNull final OemNetworkPreferences preference) { 14688 final SparseArray<Set<Integer>> prefToUids = new SparseArray<>(); 14689 final PackageManager pm = mContext.getPackageManager(); 14690 final List<UserHandle> users = 14691 mContext.getSystemService(UserManager.class).getUserHandles(true); 14692 if (null == users || users.size() == 0) { 14693 if (VDBG || DDBG) { 14694 log("No users currently available for setting the OEM network preference."); 14695 } 14696 return prefToUids; 14697 } 14698 for (final Map.Entry<String, Integer> entry : 14699 preference.getNetworkPreferences().entrySet()) { 14700 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue(); 14701 // Add the rules for all users as this policy is device wide. 14702 for (final UserHandle user : users) { 14703 try { 14704 final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid; 14705 if (!prefToUids.contains(pref)) { 14706 prefToUids.put(pref, new ArraySet<>()); 14707 } 14708 prefToUids.get(pref).add(uid); 14709 } catch (PackageManager.NameNotFoundException e) { 14710 // Although this may seem like an error scenario, it is ok that uninstalled 14711 // packages are sent on a network preference as the system will watch for 14712 // package installations associated with this network preference and update 14713 // accordingly. This is done to minimize race conditions on app install. 14714 continue; 14715 } 14716 } 14717 } 14718 return prefToUids; 14719 } 14720 14721 private NetworkRequestInfo createNriFromOemNetworkPreferences( 14722 @OemNetworkPreferences.OemNetworkPreference final int preference, 14723 @NonNull final Set<Integer> uids) { 14724 final List<NetworkRequest> requests = new ArrayList<>(); 14725 // Requests will ultimately be evaluated by order of insertion therefore it matters. 14726 switch (preference) { 14727 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID: 14728 requests.add(createUnmeteredNetworkRequest()); 14729 requests.add(createOemPaidNetworkRequest()); 14730 requests.add(createDefaultInternetRequestForTransport( 14731 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 14732 break; 14733 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK: 14734 requests.add(createUnmeteredNetworkRequest()); 14735 requests.add(createOemPaidNetworkRequest()); 14736 break; 14737 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY: 14738 requests.add(createOemPaidNetworkRequest()); 14739 break; 14740 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY: 14741 requests.add(createOemPrivateNetworkRequest()); 14742 break; 14743 case OEM_NETWORK_PREFERENCE_TEST: 14744 requests.add(createUnmeteredNetworkRequest()); 14745 requests.add(createTestNetworkRequest()); 14746 requests.add(createDefaultRequest()); 14747 break; 14748 case OEM_NETWORK_PREFERENCE_TEST_ONLY: 14749 requests.add(createTestNetworkRequest()); 14750 break; 14751 default: 14752 // This should never happen. 14753 throw new IllegalArgumentException("createNriFromOemNetworkPreferences()" 14754 + " called with invalid preference of " + preference); 14755 } 14756 14757 final ArraySet<UidRange> ranges = new ArraySet<>(); 14758 for (final int uid : uids) { 14759 ranges.add(new UidRange(uid, uid)); 14760 } 14761 setNetworkRequestUids(requests, ranges); 14762 return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM); 14763 } 14764 14765 private NetworkRequest createUnmeteredNetworkRequest() { 14766 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 14767 .addCapability(NET_CAPABILITY_NOT_METERED) 14768 .addCapability(NET_CAPABILITY_VALIDATED); 14769 return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap); 14770 } 14771 14772 private NetworkRequest createOemPaidNetworkRequest() { 14773 // NET_CAPABILITY_OEM_PAID is a restricted capability. 14774 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 14775 .addCapability(NET_CAPABILITY_OEM_PAID) 14776 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14777 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 14778 } 14779 14780 private NetworkRequest createOemPrivateNetworkRequest() { 14781 // NET_CAPABILITY_OEM_PRIVATE is a restricted capability. 14782 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 14783 .addCapability(NET_CAPABILITY_OEM_PRIVATE) 14784 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14785 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 14786 } 14787 14788 private NetworkCapabilities createDefaultPerAppNetCap() { 14789 final NetworkCapabilities netcap = new NetworkCapabilities(); 14790 netcap.addCapability(NET_CAPABILITY_INTERNET); 14791 netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 14792 return netcap; 14793 } 14794 14795 private NetworkRequest createTestNetworkRequest() { 14796 final NetworkCapabilities netcap = new NetworkCapabilities(); 14797 netcap.clearAll(); 14798 netcap.addTransportType(TRANSPORT_TEST); 14799 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 14800 } 14801 } 14802 14803 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14804 @Override 14805 public void setDataSaverEnabled(final boolean enable) { 14806 enforceNetworkStackOrSettingsPermission(); 14807 try { 14808 final boolean ret = mNetd.bandwidthEnableDataSaver(enable); 14809 if (!ret) { 14810 throw new IllegalStateException("Error when changing iptables: " + enable); 14811 } 14812 } catch (RemoteException e) { 14813 // Lack of permission or binder errors. 14814 throw new IllegalStateException(e); 14815 } 14816 14817 synchronized (mBlockedStatusTrackingUids) { 14818 try { 14819 mBpfNetMaps.setDataSaverEnabled(enable); 14820 } catch (ServiceSpecificException | UnsupportedOperationException e) { 14821 Log.e(TAG, "Failed to set data saver " + enable + " : " + e); 14822 return; 14823 } 14824 14825 if (shouldTrackUidsForBlockedStatusCallbacks()) { 14826 updateTrackingUidsBlockedReasons(); 14827 } 14828 } 14829 } 14830 14831 private int setPackageFirewallRule(final int chain, final String packageName, final int rule) 14832 throws PackageManager.NameNotFoundException { 14833 final PackageManager pm = mContext.getPackageManager(); 14834 final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */)); 14835 if (appId < Process.FIRST_APPLICATION_UID) { 14836 throw new RuntimeException("Can't set package firewall rule for system app " 14837 + packageName + " with appId " + appId); 14838 } 14839 for (final UserHandle uh : mUserManager.getUserHandles(false /* excludeDying */)) { 14840 final int uid = uh.getUid(appId); 14841 setUidFirewallRule(chain, uid, rule); 14842 } 14843 return appId; 14844 } 14845 14846 @Override 14847 public void setUidFirewallRule(final int chain, final int uid, final int rule) { 14848 enforceNetworkStackOrSettingsPermission(); 14849 14850 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 14851 Log.i(TAG, "Ignoring operation setUidFirewallRule on the background chain because the" 14852 + " feature is disabled."); 14853 return; 14854 } 14855 14856 // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY 14857 int firewallRule = getFirewallRuleType(chain, rule); 14858 14859 if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) { 14860 throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule); 14861 } 14862 14863 synchronized (mBlockedStatusTrackingUids) { 14864 try { 14865 mBpfNetMaps.setUidRule(chain, uid, firewallRule); 14866 } catch (ServiceSpecificException e) { 14867 throw new IllegalStateException(e); 14868 } 14869 if (shouldTrackUidsForBlockedStatusCallbacks() 14870 && mBlockedStatusTrackingUids.get(uid, 0) != 0) { 14871 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 14872 List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))))); 14873 } 14874 if (shouldTrackFirewallDestroySocketReasons()) { 14875 maybePostFirewallDestroySocketReasons(chain, Set.of(uid)); 14876 } 14877 } 14878 } 14879 14880 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14881 private int getPackageFirewallRule(final int chain, final String packageName) 14882 throws PackageManager.NameNotFoundException { 14883 final PackageManager pm = mContext.getPackageManager(); 14884 final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */)); 14885 return getUidFirewallRule(chain, appId); 14886 } 14887 14888 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14889 @Override 14890 public int getUidFirewallRule(final int chain, final int uid) { 14891 enforceNetworkStackOrSettingsPermission(); 14892 return mBpfNetMaps.getUidRule(chain, uid); 14893 } 14894 14895 private int getFirewallRuleType(int chain, int rule) { 14896 final int defaultRule; 14897 switch (chain) { 14898 case ConnectivityManager.FIREWALL_CHAIN_STANDBY: 14899 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1: 14900 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2: 14901 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3: 14902 case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER: 14903 case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN: 14904 defaultRule = FIREWALL_RULE_ALLOW; 14905 break; 14906 case ConnectivityManager.FIREWALL_CHAIN_DOZABLE: 14907 case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: 14908 case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: 14909 case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: 14910 case ConnectivityManager.FIREWALL_CHAIN_BACKGROUND: 14911 case ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW: 14912 defaultRule = FIREWALL_RULE_DENY; 14913 break; 14914 default: 14915 throw new IllegalArgumentException("Unsupported firewall chain: " + chain); 14916 } 14917 if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule; 14918 14919 return rule; 14920 } 14921 14922 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14923 private Set<Integer> getUidsOnFirewallChain(final int chain) throws ErrnoException { 14924 if (BpfNetMapsUtils.isFirewallAllowList(chain)) { 14925 return mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(chain); 14926 } else { 14927 return mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(chain); 14928 } 14929 } 14930 14931 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14932 private void closeSocketsForFirewallChainLocked(final int chain) 14933 throws ErrnoException, SocketException, InterruptedIOException { 14934 final Set<Integer> uidsOnChain = getUidsOnFirewallChain(chain); 14935 if (BpfNetMapsUtils.isFirewallAllowList(chain)) { 14936 // Allowlist means the firewall denies all by default, uids must be explicitly allowed 14937 // So, close all non-system socket owned by uids that are not explicitly allowed 14938 Set<Range<Integer>> ranges = new ArraySet<>(); 14939 ranges.add(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE)); 14940 mDeps.destroyLiveTcpSockets(ranges, uidsOnChain /* exemptUids */); 14941 } else { 14942 // Denylist means the firewall allows all by default, uids must be explicitly denied 14943 // So, close socket owned by uids that are explicitly denied 14944 mDeps.destroyLiveTcpSocketsByOwnerUids(uidsOnChain /* ownerUids */); 14945 } 14946 } 14947 14948 private void maybePostClearFirewallDestroySocketReasons(int chain) { 14949 if (chain != FIREWALL_CHAIN_BACKGROUND) { 14950 // TODO (b/300681644): Support other firewall chains 14951 return; 14952 } 14953 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS, 14954 DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND, 0 /* arg2 */)); 14955 } 14956 14957 @Override 14958 public void setFirewallChainEnabled(final int chain, final boolean enable) { 14959 enforceNetworkStackOrSettingsPermission(); 14960 14961 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 14962 Log.i(TAG, "Ignoring operation setFirewallChainEnabled on the background chain because" 14963 + " the feature is disabled."); 14964 return; 14965 } 14966 if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) { 14967 // Metered chains are used from a separate bpf program that is triggered by iptables 14968 // and can not be controlled by setFirewallChainEnabled. 14969 throw new UnsupportedOperationException( 14970 "Chain (" + chain + ") can not be controlled by setFirewallChainEnabled"); 14971 } 14972 14973 synchronized (mBlockedStatusTrackingUids) { 14974 try { 14975 mBpfNetMaps.setChildChain(chain, enable); 14976 } catch (ServiceSpecificException e) { 14977 throw new IllegalStateException(e); 14978 } 14979 if (shouldTrackUidsForBlockedStatusCallbacks()) { 14980 updateTrackingUidsBlockedReasons(); 14981 } 14982 if (shouldTrackFirewallDestroySocketReasons() && !enable) { 14983 // Clear destroy socket reasons so that CS does not destroy sockets of apps that 14984 // have network access. 14985 maybePostClearFirewallDestroySocketReasons(chain); 14986 } 14987 } 14988 14989 if (mDeps.isAtLeastU() && enable) { 14990 try { 14991 closeSocketsForFirewallChainLocked(chain); 14992 } catch (ErrnoException | SocketException | InterruptedIOException e) { 14993 Log.e(TAG, "Failed to close sockets after enabling chain (" + chain + "): " + e); 14994 } 14995 } 14996 } 14997 14998 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 14999 @GuardedBy("mBlockedStatusTrackingUids") 15000 private void updateTrackingUidsBlockedReasons() { 15001 if (mBlockedStatusTrackingUids.size() == 0) { 15002 return; 15003 } 15004 final ArrayList<Pair<Integer, Integer>> uidBlockedReasonsList = new ArrayList<>(); 15005 for (int i = 0; i < mBlockedStatusTrackingUids.size(); i++) { 15006 final int uid = mBlockedStatusTrackingUids.keyAt(i); 15007 uidBlockedReasonsList.add( 15008 new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid))); 15009 } 15010 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED, 15011 uidBlockedReasonsList)); 15012 } 15013 15014 private int getFirewallDestroySocketReasons(final int blockedReasons) { 15015 int destroySocketReasons = DESTROY_SOCKET_REASON_NONE; 15016 if ((blockedReasons & BLOCKED_REASON_APP_BACKGROUND) != BLOCKED_REASON_NONE) { 15017 destroySocketReasons |= DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND; 15018 } 15019 return destroySocketReasons; 15020 } 15021 15022 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 15023 @GuardedBy("mBlockedStatusTrackingUids") 15024 private void maybePostFirewallDestroySocketReasons(int chain, Set<Integer> uids) { 15025 if (chain != FIREWALL_CHAIN_BACKGROUND) { 15026 // TODO (b/300681644): Support other firewall chains 15027 return; 15028 } 15029 final ArrayList<Pair<Integer, Integer>> reasonsList = new ArrayList<>(); 15030 for (int uid: uids) { 15031 final int blockedReasons = mBpfNetMaps.getUidNetworkingBlockedReasons(uid); 15032 final int destroySocketReaons = getFirewallDestroySocketReasons(blockedReasons); 15033 reasonsList.add(new Pair<>(uid, destroySocketReaons)); 15034 } 15035 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS, 15036 reasonsList)); 15037 } 15038 15039 @Override 15040 public boolean getFirewallChainEnabled(final int chain) { 15041 enforceNetworkStackOrSettingsPermission(); 15042 15043 if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) { 15044 // Metered chains are used from a separate bpf program that is triggered by iptables 15045 // and can not be controlled by setFirewallChainEnabled. 15046 throw new UnsupportedOperationException( 15047 "getFirewallChainEnabled can not return status of chain (" + chain + ")"); 15048 } 15049 15050 return mBpfNetMaps.isChainEnabled(chain); 15051 } 15052 15053 @Override 15054 public void replaceFirewallChain(final int chain, final int[] uids) { 15055 enforceNetworkStackOrSettingsPermission(); 15056 15057 if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) { 15058 Log.i(TAG, "Ignoring operation replaceFirewallChain on the background chain because" 15059 + " the feature is disabled."); 15060 return; 15061 } 15062 15063 synchronized (mBlockedStatusTrackingUids) { 15064 // replaceFirewallChain removes uids that are currently on the chain and put |uids| on 15065 // the chain. 15066 // So this method could change blocked reasons of uids that are currently on chain + 15067 // |uids|. 15068 final Set<Integer> affectedUids = new ArraySet<>(); 15069 if (shouldTrackFirewallDestroySocketReasons()) { 15070 try { 15071 affectedUids.addAll(getUidsOnFirewallChain(chain)); 15072 } catch (ErrnoException e) { 15073 Log.e(TAG, "Failed to get uids on chain(" + chain + "): " + e); 15074 } 15075 for (final int uid: uids) { 15076 affectedUids.add(uid); 15077 } 15078 } 15079 15080 mBpfNetMaps.replaceUidChain(chain, uids); 15081 if (shouldTrackUidsForBlockedStatusCallbacks()) { 15082 updateTrackingUidsBlockedReasons(); 15083 } 15084 if (shouldTrackFirewallDestroySocketReasons()) { 15085 maybePostFirewallDestroySocketReasons(chain, affectedUids); 15086 } 15087 } 15088 } 15089 15090 @Override 15091 public IBinder getCompanionDeviceManagerProxyService() { 15092 enforceNetworkStackPermission(mContext); 15093 return mCdmps; 15094 } 15095 15096 @Override 15097 public IBinder getRoutingCoordinatorService() { 15098 enforceNetworkStackPermission(mContext); 15099 return mRoutingCoordinatorService; 15100 } 15101 15102 @Override 15103 public long getEnabledConnectivityManagerFeatures() { 15104 long features = 0; 15105 // The bitmask must be built based on final properties initialized in the constructor, to 15106 // ensure that it does not change over time and is always consistent between 15107 // ConnectivityManager and ConnectivityService. 15108 if (mUseDeclaredMethodsForCallbacksEnabled) { 15109 features |= ConnectivityManager.FEATURE_USE_DECLARED_METHODS_FOR_CALLBACKS; 15110 } 15111 if (mQueueNetworkAgentEventsInSystemServer) { 15112 features |= ConnectivityManager.FEATURE_QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER; 15113 } 15114 return features; 15115 } 15116 15117 @Override 15118 public boolean isConnectivityServiceFeatureEnabledForTesting(String featureFlag) { 15119 switch (featureFlag) { 15120 case INGRESS_TO_VPN_ADDRESS_FILTERING: 15121 return mIngressToVpnAddressFiltering; 15122 case QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER: 15123 return mQueueNetworkAgentEventsInSystemServer; 15124 default: 15125 throw new IllegalArgumentException("Unknown flag: " + featureFlag); 15126 } 15127 } 15128 } 15129