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_WATCH; 23 import static android.content.pm.PackageManager.FEATURE_WIFI; 24 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 25 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 26 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; 27 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK; 28 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT; 29 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS; 30 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS; 31 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS; 32 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS; 33 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE; 34 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 35 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; 36 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 37 import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED; 38 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 39 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 40 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 41 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 42 import static android.net.ConnectivityManager.TYPE_BLUETOOTH; 43 import static android.net.ConnectivityManager.TYPE_ETHERNET; 44 import static android.net.ConnectivityManager.TYPE_MOBILE; 45 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS; 46 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 47 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY; 48 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 49 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 50 import static android.net.ConnectivityManager.TYPE_MOBILE_IA; 51 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS; 52 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 53 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 54 import static android.net.ConnectivityManager.TYPE_NONE; 55 import static android.net.ConnectivityManager.TYPE_PROXY; 56 import static android.net.ConnectivityManager.TYPE_VPN; 57 import static android.net.ConnectivityManager.TYPE_WIFI; 58 import static android.net.ConnectivityManager.TYPE_WIFI_P2P; 59 import static android.net.ConnectivityManager.getNetworkTypeName; 60 import static android.net.ConnectivityManager.isNetworkTypeValid; 61 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 62 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 63 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 64 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_SKIPPED; 65 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 66 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 67 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 68 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 69 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 70 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 71 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 72 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 73 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 74 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 75 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 76 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 77 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 78 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 79 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 80 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 81 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 82 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 83 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 84 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 85 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 86 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 87 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 88 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 89 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 90 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; 91 import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY; 92 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 93 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 94 import static android.os.Process.INVALID_UID; 95 import static android.os.Process.VPN_UID; 96 import static android.provider.DeviceConfig.NAMESPACE_TETHERING; 97 import static android.system.OsConstants.ETH_P_ALL; 98 import static android.system.OsConstants.IPPROTO_TCP; 99 import static android.system.OsConstants.IPPROTO_UDP; 100 101 import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME; 102 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired; 103 import static com.android.net.module.util.PermissionUtils.checkAnyPermissionOf; 104 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf; 105 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission; 106 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr; 107 108 import static java.util.Map.Entry; 109 110 import android.Manifest; 111 import android.annotation.NonNull; 112 import android.annotation.Nullable; 113 import android.annotation.SuppressLint; 114 import android.annotation.TargetApi; 115 import android.app.ActivityManager; 116 import android.app.ActivityManager.UidFrozenStateChangedCallback; 117 import android.app.AppOpsManager; 118 import android.app.BroadcastOptions; 119 import android.app.PendingIntent; 120 import android.app.admin.DevicePolicyManager; 121 import android.app.compat.CompatChanges; 122 import android.app.usage.NetworkStatsManager; 123 import android.content.BroadcastReceiver; 124 import android.content.ComponentName; 125 import android.content.ContentResolver; 126 import android.content.Context; 127 import android.content.Intent; 128 import android.content.IntentFilter; 129 import android.content.pm.PackageManager; 130 import android.content.res.XmlResourceParser; 131 import android.database.ContentObserver; 132 import android.net.CaptivePortal; 133 import android.net.CaptivePortalData; 134 import android.net.ConnectionInfo; 135 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 136 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 137 import android.net.ConnectivityManager; 138 import android.net.ConnectivityManager.BlockedReason; 139 import android.net.ConnectivityManager.NetworkCallback; 140 import android.net.ConnectivityManager.RestrictBackgroundStatus; 141 import android.net.ConnectivitySettingsManager; 142 import android.net.DataStallReportParcelable; 143 import android.net.DnsResolverServiceManager; 144 import android.net.DscpPolicy; 145 import android.net.ICaptivePortal; 146 import android.net.IConnectivityDiagnosticsCallback; 147 import android.net.IConnectivityManager; 148 import android.net.IDnsResolver; 149 import android.net.INetd; 150 import android.net.INetworkActivityListener; 151 import android.net.INetworkAgent; 152 import android.net.INetworkMonitor; 153 import android.net.INetworkMonitorCallbacks; 154 import android.net.INetworkOfferCallback; 155 import android.net.IOnCompleteListener; 156 import android.net.IQosCallback; 157 import android.net.ISocketKeepaliveCallback; 158 import android.net.InetAddresses; 159 import android.net.IpMemoryStore; 160 import android.net.IpPrefix; 161 import android.net.LinkProperties; 162 import android.net.MatchAllNetworkSpecifier; 163 import android.net.NativeNetworkConfig; 164 import android.net.NativeNetworkType; 165 import android.net.NattSocketKeepalive; 166 import android.net.Network; 167 import android.net.NetworkAgent; 168 import android.net.NetworkAgentConfig; 169 import android.net.NetworkCapabilities; 170 import android.net.NetworkInfo; 171 import android.net.NetworkInfo.DetailedState; 172 import android.net.NetworkMonitorManager; 173 import android.net.NetworkPolicyManager; 174 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 175 import android.net.NetworkProvider; 176 import android.net.NetworkRequest; 177 import android.net.NetworkScore; 178 import android.net.NetworkSpecifier; 179 import android.net.NetworkStack; 180 import android.net.NetworkState; 181 import android.net.NetworkStateSnapshot; 182 import android.net.NetworkTestResultParcelable; 183 import android.net.NetworkUtils; 184 import android.net.NetworkWatchlistManager; 185 import android.net.OemNetworkPreferences; 186 import android.net.PrivateDnsConfigParcel; 187 import android.net.ProfileNetworkPreference; 188 import android.net.ProxyInfo; 189 import android.net.QosCallbackException; 190 import android.net.QosFilter; 191 import android.net.QosSocketFilter; 192 import android.net.QosSocketInfo; 193 import android.net.RouteInfo; 194 import android.net.RouteInfoParcel; 195 import android.net.SocketKeepalive; 196 import android.net.TetheringManager; 197 import android.net.TransportInfo; 198 import android.net.UidRange; 199 import android.net.UidRangeParcel; 200 import android.net.UnderlyingNetworkInfo; 201 import android.net.Uri; 202 import android.net.VpnManager; 203 import android.net.VpnTransportInfo; 204 import android.net.connectivity.ConnectivityCompatChanges; 205 import android.net.metrics.IpConnectivityLog; 206 import android.net.metrics.NetworkEvent; 207 import android.net.netd.aidl.NativeUidRangeConfig; 208 import android.net.networkstack.ModuleNetworkStackClient; 209 import android.net.networkstack.NetworkStackClientBase; 210 import android.net.networkstack.aidl.NetworkMonitorParameters; 211 import android.net.resolv.aidl.DnsHealthEventParcel; 212 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; 213 import android.net.resolv.aidl.Nat64PrefixEventParcel; 214 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 215 import android.net.shared.PrivateDnsConfig; 216 import android.net.wifi.WifiInfo; 217 import android.os.BatteryStatsManager; 218 import android.os.Binder; 219 import android.os.Build; 220 import android.os.Bundle; 221 import android.os.ConditionVariable; 222 import android.os.Handler; 223 import android.os.HandlerThread; 224 import android.os.IBinder; 225 import android.os.Looper; 226 import android.os.Message; 227 import android.os.Messenger; 228 import android.os.ParcelFileDescriptor; 229 import android.os.Parcelable; 230 import android.os.PersistableBundle; 231 import android.os.PowerManager; 232 import android.os.Process; 233 import android.os.RemoteCallbackList; 234 import android.os.RemoteException; 235 import android.os.ServiceSpecificException; 236 import android.os.SystemClock; 237 import android.os.SystemProperties; 238 import android.os.UserHandle; 239 import android.os.UserManager; 240 import android.provider.Settings; 241 import android.sysprop.NetworkProperties; 242 import android.system.ErrnoException; 243 import android.telephony.TelephonyManager; 244 import android.text.TextUtils; 245 import android.util.ArrayMap; 246 import android.util.ArraySet; 247 import android.util.LocalLog; 248 import android.util.Log; 249 import android.util.Pair; 250 import android.util.Range; 251 import android.util.SparseArray; 252 import android.util.SparseIntArray; 253 254 import androidx.annotation.RequiresApi; 255 256 import com.android.connectivity.resources.R; 257 import com.android.internal.annotations.GuardedBy; 258 import com.android.internal.annotations.VisibleForTesting; 259 import com.android.internal.util.IndentingPrintWriter; 260 import com.android.internal.util.MessageUtils; 261 import com.android.modules.utils.BasicShellCommandHandler; 262 import com.android.modules.utils.build.SdkLevel; 263 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 264 import com.android.net.module.util.BinderUtils; 265 import com.android.net.module.util.BitUtils; 266 import com.android.net.module.util.CollectionUtils; 267 import com.android.net.module.util.DeviceConfigUtils; 268 import com.android.net.module.util.InterfaceParams; 269 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; 270 import com.android.net.module.util.LinkPropertiesUtils.CompareResult; 271 import com.android.net.module.util.LocationPermissionChecker; 272 import com.android.net.module.util.PerUidCounter; 273 import com.android.net.module.util.PermissionUtils; 274 import com.android.net.module.util.TcUtils; 275 import com.android.net.module.util.netlink.InetDiagMessage; 276 import com.android.networkstack.apishim.BroadcastOptionsShimImpl; 277 import com.android.networkstack.apishim.ConstantsShim; 278 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 279 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 280 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 281 import com.android.server.connectivity.AutodestructReference; 282 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 283 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive; 284 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 285 import com.android.server.connectivity.ClatCoordinator; 286 import com.android.server.connectivity.ConnectivityFlags; 287 import com.android.server.connectivity.ConnectivityResources; 288 import com.android.server.connectivity.DnsManager; 289 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; 290 import com.android.server.connectivity.DscpPolicyTracker; 291 import com.android.server.connectivity.FullScore; 292 import com.android.server.connectivity.InvalidTagException; 293 import com.android.server.connectivity.KeepaliveResourceUtil; 294 import com.android.server.connectivity.KeepaliveTracker; 295 import com.android.server.connectivity.LingerMonitor; 296 import com.android.server.connectivity.MockableSystemProperties; 297 import com.android.server.connectivity.MultinetworkPolicyTracker; 298 import com.android.server.connectivity.NetworkAgentInfo; 299 import com.android.server.connectivity.NetworkDiagnostics; 300 import com.android.server.connectivity.NetworkNotificationManager; 301 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 302 import com.android.server.connectivity.NetworkOffer; 303 import com.android.server.connectivity.NetworkPreferenceList; 304 import com.android.server.connectivity.NetworkRanker; 305 import com.android.server.connectivity.PermissionMonitor; 306 import com.android.server.connectivity.ProfileNetworkPreferenceInfo; 307 import com.android.server.connectivity.ProxyTracker; 308 import com.android.server.connectivity.QosCallbackTracker; 309 import com.android.server.connectivity.UidRangeUtils; 310 import com.android.server.connectivity.VpnNetworkPreferenceInfo; 311 import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService; 312 313 import libcore.io.IoUtils; 314 315 import org.xmlpull.v1.XmlPullParserException; 316 317 import java.io.FileDescriptor; 318 import java.io.IOException; 319 import java.io.InterruptedIOException; 320 import java.io.PrintWriter; 321 import java.io.Writer; 322 import java.lang.IllegalArgumentException; 323 import java.net.Inet4Address; 324 import java.net.InetAddress; 325 import java.net.InetSocketAddress; 326 import java.net.SocketException; 327 import java.net.UnknownHostException; 328 import java.util.ArrayList; 329 import java.util.Arrays; 330 import java.util.Collection; 331 import java.util.Collections; 332 import java.util.Comparator; 333 import java.util.ConcurrentModificationException; 334 import java.util.HashMap; 335 import java.util.HashSet; 336 import java.util.List; 337 import java.util.Map; 338 import java.util.NoSuchElementException; 339 import java.util.Objects; 340 import java.util.Set; 341 import java.util.SortedSet; 342 import java.util.StringJoiner; 343 import java.util.TreeSet; 344 import java.util.concurrent.atomic.AtomicInteger; 345 346 /** 347 * @hide 348 */ 349 public class ConnectivityService extends IConnectivityManager.Stub 350 implements PendingIntent.OnFinished { 351 private static final String TAG = ConnectivityService.class.getSimpleName(); 352 353 private static final String DIAG_ARG = "--diag"; 354 public static final String SHORT_ARG = "--short"; 355 private static final String NETWORK_ARG = "networks"; 356 private static final String REQUEST_ARG = "requests"; 357 private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller"; 358 359 private static final boolean DBG = true; 360 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); 361 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 362 363 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 364 365 /** 366 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed 367 * by OEMs for configuration purposes, as this value is overridden by 368 * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL. 369 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose 370 * (preferably via runtime resource overlays). 371 */ 372 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL = 373 "http://connectivitycheck.gstatic.com/generate_204"; 374 375 // TODO: create better separation between radio types and network types 376 377 // how long to wait before switching back to a radio's default network 378 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 379 // system property that can override the above value 380 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 381 "android.telephony.apn-restore"; 382 383 // How long to wait before putting up a "This network doesn't have an Internet connection, 384 // connect anyway?" dialog after the user selects a network that doesn't validate. 385 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 386 387 // How long to wait before considering that a network is bad in the absence of any form 388 // of connectivity (valid, partial, captive portal). If none has been detected after this 389 // delay, the stack considers this network bad, which may affect how it's handled in ranking 390 // according to config_networkAvoidBadWifi. 391 // Timeout in case the "actively prefer bad wifi" feature is on 392 private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000; 393 // Timeout in case the "actively prefer bad wifi" feature is off 394 private static final int DEFAULT_EVALUATION_TIMEOUT_MS = 8 * 1000; 395 396 // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing. 397 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 398 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 399 private static final int DEFAULT_NASCENT_DELAY_MS = 5_000; 400 401 // Delimiter used when creating the broadcast delivery group for sending 402 // CONNECTIVITY_ACTION broadcast. 403 private static final char DELIVERY_GROUP_KEY_DELIMITER = ';'; 404 405 // The maximum value for the blocking validation result, in milliseconds. 406 public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000; 407 408 // The maximum number of network request allowed per uid before an exception is thrown. 409 @VisibleForTesting 410 static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 411 412 // The maximum number of network request allowed for system UIDs before an exception is thrown. 413 @VisibleForTesting 414 static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250; 415 416 @VisibleForTesting 417 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 418 @VisibleForTesting 419 protected int mNascentDelayMs; 420 // True if the cell radio of the device is capable of time-sharing. 421 @VisibleForTesting 422 protected boolean mCellularRadioTimesharingCapable = true; 423 424 // How long to delay to removal of a pending intent based request. 425 // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 426 private final int mReleasePendingIntentDelayMs; 427 428 private final MockableSystemProperties mSystemProperties; 429 430 private final PermissionMonitor mPermissionMonitor; 431 432 @VisibleForTesting 433 final RequestInfoPerUidCounter mNetworkRequestCounter; 434 @VisibleForTesting 435 final RequestInfoPerUidCounter mSystemNetworkRequestCounter; 436 437 private volatile boolean mLockdownEnabled; 438 439 /** 440 * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in 441 * internal handler thread, they don't need a lock. 442 */ 443 private final SparseIntArray mUidBlockedReasons = new SparseIntArray(); 444 445 private final Context mContext; 446 private final ConnectivityResources mResources; 447 private final int mWakeUpMark; 448 private final int mWakeUpMask; 449 // The Context is created for UserHandle.ALL. 450 private final Context mUserAllContext; 451 private final Dependencies mDeps; 452 private final ConnectivityFlags mFlags; 453 // 0 is full bad, 100 is full good 454 private int mDefaultInetConditionPublished = 0; 455 456 @VisibleForTesting 457 protected IDnsResolver mDnsResolver; 458 @VisibleForTesting 459 protected INetd mNetd; 460 private DscpPolicyTracker mDscpPolicyTracker = null; 461 private final NetworkStatsManager mStatsManager; 462 private final NetworkPolicyManager mPolicyManager; 463 private final BpfNetMaps mBpfNetMaps; 464 465 /** 466 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple 467 * instances. 468 */ 469 @GuardedBy("mTNSLock") 470 private TestNetworkService mTNS; 471 private final CompanionDeviceManagerProxyService mCdmps; 472 473 private final Object mTNSLock = new Object(); 474 475 private String mCurrentTcpBufferSizes; 476 477 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 478 new Class[] { 479 ConnectivityService.class, 480 NetworkAgent.class, 481 NetworkAgentInfo.class, 482 AutomaticOnOffKeepaliveTracker.class }); 483 484 private enum ReapUnvalidatedNetworks { 485 // Tear down networks that have no chance (e.g. even if validated) of becoming 486 // the highest scoring network satisfying a NetworkRequest. This should be passed when 487 // all networks have been rematched against all NetworkRequests. 488 REAP, 489 // Don't reap networks. This should be passed when some networks have not yet been 490 // rematched against all NetworkRequests. 491 DONT_REAP 492 } 493 494 private enum UnneededFor { 495 LINGER, // Determine whether this network is unneeded and should be lingered. 496 TEARDOWN, // Determine whether this network is unneeded and should be torn down. 497 } 498 499 /** 500 * For per-app preferences, requests contain an int to signify which request 501 * should have priority. The order is passed to netd which will use it together 502 * with UID ranges to generate the corresponding IP rule. This serves to 503 * direct device-originated data traffic of the specific UIDs to the correct 504 * default network for each app. 505 * Order ints passed to netd must be in the 0~999 range. Larger values code for 506 * a lower priority, see {@link NativeUidRangeConfig}. 507 * 508 * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID. 509 * The default request uses PREFERENCE_ORDER_DEFAULT. 510 */ 511 // Used when sending to netd to code for "no order". 512 static final int PREFERENCE_ORDER_NONE = 0; 513 // Order for requests that don't code for a per-app preference. As it is 514 // out of the valid range, the corresponding order should be 515 // PREFERENCE_ORDER_NONE when sending to netd. 516 @VisibleForTesting 517 static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE; 518 // As a security feature, VPNs have the top priority. 519 static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN. 520 // Order of per-app OEM preference. See {@link #setOemNetworkPreference}. 521 @VisibleForTesting 522 static final int PREFERENCE_ORDER_OEM = 10; 523 // Order of per-profile preference, such as used by enterprise networks. 524 // See {@link #setProfileNetworkPreference}. 525 @VisibleForTesting 526 static final int PREFERENCE_ORDER_PROFILE = 20; 527 // Order of user setting to prefer mobile data even when networks with 528 // better scores are connected. 529 // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids} 530 @VisibleForTesting 531 static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30; 532 // Preference order that signifies the network shouldn't be set as a default network for 533 // the UIDs, only give them access to it. TODO : replace this with a boolean 534 // in NativeUidRangeConfig 535 @VisibleForTesting 536 static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999; 537 // Bound for the lowest valid preference order. 538 static final int PREFERENCE_ORDER_LOWEST = 999; 539 540 /** 541 * used internally to clear a wakelock when transitioning 542 * from one net to another. Clear happens when we get a new 543 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 544 * after a timeout if no network is found (typically 1 min). 545 */ 546 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 547 548 /** 549 * used internally to reload global proxy settings 550 */ 551 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 552 553 /** 554 * PAC manager has received new port. 555 */ 556 private static final int EVENT_PAC_PROXY_HAS_CHANGED = 16; 557 558 /** 559 * used internally when registering NetworkProviders 560 * obj = NetworkProviderInfo 561 */ 562 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; 563 564 /** 565 * used internally when registering NetworkAgents 566 * obj = Messenger 567 */ 568 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 569 570 /** 571 * used to add a network request 572 * includes a NetworkRequestInfo 573 */ 574 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 575 576 /** 577 * indicates a timeout period is over - check if we had a network yet or not 578 * and if not, call the timeout callback (but leave the request live until they 579 * cancel it. 580 * includes a NetworkRequestInfo 581 */ 582 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 583 584 /** 585 * used to add a network listener - no request 586 * includes a NetworkRequestInfo 587 */ 588 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 589 590 /** 591 * used to remove a network request, either a listener or a real request 592 * arg1 = UID of caller 593 * obj = NetworkRequest 594 */ 595 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 596 597 /** 598 * used internally when registering NetworkProviders 599 * obj = Messenger 600 */ 601 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; 602 603 /** 604 * used internally to expire a wakelock when transitioning 605 * from one net to another. Expire happens when we fail to find 606 * a new network (typically after 1 minute) - 607 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 608 * a replacement network. 609 */ 610 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 611 612 /** 613 * used to add a network request with a pending intent 614 * obj = NetworkRequestInfo 615 */ 616 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 617 618 /** 619 * used to remove a pending intent and its associated network request. 620 * arg1 = UID of caller 621 * obj = PendingIntent 622 */ 623 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 624 625 /** 626 * used to specify whether a network should be used even if unvalidated. 627 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 628 * arg2 = whether to remember this choice in the future (1 or 0) 629 * obj = network 630 */ 631 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 632 633 /** 634 * used internally to (re)configure always-on networks. 635 */ 636 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; 637 638 /** 639 * used to add a network listener with a pending intent 640 * obj = NetworkRequestInfo 641 */ 642 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 643 644 /** 645 * used to specify whether a network should not be penalized when it becomes unvalidated. 646 */ 647 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 648 649 /** 650 * used to handle reported network connectivity. May trigger revalidation of a network. 651 */ 652 private static final int EVENT_REPORT_NETWORK_CONNECTIVITY = 36; 653 654 // Handle changes in Private DNS settings. 655 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; 656 657 // Handle private DNS validation status updates. 658 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; 659 660 /** 661 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has 662 * been tested. 663 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor. 664 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link 665 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null. 666 */ 667 private static final int EVENT_NETWORK_TESTED = 41; 668 669 /** 670 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS 671 * config was resolved. 672 * obj = PrivateDnsConfig 673 * arg2 = netid 674 */ 675 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42; 676 677 /** 678 * Request ConnectivityService display provisioning notification. 679 * arg1 = Whether to make the notification visible. 680 * arg2 = NetID. 681 * obj = Intent to be launched when notification selected by user, null if !arg1. 682 */ 683 private static final int EVENT_PROVISIONING_NOTIFICATION = 43; 684 685 /** 686 * Used to specify whether a network should be used even if connectivity is partial. 687 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for 688 * false) 689 * arg2 = whether to remember this choice in the future (1 for true or 0 for false) 690 * obj = network 691 */ 692 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44; 693 694 /** 695 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed. 696 * Both of the arguments are bitmasks, and the value of bits come from 697 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*. 698 * arg1 = unused 699 * arg2 = netId 700 * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes. 701 */ 702 public static final int EVENT_PROBE_STATUS_CHANGED = 45; 703 704 /** 705 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed. 706 * arg1 = unused 707 * arg2 = netId 708 * obj = captive portal data 709 */ 710 private static final int EVENT_CAPPORT_DATA_CHANGED = 46; 711 712 /** 713 * Used by setRequireVpnForUids. 714 * arg1 = whether the specified UID ranges are required to use a VPN. 715 * obj = Array of UidRange objects. 716 */ 717 private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47; 718 719 /** 720 * Used internally when setting the default networks for OemNetworkPreferences. 721 * obj = Pair<OemNetworkPreferences, listener> 722 */ 723 private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48; 724 725 /** 726 * Used to indicate the system default network becomes active. 727 */ 728 private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49; 729 730 /** 731 * Used internally when setting a network preference for a user profile. 732 * obj = Pair<ProfileNetworkPreference, Listener> 733 */ 734 private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50; 735 736 /** 737 * Event to specify that reasons for why an uid is blocked changed. 738 * arg1 = uid 739 * arg2 = blockedReasons 740 */ 741 private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51; 742 743 /** 744 * Event to register a new network offer 745 * obj = NetworkOffer 746 */ 747 private static final int EVENT_REGISTER_NETWORK_OFFER = 52; 748 749 /** 750 * Event to unregister an existing network offer 751 * obj = INetworkOfferCallback 752 */ 753 private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53; 754 755 /** 756 * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed. 757 */ 758 private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54; 759 760 /** 761 * Event to set temporary allow bad wifi within a limited time to override 762 * {@code config_networkAvoidBadWifi}. 763 */ 764 private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55; 765 766 /** 767 * Used internally when INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting changes. 768 */ 769 private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56; 770 771 /** 772 * The initial evaluation period is over for this network. 773 * 774 * If no form of connectivity has been found on this network (valid, partial, captive portal) 775 * then the stack will now consider it to have been determined bad. 776 */ 777 private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57; 778 779 /** 780 * Used internally when the user does not want the network from captive portal app. 781 * obj = Network 782 */ 783 private static final int EVENT_USER_DOES_NOT_WANT = 58; 784 785 /** 786 * Event to set VPN as preferred network for specific apps. 787 * obj = VpnNetworkPreferenceInfo 788 */ 789 private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59; 790 791 /** 792 * Event to use low TCP polling timer used in automatic on/off keepalive temporarily. 793 */ 794 private static final int EVENT_SET_LOW_TCP_POLLING_UNTIL = 60; 795 796 /** 797 * Event to inform the ConnectivityService handler when a uid has been frozen or unfrozen. 798 */ 799 private static final int EVENT_UID_FROZEN_STATE_CHANGED = 61; 800 801 /** 802 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 803 * should be shown. 804 */ 805 private static final int PROVISIONING_NOTIFICATION_SHOW = 1; 806 807 /** 808 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification 809 * should be hidden. 810 */ 811 private static final int PROVISIONING_NOTIFICATION_HIDE = 0; 812 813 /** 814 * The maximum alive time to allow bad wifi configuration for testing. 815 */ 816 private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L; 817 818 /** 819 * The maximum alive time to decrease TCP polling timer in automatic on/off keepalive for 820 * testing. 821 */ 822 private static final long MAX_TEST_LOW_TCP_POLLING_UNTIL_MS = 5 * 60 * 1000L; 823 824 /** 825 * The priority of the tc police rate limiter -- smaller value is higher priority. 826 * This value needs to be coordinated with PRIO_CLAT, PRIO_TETHER4, and PRIO_TETHER6. 827 */ 828 private static final short TC_PRIO_POLICE = 1; 829 830 /** 831 * The BPF program attached to the tc-police hook to account for to-be-dropped traffic. 832 */ 833 private static final String TC_POLICE_BPF_PROG_PATH = 834 "/sys/fs/bpf/netd_shared/prog_netd_schedact_ingress_account"; 835 eventName(int what)836 private static String eventName(int what) { 837 return sMagicDecoderRing.get(what, Integer.toString(what)); 838 } 839 getDnsResolver(Context context)840 private static IDnsResolver getDnsResolver(Context context) { 841 final DnsResolverServiceManager dsm = context.getSystemService( 842 DnsResolverServiceManager.class); 843 return IDnsResolver.Stub.asInterface(dsm.getService()); 844 } 845 846 /** Handler thread used for all of the handlers below. */ 847 @VisibleForTesting 848 protected final HandlerThread mHandlerThread; 849 /** Handler used for internal events. */ 850 final private InternalHandler mHandler; 851 /** Handler used for incoming {@link NetworkStateTracker} events. */ 852 final private NetworkStateTrackerHandler mTrackerHandler; 853 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */ 854 @VisibleForTesting 855 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler; 856 857 private final DnsManager mDnsManager; 858 @VisibleForTesting 859 final NetworkRanker mNetworkRanker; 860 861 private boolean mSystemReady; 862 private Intent mInitialBroadcast; 863 864 private final PowerManager.WakeLock mNetTransitionWakeLock; 865 private final PowerManager.WakeLock mPendingIntentWakeLock; 866 867 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell 868 // the world when it changes. 869 private final ProxyTracker mProxyTracker; 870 871 final private SettingsObserver mSettingsObserver; 872 873 private final UserManager mUserManager; 874 875 // the set of network types that can only be enabled by system/sig apps 876 private final List<Integer> mProtectedNetworks; 877 878 private Set<String> mWolSupportedInterfaces; 879 880 private final TelephonyManager mTelephonyManager; 881 private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 882 private final AppOpsManager mAppOpsManager; 883 884 private final LocationPermissionChecker mLocationPermissionChecker; 885 886 private final AutomaticOnOffKeepaliveTracker mKeepaliveTracker; 887 private final QosCallbackTracker mQosCallbackTracker; 888 private final NetworkNotificationManager mNotifier; 889 private final LingerMonitor mLingerMonitor; 890 891 // sequence number of NetworkRequests 892 private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID; 893 894 // Sequence number for NetworkProvider IDs. 895 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( 896 NetworkProvider.FIRST_PROVIDER_ID); 897 898 // NetworkRequest activity String log entries. 899 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 900 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 901 902 // NetworkInfo blocked and unblocked String log entries 903 private static final int MAX_NETWORK_INFO_LOGS = 40; 904 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 905 906 private static final int MAX_WAKELOCK_LOGS = 20; 907 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS); 908 private int mTotalWakelockAcquisitions = 0; 909 private int mTotalWakelockReleases = 0; 910 private long mTotalWakelockDurationMs = 0; 911 private long mMaxWakelockDurationMs = 0; 912 private long mLastWakeLockAcquireTimestamp = 0; 913 914 private final IpConnectivityLog mMetricsLog; 915 916 @GuardedBy("mBandwidthRequests") 917 private final SparseArray<Integer> mBandwidthRequests = new SparseArray<>(10); 918 919 @VisibleForTesting 920 final MultinetworkPolicyTracker mMultinetworkPolicyTracker; 921 922 @VisibleForTesting 923 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks = 924 new HashMap<>(); 925 926 // Rate limit applicable to all internet capable networks (-1 = disabled). This value is 927 // configured via {@link 928 // ConnectivitySettingsManager#INGRESS_RATE_LIMIT_BYTES_PER_SECOND} 929 // Only the handler thread is allowed to access this field. 930 private long mIngressRateLimit = -1; 931 932 // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This 933 // value can be accessed from both handler thread and any random binder thread. Therefore, 934 // accessing this value requires holding a lock. The cache is the same across all the users. 935 @GuardedBy("mSelfCertifiedCapabilityCache") 936 private final Map<String, ApplicationSelfCertifiedNetworkCapabilities> 937 mSelfCertifiedCapabilityCache = new HashMap<>(); 938 939 /** 940 * Implements support for the legacy "one network per network type" model. 941 * 942 * We used to have a static array of NetworkStateTrackers, one for each 943 * network type, but that doesn't work any more now that we can have, 944 * for example, more that one wifi network. This class stores all the 945 * NetworkAgentInfo objects that support a given type, but the legacy 946 * API will only see the first one. 947 * 948 * It serves two main purposes: 949 * 950 * 1. Provide information about "the network for a given type" (since this 951 * API only supports one). 952 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 953 * the first network for a given type changes, or if the default network 954 * changes. 955 */ 956 @VisibleForTesting 957 static class LegacyTypeTracker { 958 959 private static final boolean DBG = true; 960 private static final boolean VDBG = false; 961 962 /** 963 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 964 * Each list holds references to all NetworkAgentInfos that are used to 965 * satisfy requests for that network type. 966 * 967 * This array is built out at startup such that an unsupported network 968 * doesn't get an ArrayList instance, making this a tristate: 969 * unsupported, supported but not active and active. 970 * 971 * The actual lists are populated when we scan the network types that 972 * are supported on this device. 973 * 974 * Threading model: 975 * - addSupportedType() is only called in the constructor 976 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 977 * They are therefore not thread-safe with respect to each other. 978 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 979 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 980 * - getRestoreTimerForType(type) is also synchronized on mTypeLists. 981 * - dump is thread-safe with respect to concurrent add and remove calls. 982 */ 983 private final ArrayList<NetworkAgentInfo>[] mTypeLists; 984 @NonNull 985 private final ConnectivityService mService; 986 987 // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without 988 // an entry have no timer (equivalent to -1). Lazily loaded. 989 @NonNull 990 private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>(); 991 LegacyTypeTracker(@onNull ConnectivityService service)992 LegacyTypeTracker(@NonNull ConnectivityService service) { 993 mService = service; 994 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 995 } 996 997 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is 998 // addressed. 999 @TargetApi(Build.VERSION_CODES.S) loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)1000 public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) { 1001 final PackageManager pm = ctx.getPackageManager(); 1002 if (pm.hasSystemFeature(FEATURE_WIFI)) { 1003 addSupportedType(TYPE_WIFI); 1004 } 1005 if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) { 1006 addSupportedType(TYPE_WIFI_P2P); 1007 } 1008 if (tm.isDataCapable()) { 1009 // Telephony does not have granular support for these types: they are either all 1010 // supported, or none is supported 1011 addSupportedType(TYPE_MOBILE); 1012 addSupportedType(TYPE_MOBILE_MMS); 1013 addSupportedType(TYPE_MOBILE_SUPL); 1014 addSupportedType(TYPE_MOBILE_DUN); 1015 addSupportedType(TYPE_MOBILE_HIPRI); 1016 addSupportedType(TYPE_MOBILE_FOTA); 1017 addSupportedType(TYPE_MOBILE_IMS); 1018 addSupportedType(TYPE_MOBILE_CBS); 1019 addSupportedType(TYPE_MOBILE_IA); 1020 addSupportedType(TYPE_MOBILE_EMERGENCY); 1021 } 1022 if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) { 1023 addSupportedType(TYPE_BLUETOOTH); 1024 } 1025 if (pm.hasSystemFeature(FEATURE_WATCH)) { 1026 // TYPE_PROXY is only used on Wear 1027 addSupportedType(TYPE_PROXY); 1028 } 1029 // Ethernet is often not specified in the configs, although many devices can use it via 1030 // USB host adapters. Add it as long as the ethernet service is here. 1031 if (deviceSupportsEthernet(ctx)) { 1032 addSupportedType(TYPE_ETHERNET); 1033 } 1034 1035 // Always add TYPE_VPN as a supported type 1036 addSupportedType(TYPE_VPN); 1037 } 1038 addSupportedType(int type)1039 private void addSupportedType(int type) { 1040 if (mTypeLists[type] != null) { 1041 throw new IllegalStateException( 1042 "legacy list for type " + type + "already initialized"); 1043 } 1044 mTypeLists[type] = new ArrayList<>(); 1045 } 1046 isTypeSupported(int type)1047 public boolean isTypeSupported(int type) { 1048 return isNetworkTypeValid(type) && mTypeLists[type] != null; 1049 } 1050 getNetworkForType(int type)1051 public NetworkAgentInfo getNetworkForType(int type) { 1052 synchronized (mTypeLists) { 1053 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 1054 return mTypeLists[type].get(0); 1055 } 1056 } 1057 return null; 1058 } 1059 getRestoreTimerForType(int type)1060 public int getRestoreTimerForType(int type) { 1061 synchronized (mTypeLists) { 1062 if (mRestoreTimers == null) { 1063 mRestoreTimers = loadRestoreTimers(); 1064 } 1065 return mRestoreTimers.getOrDefault(type, -1); 1066 } 1067 } 1068 loadRestoreTimers()1069 private ArrayMap<Integer, Integer> loadRestoreTimers() { 1070 final String[] configs = mService.mResources.get().getStringArray( 1071 R.array.config_legacy_networktype_restore_timers); 1072 final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length); 1073 for (final String config : configs) { 1074 final String[] splits = TextUtils.split(config, ","); 1075 if (splits.length != 2) { 1076 logwtf("Invalid restore timer token count: " + config); 1077 continue; 1078 } 1079 try { 1080 ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1])); 1081 } catch (NumberFormatException e) { 1082 logwtf("Invalid restore timer number format: " + config, e); 1083 } 1084 } 1085 return ret; 1086 } 1087 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)1088 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 1089 boolean isDefaultNetwork) { 1090 if (DBG) { 1091 log("Sending " + state 1092 + " broadcast for type " + type + " " + nai.toShortString() 1093 + " isDefaultNetwork=" + isDefaultNetwork); 1094 } 1095 } 1096 1097 // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying 1098 // network type, to preserve previous behaviour. maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)1099 private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) { 1100 if (vpnNai != mService.getLegacyLockdownNai()) return; 1101 1102 if (vpnNai.declaredUnderlyingNetworks == null 1103 || vpnNai.declaredUnderlyingNetworks.length != 1) { 1104 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: " 1105 + Arrays.toString(vpnNai.declaredUnderlyingNetworks)); 1106 return; 1107 } 1108 final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork( 1109 vpnNai.declaredUnderlyingNetworks[0]); 1110 if (underlyingNai == null) return; 1111 1112 final int type = underlyingNai.networkInfo.getType(); 1113 final DetailedState state = DetailedState.CONNECTED; 1114 maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */); 1115 mService.sendLegacyNetworkBroadcast(underlyingNai, state, type); 1116 } 1117 1118 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)1119 public void add(int type, NetworkAgentInfo nai) { 1120 if (!isTypeSupported(type)) { 1121 return; // Invalid network type. 1122 } 1123 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 1124 1125 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1126 if (list.contains(nai)) { 1127 return; 1128 } 1129 synchronized (mTypeLists) { 1130 list.add(nai); 1131 } 1132 1133 // Send a broadcast if this is the first network of its type or if it's the default. 1134 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); 1135 1136 // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts 1137 // to preserve previous behaviour. 1138 final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED); 1139 if ((list.size() == 1) || isDefaultNetwork) { 1140 maybeLogBroadcast(nai, state, type, isDefaultNetwork); 1141 mService.sendLegacyNetworkBroadcast(nai, state, type); 1142 } 1143 1144 if (type == TYPE_VPN && state == DetailedState.CONNECTED) { 1145 maybeSendLegacyLockdownBroadcast(nai); 1146 } 1147 } 1148 1149 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)1150 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 1151 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1152 if (list == null || list.isEmpty()) { 1153 return; 1154 } 1155 final boolean wasFirstNetwork = list.get(0).equals(nai); 1156 1157 synchronized (mTypeLists) { 1158 if (!list.remove(nai)) { 1159 return; 1160 } 1161 } 1162 1163 if (wasFirstNetwork || wasDefault) { 1164 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault); 1165 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type); 1166 } 1167 1168 if (!list.isEmpty() && wasFirstNetwork) { 1169 if (DBG) log("Other network available for type " + type + 1170 ", sending connected broadcast"); 1171 final NetworkAgentInfo replacement = list.get(0); 1172 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type, 1173 mService.isDefaultNetwork(replacement)); 1174 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type); 1175 } 1176 } 1177 1178 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)1179 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 1180 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 1181 for (int type = 0; type < mTypeLists.length; type++) { 1182 remove(type, nai, wasDefault); 1183 } 1184 } 1185 1186 // send out another legacy broadcast - currently only used for suspend/unsuspend toggle update(NetworkAgentInfo nai)1187 public void update(NetworkAgentInfo nai) { 1188 final boolean isDefault = mService.isDefaultNetwork(nai); 1189 final DetailedState state = nai.networkInfo.getDetailedState(); 1190 for (int type = 0; type < mTypeLists.length; type++) { 1191 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 1192 final boolean contains = (list != null && list.contains(nai)); 1193 final boolean isFirst = contains && (nai == list.get(0)); 1194 if (isFirst || contains && isDefault) { 1195 maybeLogBroadcast(nai, state, type, isDefault); 1196 mService.sendLegacyNetworkBroadcast(nai, state, type); 1197 } 1198 } 1199 } 1200 dump(IndentingPrintWriter pw)1201 public void dump(IndentingPrintWriter pw) { 1202 pw.println("mLegacyTypeTracker:"); 1203 pw.increaseIndent(); 1204 pw.print("Supported types:"); 1205 for (int type = 0; type < mTypeLists.length; type++) { 1206 if (mTypeLists[type] != null) pw.print(" " + type); 1207 } 1208 pw.println(); 1209 pw.println("Current state:"); 1210 pw.increaseIndent(); 1211 synchronized (mTypeLists) { 1212 for (int type = 0; type < mTypeLists.length; type++) { 1213 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 1214 for (NetworkAgentInfo nai : mTypeLists[type]) { 1215 pw.println(type + " " + nai.toShortString()); 1216 } 1217 } 1218 } 1219 pw.decreaseIndent(); 1220 pw.decreaseIndent(); 1221 pw.println(); 1222 } 1223 } 1224 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this); 1225 1226 final LocalPriorityDump mPriorityDumper = new LocalPriorityDump(); 1227 /** 1228 * Helper class which parses out priority arguments and dumps sections according to their 1229 * priority. If priority arguments are omitted, function calls the legacy dump command. 1230 */ 1231 private class LocalPriorityDump { 1232 private static final String PRIORITY_ARG = "--dump-priority"; 1233 private static final String PRIORITY_ARG_HIGH = "HIGH"; 1234 private static final String PRIORITY_ARG_NORMAL = "NORMAL"; 1235 LocalPriorityDump()1236 LocalPriorityDump() {} 1237 dumpHigh(FileDescriptor fd, PrintWriter pw)1238 private void dumpHigh(FileDescriptor fd, PrintWriter pw) { 1239 doDump(fd, pw, new String[] {DIAG_ARG}); 1240 doDump(fd, pw, new String[] {SHORT_ARG}); 1241 } 1242 dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1243 private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { 1244 doDump(fd, pw, args); 1245 } 1246 dump(FileDescriptor fd, PrintWriter pw, String[] args)1247 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1248 if (args == null) { 1249 dumpNormal(fd, pw, args); 1250 return; 1251 } 1252 1253 String priority = null; 1254 for (int argIndex = 0; argIndex < args.length; argIndex++) { 1255 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) { 1256 argIndex++; 1257 priority = args[argIndex]; 1258 } 1259 } 1260 1261 if (PRIORITY_ARG_HIGH.equals(priority)) { 1262 dumpHigh(fd, pw); 1263 } else if (PRIORITY_ARG_NORMAL.equals(priority)) { 1264 dumpNormal(fd, pw, args); 1265 } else { 1266 // ConnectivityService publishes binder service using publishBinderService() with 1267 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send 1268 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the 1269 // legacy output for dumpsys connectivity. 1270 // TODO: Integrate into signal dump. 1271 dumpNormal(fd, pw, args); 1272 } 1273 } 1274 } 1275 1276 /** 1277 * Dependencies of ConnectivityService, for injection in tests. 1278 */ 1279 @VisibleForTesting 1280 public static class Dependencies { getCallingUid()1281 public int getCallingUid() { 1282 return Binder.getCallingUid(); 1283 } 1284 isAtLeastS()1285 public boolean isAtLeastS() { 1286 return SdkLevel.isAtLeastS(); 1287 } 1288 isAtLeastT()1289 public boolean isAtLeastT() { 1290 return SdkLevel.isAtLeastT(); 1291 } 1292 isAtLeastU()1293 public boolean isAtLeastU() { 1294 return SdkLevel.isAtLeastU(); 1295 } 1296 1297 /** 1298 * Get system properties to use in ConnectivityService. 1299 */ getSystemProperties()1300 public MockableSystemProperties getSystemProperties() { 1301 return new MockableSystemProperties(); 1302 } 1303 1304 /** 1305 * Get the {@link ConnectivityResources} to use in ConnectivityService. 1306 */ getResources(@onNull Context ctx)1307 public ConnectivityResources getResources(@NonNull Context ctx) { 1308 return new ConnectivityResources(ctx); 1309 } 1310 1311 /** 1312 * Create a HandlerThread to use in ConnectivityService. 1313 */ makeHandlerThread()1314 public HandlerThread makeHandlerThread() { 1315 return new HandlerThread("ConnectivityServiceThread"); 1316 } 1317 1318 /** 1319 * Get a reference to the ModuleNetworkStackClient. 1320 */ getNetworkStack()1321 public NetworkStackClientBase getNetworkStack() { 1322 return ModuleNetworkStackClient.getInstance(null); 1323 } 1324 1325 /** 1326 * @see ProxyTracker 1327 */ makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1328 public ProxyTracker makeProxyTracker(@NonNull Context context, 1329 @NonNull Handler connServiceHandler) { 1330 return new ProxyTracker(context, connServiceHandler, EVENT_PAC_PROXY_HAS_CHANGED); 1331 } 1332 1333 /** 1334 * @see NetIdManager 1335 */ makeNetIdManager()1336 public NetIdManager makeNetIdManager() { 1337 return new NetIdManager(); 1338 } 1339 1340 /** 1341 * @see NetworkUtils#queryUserAccess(int, int) 1342 */ queryUserAccess(int uid, Network network, ConnectivityService cs)1343 public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) { 1344 return cs.queryUserAccess(uid, network); 1345 } 1346 1347 /** 1348 * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets 1349 * requires CAP_NET_ADMIN, which the unit tests do not have. 1350 */ getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1351 public int getConnectionOwnerUid(int protocol, InetSocketAddress local, 1352 InetSocketAddress remote) { 1353 return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote); 1354 } 1355 1356 /** 1357 * @see MultinetworkPolicyTracker 1358 */ makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1359 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( 1360 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { 1361 return new MultinetworkPolicyTracker(c, h, r); 1362 } 1363 1364 /** 1365 * @see AutomaticOnOffKeepaliveTracker 1366 */ makeAutomaticOnOffKeepaliveTracker( @onNull Context c, @NonNull Handler h)1367 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker( 1368 @NonNull Context c, @NonNull Handler h) { 1369 return new AutomaticOnOffKeepaliveTracker(c, h); 1370 } 1371 1372 /** 1373 * @see BatteryStatsManager 1374 */ reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1375 public void reportNetworkInterfaceForTransports(Context context, String iface, 1376 int[] transportTypes) { 1377 final BatteryStatsManager batteryStats = 1378 context.getSystemService(BatteryStatsManager.class); 1379 batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes); 1380 } 1381 getCellular464XlatEnabled()1382 public boolean getCellular464XlatEnabled() { 1383 return NetworkProperties.isCellular464XlatEnabled().orElse(true); 1384 } 1385 1386 /** 1387 * @see PendingIntent#intentFilterEquals 1388 */ intentFilterEquals(PendingIntent a, PendingIntent b)1389 public boolean intentFilterEquals(PendingIntent a, PendingIntent b) { 1390 return a.intentFilterEquals(b); 1391 } 1392 1393 /** 1394 * @see LocationPermissionChecker 1395 */ makeLocationPermissionChecker(Context context)1396 public LocationPermissionChecker makeLocationPermissionChecker(Context context) { 1397 return new LocationPermissionChecker(context); 1398 } 1399 1400 /** 1401 * @see CarrierPrivilegeAuthenticator 1402 * 1403 * This method returns null in versions before T, where carrier privilege 1404 * authentication is not supported. 1405 */ 1406 @Nullable makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm)1407 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 1408 @NonNull final Context context, @NonNull final TelephonyManager tm) { 1409 if (isAtLeastT()) { 1410 return new CarrierPrivilegeAuthenticator(context, tm); 1411 } else { 1412 return null; 1413 } 1414 } 1415 1416 /** 1417 * @see DeviceConfigUtils#isFeatureEnabled 1418 */ isFeatureEnabled(Context context, String name)1419 public boolean isFeatureEnabled(Context context, String name) { 1420 return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_TETHERING, name, 1421 TETHERING_MODULE_NAME, false /* defaultValue */); 1422 } 1423 1424 /** 1425 * Get the BpfNetMaps implementation to use in ConnectivityService. 1426 * @param netd a netd binder 1427 * @return BpfNetMaps implementation. 1428 */ getBpfNetMaps(Context context, INetd netd)1429 public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { 1430 return new BpfNetMaps(context, netd); 1431 } 1432 1433 /** 1434 * @see ClatCoordinator 1435 */ getClatCoordinator(INetd netd)1436 public ClatCoordinator getClatCoordinator(INetd netd) { 1437 return new ClatCoordinator( 1438 new ClatCoordinator.Dependencies() { 1439 @NonNull 1440 public INetd getNetd() { 1441 return netd; 1442 } 1443 }); 1444 } 1445 1446 /** 1447 * Wraps {@link TcUtils#tcFilterAddDevIngressPolice} 1448 */ enableIngressRateLimit(String iface, long rateInBytesPerSecond)1449 public void enableIngressRateLimit(String iface, long rateInBytesPerSecond) { 1450 final InterfaceParams params = InterfaceParams.getByName(iface); 1451 if (params == null) { 1452 // the interface might have disappeared. 1453 logw("Failed to get interface params for interface " + iface); 1454 return; 1455 } 1456 try { 1457 // converting rateInBytesPerSecond from long to int is safe here because the 1458 // setting's range is limited to INT_MAX. 1459 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice. 1460 Log.i(TAG, 1461 "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s"); 1462 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL, 1463 (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH); 1464 } catch (IOException e) { 1465 loge("TcUtils.tcFilterAddDevIngressPolice(ifaceIndex=" + params.index 1466 + ", PRIO_POLICE, ETH_P_ALL, rateInBytesPerSecond=" 1467 + rateInBytesPerSecond + ", bpfProgPath=" + TC_POLICE_BPF_PROG_PATH 1468 + ") failure: ", e); 1469 } 1470 } 1471 1472 /** 1473 * Wraps {@link TcUtils#tcFilterDelDev} 1474 */ disableIngressRateLimit(String iface)1475 public void disableIngressRateLimit(String iface) { 1476 final InterfaceParams params = InterfaceParams.getByName(iface); 1477 if (params == null) { 1478 // the interface might have disappeared. 1479 logw("Failed to get interface params for interface " + iface); 1480 return; 1481 } 1482 try { 1483 Log.i(TAG, 1484 "disableIngressRateLimit on " + iface); 1485 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL); 1486 } catch (IOException e) { 1487 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index 1488 + ", ingress=true, PRIO_POLICE, ETH_P_ALL) failure: ", e); 1489 } 1490 } 1491 1492 /** 1493 * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)} 1494 */ 1495 // TODO: when available in all active branches: 1496 // @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 1497 @RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT) makeBroadcastOptionsShim(BroadcastOptions options)1498 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 1499 return BroadcastOptionsShimImpl.newInstance(options); 1500 } 1501 1502 /** 1503 * Wrapper method for 1504 * {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}. 1505 * 1506 * @param changeId The ID of the compatibility change in question. 1507 * @param packageName The package name of the app in question. 1508 * @param user The user that the operation is done for. 1509 * @return {@code true} if the change is enabled for the specified package. 1510 */ isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)1511 public boolean isChangeEnabled(long changeId, @NonNull final String packageName, 1512 @NonNull final UserHandle user) { 1513 return CompatChanges.isChangeEnabled(changeId, packageName, user); 1514 } 1515 1516 /** 1517 * As above but with a UID. 1518 * @see CompatChanges#isChangeEnabled(long, int) 1519 */ isChangeEnabled(final long changeId, final int uid)1520 public boolean isChangeEnabled(final long changeId, final int uid) { 1521 return CompatChanges.isChangeEnabled(changeId, uid); 1522 } 1523 1524 /** 1525 * Call {@link InetDiagMessage#destroyLiveTcpSockets(Set, Set)} 1526 * 1527 * @param ranges target uid ranges 1528 * @param exemptUids uids to skip close socket 1529 */ destroyLiveTcpSockets(@onNull final Set<Range<Integer>> ranges, @NonNull final Set<Integer> exemptUids)1530 public void destroyLiveTcpSockets(@NonNull final Set<Range<Integer>> ranges, 1531 @NonNull final Set<Integer> exemptUids) 1532 throws SocketException, InterruptedIOException, ErrnoException { 1533 InetDiagMessage.destroyLiveTcpSockets(ranges, exemptUids); 1534 } 1535 1536 /** 1537 * Call {@link InetDiagMessage#destroyLiveTcpSocketsByOwnerUids(Set)} 1538 * 1539 * @param ownerUids target uids to close sockets 1540 */ destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)1541 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) 1542 throws SocketException, InterruptedIOException, ErrnoException { 1543 InetDiagMessage.destroyLiveTcpSocketsByOwnerUids(ownerUids); 1544 } 1545 1546 /** 1547 * Schedule the evaluation timeout. 1548 * 1549 * When a network connects, it's "not evaluated" yet. Detection events cause the network 1550 * to be "evaluated" (typically, validation or detection of a captive portal). If none 1551 * of these events happen, this time will run out, after which the network is considered 1552 * "evaluated" even if nothing happened to it. Notionally that means the system gave up 1553 * on this network and considers it won't provide connectivity. In particular, that means 1554 * it's when the system prefers it to cell if it's wifi and configuration says it should 1555 * prefer bad wifi to cell. 1556 */ scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)1557 public void scheduleEvaluationTimeout(@NonNull Handler handler, 1558 @NonNull final Network network, final long delayMs) { 1559 handler.sendMessageDelayed( 1560 handler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs); 1561 } 1562 } 1563 1564 public ConnectivityService(Context context) { 1565 this(context, getDnsResolver(context), new IpConnectivityLog(), 1566 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), 1567 new Dependencies()); 1568 } 1569 1570 @VisibleForTesting 1571 protected ConnectivityService(Context context, IDnsResolver dnsresolver, 1572 IpConnectivityLog logger, INetd netd, Dependencies deps) { 1573 if (DBG) log("ConnectivityService starting up"); 1574 1575 mDeps = Objects.requireNonNull(deps, "missing Dependencies"); 1576 mFlags = new ConnectivityFlags(); 1577 mSystemProperties = mDeps.getSystemProperties(); 1578 mNetIdManager = mDeps.makeNetIdManager(); 1579 mContext = Objects.requireNonNull(context, "missing Context"); 1580 mResources = deps.getResources(mContext); 1581 // The legacy PerUidCounter is buggy and throwing exception at count == limit. 1582 // Pass limit - 1 to maintain backward compatibility. 1583 // TODO: Remove the workaround. 1584 mNetworkRequestCounter = 1585 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_UID - 1); 1586 mSystemNetworkRequestCounter = 1587 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1); 1588 1589 mMetricsLog = logger; 1590 final NetworkRequest defaultInternetRequest = createDefaultRequest(); 1591 mDefaultRequest = new NetworkRequestInfo( 1592 Process.myUid(), defaultInternetRequest, null, 1593 null /* binder */, NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1594 null /* attributionTags */); 1595 mNetworkRequests.put(defaultInternetRequest, mDefaultRequest); 1596 mDefaultNetworkRequests.add(mDefaultRequest); 1597 mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest); 1598 1599 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( 1600 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); 1601 1602 // The default WiFi request is a background request so that apps using WiFi are 1603 // migrated to a better network (typically ethernet) when one comes up, instead 1604 // of staying on WiFi forever. 1605 mDefaultWifiRequest = createDefaultInternetRequestForTransport( 1606 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); 1607 1608 mDefaultVehicleRequest = createAlwaysOnRequestForCapability( 1609 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL, 1610 NetworkRequest.Type.BACKGROUND_REQUEST); 1611 1612 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 1613 // TODO: Consider making the timer customizable. 1614 mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS; 1615 mCellularRadioTimesharingCapable = 1616 mResources.get().getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1617 1618 int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark); 1619 int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask); 1620 1621 if (SdkLevel.isAtLeastU()) { 1622 // U+ default value of both mark & mask, this is the top bit of the skb->mark, 1623 // see //system/netd/include/FwMark.h union Fwmark, field ingress_cpu_wakeup 1624 final int defaultUMarkMask = 0x80000000; // u32 1625 1626 if ((mark == 0) || (mask == 0)) { 1627 // simply treat unset/disabled as the default U value 1628 mark = defaultUMarkMask; 1629 mask = defaultUMarkMask; 1630 } 1631 if ((mark != defaultUMarkMask) || (mask != defaultUMarkMask)) { 1632 // invalid device overlay settings 1633 throw new IllegalArgumentException( 1634 "Bad config_networkWakeupPacketMark/Mask " + mark + "/" + mask); 1635 } 1636 } 1637 1638 mWakeUpMark = mark; 1639 mWakeUpMask = mask; 1640 1641 mNetd = netd; 1642 mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd); 1643 mHandlerThread = mDeps.makeHandlerThread(); 1644 mPermissionMonitor = 1645 new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mHandlerThread); 1646 mHandlerThread.start(); 1647 mHandler = new InternalHandler(mHandlerThread.getLooper()); 1648 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 1649 mConnectivityDiagnosticsHandler = 1650 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper()); 1651 1652 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 1653 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 1654 1655 mStatsManager = mContext.getSystemService(NetworkStatsManager.class); 1656 mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); 1657 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver"); 1658 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); 1659 1660 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1661 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 1662 mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); 1663 mCarrierPrivilegeAuthenticator = 1664 mDeps.makeCarrierPrivilegeAuthenticator(mContext, mTelephonyManager); 1665 1666 // To ensure uid state is synchronized with Network Policy, register for 1667 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService 1668 // reading existing policy from disk. 1669 mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback); 1670 1671 final PowerManager powerManager = (PowerManager) context.getSystemService( 1672 Context.POWER_SERVICE); 1673 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1674 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1675 1676 mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager); 1677 mProtectedNetworks = new ArrayList<>(); 1678 int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks); 1679 for (int p : protectedNetworks) { 1680 if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) { 1681 mProtectedNetworks.add(p); 1682 } else { 1683 if (DBG) loge("Ignoring protectedNetwork " + p); 1684 } 1685 } 1686 1687 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 1688 1689 mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */); 1690 // Listen for user add/removes to inform PermissionMonitor. 1691 // Should run on mHandler to avoid any races. 1692 final IntentFilter userIntentFilter = new IntentFilter(); 1693 userIntentFilter.addAction(Intent.ACTION_USER_ADDED); 1694 userIntentFilter.addAction(Intent.ACTION_USER_REMOVED); 1695 mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter, 1696 null /* broadcastPermission */, mHandler); 1697 1698 // Listen to package add/removes for netd 1699 final IntentFilter packageIntentFilter = new IntentFilter(); 1700 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 1701 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1702 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 1703 packageIntentFilter.addDataScheme("package"); 1704 mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter, 1705 null /* broadcastPermission */, mHandler); 1706 1707 mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd); 1708 1709 final NetdCallback netdCallback = new NetdCallback(); 1710 try { 1711 mNetd.registerUnsolicitedEventListener(netdCallback); 1712 } catch (RemoteException | ServiceSpecificException e) { 1713 loge("Error registering event listener :" + e); 1714 } 1715 1716 mSettingsObserver = new SettingsObserver(mContext, mHandler); 1717 registerSettingsCallbacks(); 1718 1719 mKeepaliveTracker = mDeps.makeAutomaticOnOffKeepaliveTracker(mContext, mHandler); 1720 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager); 1721 mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter); 1722 1723 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 1724 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 1725 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 1726 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 1727 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 1728 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 1729 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 1730 1731 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( 1732 mContext, mHandler, () -> updateAvoidBadWifi()); 1733 mNetworkRanker = 1734 new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi())); 1735 1736 mMultinetworkPolicyTracker.start(); 1737 1738 mDnsManager = new DnsManager(mContext, mDnsResolver); 1739 registerPrivateDnsSettingsCallbacks(); 1740 1741 // This NAI is a sentinel used to offer no service to apps that are on a multi-layer 1742 // request that doesn't allow fallback to the default network. It should never be visible 1743 // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal 1744 // arguments like the handler or the DnsResolver. 1745 // TODO : remove this ; it is probably better handled with a sentinel request. 1746 mNoServiceNetwork = new NetworkAgentInfo(null, 1747 new Network(INetd.UNREACHABLE_NET_ID), 1748 new NetworkInfo(TYPE_NONE, 0, "", ""), 1749 new LinkProperties(), new NetworkCapabilities(), 1750 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, 1751 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, 1752 mLingerDelayMs, mQosCallbackTracker, mDeps); 1753 1754 try { 1755 // DscpPolicyTracker cannot run on S because on S the tethering module can only load 1756 // BPF programs/maps into /sys/fs/tethering/bpf, which the system server cannot access. 1757 // Even if it could, running on S would at least require mocking out the BPF map, 1758 // otherwise the unit tests will fail on pre-T devices where the seccomp filter blocks 1759 // the bpf syscall. http://aosp/1907693 1760 if (mDeps.isAtLeastT()) { 1761 mDscpPolicyTracker = new DscpPolicyTracker(); 1762 } 1763 } catch (ErrnoException e) { 1764 loge("Unable to create DscpPolicyTracker"); 1765 } 1766 1767 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 1768 mContext); 1769 1770 if (mDeps.isAtLeastT()) { 1771 mCdmps = new CompanionDeviceManagerProxyService(context); 1772 } else { 1773 mCdmps = null; 1774 } 1775 1776 if (mDeps.isAtLeastU() 1777 && mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION)) { 1778 final UidFrozenStateChangedCallback frozenStateChangedCallback = 1779 new UidFrozenStateChangedCallback() { 1780 @Override 1781 public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) { 1782 if (uids.length != frozenStates.length) { 1783 Log.wtf(TAG, "uids has length " + uids.length 1784 + " but frozenStates has length " + frozenStates.length); 1785 return; 1786 } 1787 1788 final UidFrozenStateChangedArgs args = 1789 new UidFrozenStateChangedArgs(uids, frozenStates); 1790 1791 mHandler.sendMessage( 1792 mHandler.obtainMessage(EVENT_UID_FROZEN_STATE_CHANGED, args)); 1793 } 1794 }; 1795 1796 final ActivityManager activityManager = 1797 mContext.getSystemService(ActivityManager.class); 1798 activityManager.registerUidFrozenStateChangedCallback( 1799 (Runnable r) -> r.run(), frozenStateChangedCallback); 1800 } 1801 } 1802 1803 /** 1804 * Check whether or not the device supports Ethernet transport. 1805 */ 1806 public static boolean deviceSupportsEthernet(final Context context) { 1807 final PackageManager pm = context.getPackageManager(); 1808 return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET) 1809 || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST); 1810 } 1811 1812 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { 1813 return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton( 1814 new UidRange(uid, uid))); 1815 } 1816 1817 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet( 1818 @NonNull final Set<UidRange> uidRangeSet) { 1819 final NetworkCapabilities netCap = new NetworkCapabilities(); 1820 netCap.addCapability(NET_CAPABILITY_INTERNET); 1821 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 1822 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 1823 netCap.setUids(UidRange.toIntRanges(uidRangeSet)); 1824 return netCap; 1825 } 1826 1827 private NetworkRequest createDefaultRequest() { 1828 return createDefaultInternetRequestForTransport( 1829 TYPE_NONE, NetworkRequest.Type.REQUEST); 1830 } 1831 1832 private NetworkRequest createVpnRequest() { 1833 final NetworkCapabilities netCap = new NetworkCapabilities.Builder() 1834 .withoutDefaultCapabilities() 1835 .addTransportType(TRANSPORT_VPN) 1836 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 1837 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 1838 .build(); 1839 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 1840 return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap); 1841 } 1842 1843 private NetworkRequest createDefaultInternetRequestForTransport( 1844 int transportType, NetworkRequest.Type type) { 1845 final NetworkCapabilities netCap = new NetworkCapabilities(); 1846 netCap.addCapability(NET_CAPABILITY_INTERNET); 1847 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 1848 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 1849 if (transportType > TYPE_NONE) { 1850 netCap.addTransportType(transportType); 1851 } 1852 return createNetworkRequest(type, netCap); 1853 } 1854 1855 private NetworkRequest createNetworkRequest( 1856 NetworkRequest.Type type, NetworkCapabilities netCap) { 1857 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 1858 } 1859 1860 private NetworkRequest createAlwaysOnRequestForCapability(int capability, 1861 NetworkRequest.Type type) { 1862 final NetworkCapabilities netCap = new NetworkCapabilities(); 1863 netCap.clearAll(); 1864 netCap.addCapability(capability); 1865 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 1866 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); 1867 } 1868 1869 // Used only for testing. 1870 // TODO: Delete this and either: 1871 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires 1872 // changing ContentResolver to make registerContentObserver non-final). 1873 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 1874 // by subclassing SettingsObserver. 1875 @VisibleForTesting 1876 void updateAlwaysOnNetworks() { 1877 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1878 } 1879 1880 // See FakeSettingsProvider comment above. 1881 @VisibleForTesting 1882 void updatePrivateDnsSettings() { 1883 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1884 } 1885 1886 @VisibleForTesting 1887 void updateMobileDataPreferredUids() { 1888 mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 1889 } 1890 1891 @VisibleForTesting 1892 void updateIngressRateLimit() { 1893 mHandler.sendEmptyMessage(EVENT_INGRESS_RATE_LIMIT_CHANGED); 1894 } 1895 1896 @VisibleForTesting 1897 void simulateUpdateProxyInfo(@Nullable final Network network, 1898 @NonNull final ProxyInfo proxyInfo) { 1899 Message.obtain(mHandler, EVENT_PAC_PROXY_HAS_CHANGED, 1900 new Pair<>(network, proxyInfo)).sendToTarget(); 1901 } 1902 1903 private void handleAlwaysOnNetworkRequest( 1904 NetworkRequest networkRequest, String settingName, boolean defaultValue) { 1905 final boolean enable = toBool(Settings.Global.getInt( 1906 mContext.getContentResolver(), settingName, encodeBool(defaultValue))); 1907 handleAlwaysOnNetworkRequest(networkRequest, enable); 1908 } 1909 1910 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) { 1911 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); 1912 if (enable == isEnabled) { 1913 return; // Nothing to do. 1914 } 1915 1916 if (enable) { 1917 handleRegisterNetworkRequest(new NetworkRequestInfo( 1918 Process.myUid(), networkRequest, null /* messenger */, null /* binder */, 1919 NetworkCallback.FLAG_INCLUDE_LOCATION_INFO, 1920 null /* attributionTags */)); 1921 } else { 1922 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, 1923 /* callOnUnavailable */ false); 1924 } 1925 } 1926 1927 private void handleConfigureAlwaysOnNetworks() { 1928 handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest, 1929 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */); 1930 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, 1931 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */); 1932 final boolean vehicleAlwaysRequested = mResources.get().getBoolean( 1933 R.bool.config_vehicleInternalNetworkAlwaysRequested); 1934 handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested); 1935 } 1936 1937 // Note that registering observer for setting do not get initial callback when registering, 1938 // callers must fetch the initial value of the setting themselves if needed. 1939 private void registerSettingsCallbacks() { 1940 // Watch for global HTTP proxy changes. 1941 mSettingsObserver.observe( 1942 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 1943 EVENT_APPLY_GLOBAL_HTTP_PROXY); 1944 1945 // Watch for whether to keep mobile data always on. 1946 mSettingsObserver.observe( 1947 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON), 1948 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1949 1950 // Watch for whether to keep wifi always on. 1951 mSettingsObserver.observe( 1952 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED), 1953 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); 1954 1955 // Watch for mobile data preferred uids changes. 1956 mSettingsObserver.observe( 1957 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS), 1958 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); 1959 1960 // Watch for ingress rate limit changes. 1961 mSettingsObserver.observe( 1962 Settings.Global.getUriFor( 1963 ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND), 1964 EVENT_INGRESS_RATE_LIMIT_CHANGED); 1965 } 1966 1967 private void registerPrivateDnsSettingsCallbacks() { 1968 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { 1969 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); 1970 } 1971 } 1972 1973 private synchronized int nextNetworkRequestId() { 1974 // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if 1975 // doing that. 1976 return mNextNetworkRequestId++; 1977 } 1978 1979 @VisibleForTesting 1980 @Nullable 1981 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 1982 if (network == null) { 1983 return null; 1984 } 1985 return getNetworkAgentInfoForNetId(network.getNetId()); 1986 } 1987 1988 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { 1989 synchronized (mNetworkForNetId) { 1990 return mNetworkForNetId.get(netId); 1991 } 1992 } 1993 1994 // TODO: determine what to do when more than one VPN applies to |uid|. 1995 @Nullable 1996 private NetworkAgentInfo getVpnForUid(int uid) { 1997 synchronized (mNetworkForNetId) { 1998 for (int i = 0; i < mNetworkForNetId.size(); i++) { 1999 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 2000 if (nai.isVPN() && nai.everConnected() 2001 && nai.networkCapabilities.appliesToUid(uid)) { 2002 return nai; 2003 } 2004 } 2005 } 2006 return null; 2007 } 2008 2009 @Nullable 2010 private Network[] getVpnUnderlyingNetworks(int uid) { 2011 if (mLockdownEnabled) return null; 2012 final NetworkAgentInfo nai = getVpnForUid(uid); 2013 if (nai != null) return nai.declaredUnderlyingNetworks; 2014 return null; 2015 } 2016 2017 private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) { 2018 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2019 2020 final Network[] networks = getVpnUnderlyingNetworks(uid); 2021 if (networks != null) { 2022 // getUnderlyingNetworks() returns: 2023 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 2024 // empty array => the VPN explicitly said "no default network". 2025 // non-empty array => the VPN specified one or more default networks; we use the 2026 // first one. 2027 if (networks.length > 0) { 2028 nai = getNetworkAgentInfoForNetwork(networks[0]); 2029 } else { 2030 nai = null; 2031 } 2032 } 2033 return nai; 2034 } 2035 2036 /** 2037 * Check if UID should be blocked from using the specified network. 2038 */ 2039 private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc, 2040 final int uid, final boolean ignoreBlocked) { 2041 // Networks aren't blocked when ignoring blocked status 2042 if (ignoreBlocked) { 2043 return false; 2044 } 2045 if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true; 2046 final long ident = Binder.clearCallingIdentity(); 2047 try { 2048 final boolean metered = nc == null ? true : nc.isMetered(); 2049 return mPolicyManager.isUidNetworkingBlocked(uid, metered); 2050 } finally { 2051 Binder.restoreCallingIdentity(ident); 2052 } 2053 } 2054 2055 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 2056 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 2057 return; 2058 } 2059 final boolean blocked; 2060 synchronized (mBlockedAppUids) { 2061 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 2062 blocked = true; 2063 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 2064 blocked = false; 2065 } else { 2066 return; 2067 } 2068 } 2069 String action = blocked ? "BLOCKED" : "UNBLOCKED"; 2070 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid)); 2071 mNetworkInfoBlockingLogs.log(action + " " + uid); 2072 } 2073 2074 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) { 2075 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { 2076 return; 2077 } 2078 final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED"; 2079 final int requestId = nri.getActiveRequest() != null 2080 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId; 2081 mNetworkInfoBlockingLogs.log(String.format( 2082 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(), 2083 Integer.toHexString(blocked))); 2084 } 2085 2086 /** 2087 * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For 2088 * example, this may mark the network as {@link DetailedState#BLOCKED} based 2089 * on {@link #isNetworkWithCapabilitiesBlocked}. 2090 */ 2091 @NonNull 2092 private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type, 2093 @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) { 2094 final NetworkInfo filtered = new NetworkInfo(networkInfo); 2095 // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network 2096 // but only exists if an app asks about them or requests them. Ensure the requesting app 2097 // gets the type it asks for. 2098 filtered.setType(type); 2099 if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) { 2100 filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */, 2101 null /* extraInfo */); 2102 } 2103 filterForLegacyLockdown(filtered); 2104 return filtered; 2105 } 2106 2107 private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid, 2108 boolean ignoreBlocked) { 2109 return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), 2110 nai.networkCapabilities, uid, ignoreBlocked); 2111 } 2112 2113 /** 2114 * Return NetworkInfo for the active (i.e., connected) network interface. 2115 * It is assumed that at most one network is active at a time. If more 2116 * than one is active, it is indeterminate which will be returned. 2117 * @return the info for the active network, or {@code null} if none is 2118 * active 2119 */ 2120 @Override 2121 @Nullable 2122 public NetworkInfo getActiveNetworkInfo() { 2123 enforceAccessPermission(); 2124 final int uid = mDeps.getCallingUid(); 2125 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2126 if (nai == null) return null; 2127 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 2128 maybeLogBlockedNetworkInfo(networkInfo, uid); 2129 return networkInfo; 2130 } 2131 2132 @Override 2133 @Nullable 2134 public Network getActiveNetwork() { 2135 enforceAccessPermission(); 2136 return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false); 2137 } 2138 2139 @Override 2140 @Nullable 2141 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 2142 enforceNetworkStackPermission(mContext); 2143 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 2144 } 2145 2146 @Nullable 2147 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 2148 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 2149 if (vpnNai != null) { 2150 final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid); 2151 if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) { 2152 return vpnNai.network; 2153 } 2154 } 2155 2156 NetworkAgentInfo nai = getDefaultNetworkForUid(uid); 2157 if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, 2158 ignoreBlocked)) { 2159 return null; 2160 } 2161 return nai.network; 2162 } 2163 2164 @Override 2165 @Nullable 2166 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 2167 enforceNetworkStackPermission(mContext); 2168 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2169 if (nai == null) return null; 2170 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2171 } 2172 2173 /** Returns a NetworkInfo object for a network that doesn't exist. */ 2174 private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) { 2175 final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */, 2176 getNetworkTypeName(networkType), "" /* subtypeName */); 2177 info.setIsAvailable(true); 2178 // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when 2179 // background data is restricted. 2180 final NetworkCapabilities nc = new NetworkCapabilities(); // Metered. 2181 final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false) 2182 ? DetailedState.BLOCKED 2183 : DetailedState.DISCONNECTED; 2184 info.setDetailedState(state, null /* reason */, null /* extraInfo */); 2185 filterForLegacyLockdown(info); 2186 return info; 2187 } 2188 2189 private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) { 2190 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2191 return null; 2192 } 2193 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2194 if (nai == null) { 2195 return makeFakeNetworkInfo(networkType, uid); 2196 } 2197 return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid, 2198 false); 2199 } 2200 2201 @Override 2202 @Nullable 2203 public NetworkInfo getNetworkInfo(int networkType) { 2204 enforceAccessPermission(); 2205 final int uid = mDeps.getCallingUid(); 2206 if (getVpnUnderlyingNetworks(uid) != null) { 2207 // A VPN is active, so we may need to return one of its underlying networks. This 2208 // information is not available in LegacyTypeTracker, so we have to get it from 2209 // getNetworkAgentInfoForUid. 2210 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2211 if (nai == null) return null; 2212 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false); 2213 if (networkInfo.getType() == networkType) { 2214 return networkInfo; 2215 } 2216 } 2217 return getFilteredNetworkInfoForType(networkType, uid); 2218 } 2219 2220 @Override 2221 @Nullable 2222 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 2223 enforceAccessPermission(); 2224 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2225 if (nai == null) return null; 2226 return getFilteredNetworkInfo(nai, uid, ignoreBlocked); 2227 } 2228 2229 @Override 2230 public NetworkInfo[] getAllNetworkInfo() { 2231 enforceAccessPermission(); 2232 final ArrayList<NetworkInfo> result = new ArrayList<>(); 2233 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 2234 networkType++) { 2235 NetworkInfo info = getNetworkInfo(networkType); 2236 if (info != null) { 2237 result.add(info); 2238 } 2239 } 2240 return result.toArray(new NetworkInfo[result.size()]); 2241 } 2242 2243 @Override 2244 @Nullable 2245 public Network getNetworkForType(int networkType) { 2246 enforceAccessPermission(); 2247 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2248 return null; 2249 } 2250 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2251 if (nai == null) { 2252 return null; 2253 } 2254 final int uid = mDeps.getCallingUid(); 2255 if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) { 2256 return null; 2257 } 2258 return nai.network; 2259 } 2260 2261 @Override 2262 @NonNull 2263 public Network[] getAllNetworks() { 2264 enforceAccessPermission(); 2265 synchronized (mNetworkForNetId) { 2266 final Network[] result = new Network[mNetworkForNetId.size()]; 2267 for (int i = 0; i < mNetworkForNetId.size(); i++) { 2268 result[i] = mNetworkForNetId.valueAt(i).network; 2269 } 2270 return result; 2271 } 2272 } 2273 2274 @Override 2275 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser( 2276 int userId, String callingPackageName, @Nullable String callingAttributionTag) { 2277 // The basic principle is: if an app's traffic could possibly go over a 2278 // network, without the app doing anything multinetwork-specific, 2279 // (hence, by "default"), then include that network's capabilities in 2280 // the array. 2281 // 2282 // In the normal case, app traffic only goes over the system's default 2283 // network connection, so that's the only network returned. 2284 // 2285 // With a VPN in force, some app traffic may go into the VPN, and thus 2286 // over whatever underlying networks the VPN specifies, while other app 2287 // traffic may go over the system default network (e.g.: a split-tunnel 2288 // VPN, or an app disallowed by the VPN), so the set of networks 2289 // returned includes the VPN's underlying networks and the system 2290 // default. 2291 enforceAccessPermission(); 2292 2293 HashMap<Network, NetworkCapabilities> result = new HashMap<>(); 2294 2295 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 2296 if (!nri.isBeingSatisfied()) { 2297 continue; 2298 } 2299 final NetworkAgentInfo nai = nri.getSatisfier(); 2300 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 2301 if (null != nc 2302 && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 2303 && !result.containsKey(nai.network)) { 2304 result.put( 2305 nai.network, 2306 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2307 nc, false /* includeLocationSensitiveInfo */, 2308 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2309 callingAttributionTag)); 2310 } 2311 } 2312 2313 // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null. 2314 final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid()); 2315 if (null != networks) { 2316 for (final Network network : networks) { 2317 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 2318 if (null != nc) { 2319 result.put( 2320 network, 2321 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2322 nc, 2323 false /* includeLocationSensitiveInfo */, 2324 getCallingPid(), mDeps.getCallingUid(), callingPackageName, 2325 callingAttributionTag)); 2326 } 2327 } 2328 } 2329 2330 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 2331 out = result.values().toArray(out); 2332 return out; 2333 } 2334 2335 @Override 2336 public boolean isNetworkSupported(int networkType) { 2337 enforceAccessPermission(); 2338 return mLegacyTypeTracker.isTypeSupported(networkType); 2339 } 2340 2341 /** 2342 * Return LinkProperties for the active (i.e., connected) default 2343 * network interface for the calling uid. 2344 * @return the ip properties for the active network, or {@code null} if 2345 * none is active 2346 */ 2347 @Override 2348 public LinkProperties getActiveLinkProperties() { 2349 enforceAccessPermission(); 2350 final int uid = mDeps.getCallingUid(); 2351 NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid); 2352 if (nai == null) return null; 2353 return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties, 2354 Binder.getCallingPid(), uid); 2355 } 2356 2357 @Override 2358 public LinkProperties getLinkPropertiesForType(int networkType) { 2359 enforceAccessPermission(); 2360 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2361 final LinkProperties lp = getLinkProperties(nai); 2362 if (lp == null) return null; 2363 return linkPropertiesRestrictedForCallerPermissions( 2364 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2365 } 2366 2367 // TODO - this should be ALL networks 2368 @Override 2369 public LinkProperties getLinkProperties(Network network) { 2370 enforceAccessPermission(); 2371 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network)); 2372 if (lp == null) return null; 2373 return linkPropertiesRestrictedForCallerPermissions( 2374 lp, Binder.getCallingPid(), mDeps.getCallingUid()); 2375 } 2376 2377 @Nullable 2378 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) { 2379 if (nai == null) { 2380 return null; 2381 } 2382 synchronized (nai) { 2383 return nai.linkProperties; 2384 } 2385 } 2386 2387 @Override 2388 @Nullable 2389 public LinkProperties getRedactedLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid, 2390 @NonNull String packageName, @Nullable String callingAttributionTag) { 2391 Objects.requireNonNull(packageName); 2392 Objects.requireNonNull(lp); 2393 enforceNetworkStackOrSettingsPermission(); 2394 if (!checkAccessPermission(-1 /* pid */, uid)) { 2395 return null; 2396 } 2397 return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid); 2398 } 2399 2400 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) { 2401 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 2402 } 2403 2404 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 2405 if (nai == null) return null; 2406 synchronized (nai) { 2407 return networkCapabilitiesRestrictedForCallerPermissions( 2408 nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid()); 2409 } 2410 } 2411 2412 @Override 2413 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName, 2414 @Nullable String callingAttributionTag) { 2415 mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName); 2416 enforceAccessPermission(); 2417 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2418 getNetworkCapabilitiesInternal(network), 2419 false /* includeLocationSensitiveInfo */, 2420 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag); 2421 } 2422 2423 @Override 2424 public NetworkCapabilities getRedactedNetworkCapabilitiesForPackage( 2425 @NonNull NetworkCapabilities nc, int uid, @NonNull String packageName, 2426 @Nullable String callingAttributionTag) { 2427 Objects.requireNonNull(nc); 2428 Objects.requireNonNull(packageName); 2429 enforceNetworkStackOrSettingsPermission(); 2430 if (!checkAccessPermission(-1 /* pid */, uid)) { 2431 return null; 2432 } 2433 return createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2434 networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid), 2435 true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName, 2436 callingAttributionTag); 2437 } 2438 2439 private void redactUnderlyingNetworksForCapabilities(NetworkCapabilities nc, int pid, int uid) { 2440 if (nc.getUnderlyingNetworks() != null 2441 && !checkNetworkFactoryOrSettingsPermission(pid, uid)) { 2442 nc.setUnderlyingNetworks(null); 2443 } 2444 } 2445 2446 @VisibleForTesting 2447 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( 2448 NetworkCapabilities nc, int callerPid, int callerUid) { 2449 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 2450 // this would be expensive (one more permission check every time any NC callback is 2451 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 2452 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 2453 // send the callback) it would crash the system server with NPE. 2454 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 2455 if (!checkSettingsPermission(callerPid, callerUid)) { 2456 newNc.setUids(null); 2457 newNc.setSSID(null); 2458 } 2459 if (newNc.getNetworkSpecifier() != null) { 2460 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); 2461 } 2462 if (!checkAnyPermissionOf(mContext, callerPid, callerUid, 2463 android.Manifest.permission.NETWORK_STACK, 2464 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) { 2465 newNc.setAdministratorUids(new int[0]); 2466 } 2467 if (!checkAnyPermissionOf(mContext, 2468 callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) { 2469 newNc.setAllowedUids(new ArraySet<>()); 2470 newNc.setSubscriptionIds(Collections.emptySet()); 2471 } 2472 redactUnderlyingNetworksForCapabilities(newNc, callerPid, callerUid); 2473 2474 return newNc; 2475 } 2476 2477 /** 2478 * Wrapper used to cache the permission check results performed for the corresponding 2479 * app. This avoids performing multiple permission checks for different fields in 2480 * NetworkCapabilities. 2481 * Note: This wrapper does not support any sort of invalidation and thus must not be 2482 * persistent or long-lived. It may only be used for the time necessary to 2483 * compute the redactions required by one particular NetworkCallback or 2484 * synchronous call. 2485 */ 2486 private class RedactionPermissionChecker { 2487 private final int mCallingPid; 2488 private final int mCallingUid; 2489 @NonNull private final String mCallingPackageName; 2490 @Nullable private final String mCallingAttributionTag; 2491 2492 private Boolean mHasLocationPermission = null; 2493 private Boolean mHasLocalMacAddressPermission = null; 2494 private Boolean mHasSettingsPermission = null; 2495 2496 RedactionPermissionChecker(int callingPid, int callingUid, 2497 @NonNull String callingPackageName, @Nullable String callingAttributionTag) { 2498 mCallingPid = callingPid; 2499 mCallingUid = callingUid; 2500 mCallingPackageName = callingPackageName; 2501 mCallingAttributionTag = callingAttributionTag; 2502 } 2503 2504 private boolean hasLocationPermissionInternal() { 2505 final long token = Binder.clearCallingIdentity(); 2506 try { 2507 return mLocationPermissionChecker.checkLocationPermission( 2508 mCallingPackageName, mCallingAttributionTag, mCallingUid, 2509 null /* message */); 2510 } finally { 2511 Binder.restoreCallingIdentity(token); 2512 } 2513 } 2514 2515 /** 2516 * Returns whether the app holds location permission or not (might return cached result 2517 * if the permission was already checked before). 2518 */ 2519 public boolean hasLocationPermission() { 2520 if (mHasLocationPermission == null) { 2521 // If there is no cached result, perform the check now. 2522 mHasLocationPermission = hasLocationPermissionInternal(); 2523 } 2524 return mHasLocationPermission; 2525 } 2526 2527 /** 2528 * Returns whether the app holds local mac address permission or not (might return cached 2529 * result if the permission was already checked before). 2530 */ 2531 public boolean hasLocalMacAddressPermission() { 2532 if (mHasLocalMacAddressPermission == null) { 2533 // If there is no cached result, perform the check now. 2534 mHasLocalMacAddressPermission = 2535 checkLocalMacAddressPermission(mCallingPid, mCallingUid); 2536 } 2537 return mHasLocalMacAddressPermission; 2538 } 2539 2540 /** 2541 * Returns whether the app holds settings permission or not (might return cached 2542 * result if the permission was already checked before). 2543 */ 2544 public boolean hasSettingsPermission() { 2545 if (mHasSettingsPermission == null) { 2546 // If there is no cached result, perform the check now. 2547 mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid); 2548 } 2549 return mHasSettingsPermission; 2550 } 2551 } 2552 2553 private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions, 2554 @NetworkCapabilities.NetCapability long redaction) { 2555 return (redactions & redaction) != 0; 2556 } 2557 2558 /** 2559 * Use the provided |applicableRedactions| to check the receiving app's 2560 * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask 2561 * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities 2562 * before being sent to the corresponding app. 2563 */ 2564 private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions( 2565 @NetworkCapabilities.RedactionType long applicableRedactions, 2566 @NonNull RedactionPermissionChecker redactionPermissionChecker, 2567 boolean includeLocationSensitiveInfo) { 2568 long redactions = applicableRedactions; 2569 if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) { 2570 if (includeLocationSensitiveInfo 2571 && redactionPermissionChecker.hasLocationPermission()) { 2572 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION; 2573 } 2574 } 2575 if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) { 2576 if (redactionPermissionChecker.hasLocalMacAddressPermission()) { 2577 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS; 2578 } 2579 } 2580 if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) { 2581 if (redactionPermissionChecker.hasSettingsPermission()) { 2582 redactions &= ~REDACT_FOR_NETWORK_SETTINGS; 2583 } 2584 } 2585 return redactions; 2586 } 2587 2588 @VisibleForTesting 2589 @Nullable 2590 NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled( 2591 @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo, 2592 int callingPid, int callingUid, @NonNull String callingPkgName, 2593 @Nullable String callingAttributionTag) { 2594 if (nc == null) { 2595 return null; 2596 } 2597 // Avoid doing location permission check if the transport info has no location sensitive 2598 // data. 2599 final RedactionPermissionChecker redactionPermissionChecker = 2600 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName, 2601 callingAttributionTag); 2602 final long redactions = retrieveRequiredRedactions( 2603 nc.getApplicableRedactions(), redactionPermissionChecker, 2604 includeLocationSensitiveInfo); 2605 final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions); 2606 // Reset owner uid if not destined for the owner app. 2607 // TODO : calling UID is redacted because apps should generally not know what UID is 2608 // bringing up the VPN, but this should not apply to some very privileged apps like settings 2609 if (callingUid != nc.getOwnerUid()) { 2610 newNc.setOwnerUid(INVALID_UID); 2611 return newNc; 2612 } 2613 // Allow VPNs to see ownership of their own VPN networks - not location sensitive. 2614 if (nc.hasTransport(TRANSPORT_VPN)) { 2615 // Owner UIDs already checked above. No need to re-check. 2616 return newNc; 2617 } 2618 // If the calling does not want location sensitive data & target SDK >= S, then mask info. 2619 // Else include the owner UID iff the calling has location permission to provide backwards 2620 // compatibility for older apps. 2621 if (!includeLocationSensitiveInfo 2622 && isTargetSdkAtleast( 2623 Build.VERSION_CODES.S, callingUid, callingPkgName)) { 2624 newNc.setOwnerUid(INVALID_UID); 2625 return newNc; 2626 } 2627 // Reset owner uid if the app has no location permission. 2628 if (!redactionPermissionChecker.hasLocationPermission()) { 2629 newNc.setOwnerUid(INVALID_UID); 2630 } 2631 return newNc; 2632 } 2633 2634 @NonNull 2635 private LinkProperties linkPropertiesRestrictedForCallerPermissions( 2636 LinkProperties lp, int callerPid, int callerUid) { 2637 if (lp == null) return new LinkProperties(); 2638 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but 2639 // this would be expensive (one more permission check every time any LP callback is 2640 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if 2641 // it happens for some reason (e.g. the package is uninstalled while CS is trying to 2642 // send the callback) it would crash the system server with NPE. 2643 2644 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls. 2645 final boolean needsSanitization = 2646 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null); 2647 if (!needsSanitization) { 2648 return new LinkProperties(lp); 2649 } 2650 2651 if (checkSettingsPermission(callerPid, callerUid)) { 2652 return new LinkProperties(lp, true /* parcelSensitiveFields */); 2653 } 2654 2655 final LinkProperties newLp = new LinkProperties(lp); 2656 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the 2657 // object gets parceled. 2658 newLp.setCaptivePortalApiUrl(null); 2659 newLp.setCaptivePortalData(null); 2660 return newLp; 2661 } 2662 2663 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, 2664 int callerUid, String callerPackageName) { 2665 // There is no need to track the effective UID of the request here. If the caller 2666 // lacks the settings permission, the effective UID is the same as the calling ID. 2667 if (!checkSettingsPermission()) { 2668 // Unprivileged apps can only pass in null or their own UID. 2669 if (nc.getUids() == null) { 2670 // If the caller passes in null, the callback will also match networks that do not 2671 // apply to its UID, similarly to what it would see if it called getAllNetworks. 2672 // In this case, redact everything in the request immediately. This ensures that the 2673 // app is not able to get any redacted information by filing an unredacted request 2674 // and observing whether the request matches something. 2675 if (nc.getNetworkSpecifier() != null) { 2676 nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact()); 2677 } 2678 } else { 2679 nc.setSingleUid(callerUid); 2680 } 2681 } 2682 nc.setRequestorUidAndPackageName(callerUid, callerPackageName); 2683 nc.setAdministratorUids(new int[0]); 2684 2685 // Clear owner UID; this can never come from an app. 2686 nc.setOwnerUid(INVALID_UID); 2687 } 2688 2689 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) { 2690 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) { 2691 nc.addCapability(NET_CAPABILITY_FOREGROUND); 2692 } 2693 } 2694 2695 @Override 2696 public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() { 2697 enforceAccessPermission(); 2698 final int callerUid = Binder.getCallingUid(); 2699 final long token = Binder.clearCallingIdentity(); 2700 try { 2701 return mPolicyManager.getRestrictBackgroundStatus(callerUid); 2702 } finally { 2703 Binder.restoreCallingIdentity(token); 2704 } 2705 } 2706 2707 // TODO: Consider delete this function or turn it into a no-op method. 2708 @Override 2709 public NetworkState[] getAllNetworkState() { 2710 // This contains IMSI details, so make sure the caller is privileged. 2711 enforceNetworkStackPermission(mContext); 2712 2713 final ArrayList<NetworkState> result = new ArrayList<>(); 2714 for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) { 2715 // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the 2716 // NetworkAgentInfo. 2717 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork()); 2718 if (nai != null && nai.networkInfo.isConnected()) { 2719 result.add(new NetworkState(new NetworkInfo(nai.networkInfo), 2720 snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(), 2721 snapshot.getNetwork(), snapshot.getSubscriberId())); 2722 } 2723 } 2724 return result.toArray(new NetworkState[0]); 2725 } 2726 2727 @Override 2728 @NonNull 2729 public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() { 2730 // This contains IMSI details, so make sure the caller is privileged. 2731 enforceNetworkStackOrSettingsPermission(); 2732 2733 final ArrayList<NetworkStateSnapshot> result = new ArrayList<>(); 2734 for (Network network : getAllNetworks()) { 2735 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2736 final boolean includeNetwork = (nai != null) && nai.isCreated(); 2737 if (includeNetwork) { 2738 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the 2739 // NetworkCapabilities, which may contain UIDs of apps to which the 2740 // network applies. Should the UIDs be cleared so as not to leak or 2741 // interfere ? 2742 result.add(nai.getNetworkStateSnapshot()); 2743 } 2744 } 2745 return result; 2746 } 2747 2748 @Override 2749 public boolean isActiveNetworkMetered() { 2750 enforceAccessPermission(); 2751 2752 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork()); 2753 if (caps != null) { 2754 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 2755 } else { 2756 // Always return the most conservative value 2757 return true; 2758 } 2759 } 2760 2761 /** 2762 * Ensures that the system cannot call a particular method. 2763 */ 2764 private boolean disallowedBecauseSystemCaller() { 2765 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling 2766 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost 2767 // for devices launched with Q and above. However, existing devices upgrading to Q and 2768 // above must continued to be supported for few more releases. 2769 if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt( 2770 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) { 2771 log("This method exists only for app backwards compatibility" 2772 + " and must not be called by system services."); 2773 return true; 2774 } 2775 return false; 2776 } 2777 2778 private int getAppUid(final String app, final UserHandle user) { 2779 final PackageManager pm = 2780 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 2781 final long token = Binder.clearCallingIdentity(); 2782 try { 2783 return pm.getPackageUid(app, 0 /* flags */); 2784 } catch (PackageManager.NameNotFoundException e) { 2785 return -1; 2786 } finally { 2787 Binder.restoreCallingIdentity(token); 2788 } 2789 } 2790 2791 private void verifyCallingUidAndPackage(String packageName, int callingUid) { 2792 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 2793 if (getAppUid(packageName, user) != callingUid) { 2794 throw new SecurityException(packageName + " does not belong to uid " + callingUid); 2795 } 2796 } 2797 2798 /** 2799 * Ensure that a network route exists to deliver traffic to the specified 2800 * host via the specified network interface. 2801 * @param networkType the type of the network over which traffic to the 2802 * specified host is to be routed 2803 * @param hostAddress the IP address of the host to which the route is 2804 * desired 2805 * @return {@code true} on success, {@code false} on failure 2806 */ 2807 @Override 2808 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, 2809 String callingPackageName, String callingAttributionTag) { 2810 if (disallowedBecauseSystemCaller()) { 2811 return false; 2812 } 2813 verifyCallingUidAndPackage(callingPackageName, mDeps.getCallingUid()); 2814 enforceChangePermission(callingPackageName, callingAttributionTag); 2815 if (mProtectedNetworks.contains(networkType)) { 2816 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 2817 } 2818 2819 InetAddress addr; 2820 try { 2821 addr = InetAddress.getByAddress(hostAddress); 2822 } catch (UnknownHostException e) { 2823 if (DBG) log("requestRouteToHostAddress got " + e); 2824 return false; 2825 } 2826 2827 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 2828 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 2829 return false; 2830 } 2831 2832 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 2833 if (nai == null) { 2834 if (!mLegacyTypeTracker.isTypeSupported(networkType)) { 2835 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 2836 } else { 2837 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 2838 } 2839 return false; 2840 } 2841 2842 DetailedState netState; 2843 synchronized (nai) { 2844 netState = nai.networkInfo.getDetailedState(); 2845 } 2846 2847 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 2848 if (VDBG) { 2849 log("requestRouteToHostAddress on down network " 2850 + "(" + networkType + ") - dropped" 2851 + " netState=" + netState); 2852 } 2853 return false; 2854 } 2855 2856 final int uid = mDeps.getCallingUid(); 2857 final long token = Binder.clearCallingIdentity(); 2858 try { 2859 LinkProperties lp; 2860 int netId; 2861 synchronized (nai) { 2862 lp = nai.linkProperties; 2863 netId = nai.network.getNetId(); 2864 } 2865 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 2866 if (DBG) { 2867 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok); 2868 } 2869 return ok; 2870 } finally { 2871 Binder.restoreCallingIdentity(token); 2872 } 2873 } 2874 2875 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 2876 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 2877 if (bestRoute == null) { 2878 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 2879 } else { 2880 String iface = bestRoute.getInterface(); 2881 if (bestRoute.getGateway().equals(addr)) { 2882 // if there is no better route, add the implied hostroute for our gateway 2883 bestRoute = RouteInfo.makeHostRoute(addr, iface); 2884 } else { 2885 // if we will connect to this through another route, add a direct route 2886 // to it's gateway 2887 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 2888 } 2889 } 2890 if (DBG) log("Adding legacy route " + bestRoute + 2891 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 2892 2893 final String dst = bestRoute.getDestinationLinkAddress().toString(); 2894 final String nextHop = bestRoute.hasGateway() 2895 ? bestRoute.getGateway().getHostAddress() : ""; 2896 try { 2897 mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid); 2898 } catch (RemoteException | ServiceSpecificException e) { 2899 if (DBG) loge("Exception trying to add a route: " + e); 2900 return false; 2901 } 2902 return true; 2903 } 2904 2905 class DnsResolverUnsolicitedEventCallback extends 2906 IDnsResolverUnsolicitedEventListener.Stub { 2907 @Override 2908 public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { 2909 try { 2910 mHandler.sendMessage(mHandler.obtainMessage( 2911 EVENT_PRIVATE_DNS_VALIDATION_UPDATE, 2912 new PrivateDnsValidationUpdate(event.netId, 2913 InetAddresses.parseNumericAddress(event.ipAddress), 2914 event.hostname, event.validation))); 2915 } catch (IllegalArgumentException e) { 2916 loge("Error parsing ip address in validation event"); 2917 } 2918 } 2919 2920 @Override 2921 public void onDnsHealthEvent(final DnsHealthEventParcel event) { 2922 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); 2923 // Netd event only allow registrants from system. Each NetworkMonitor thread is under 2924 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd 2925 // event callback for certain nai. e.g. cellular. Register here to pass to 2926 // NetworkMonitor instead. 2927 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allows one 2928 // callback from each caller type. Need to re-factor NetdEventListenerService to allow 2929 // multiple NetworkMonitor registrants. 2930 if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { 2931 nai.networkMonitor().notifyDnsResponse(event.healthResult); 2932 } 2933 } 2934 2935 @Override 2936 public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { 2937 mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, 2938 event.prefixAddress, event.prefixLength)); 2939 } 2940 2941 @Override 2942 public int getInterfaceVersion() { 2943 return this.VERSION; 2944 } 2945 2946 @Override 2947 public String getInterfaceHash() { 2948 return this.HASH; 2949 } 2950 } 2951 2952 @VisibleForTesting 2953 protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = 2954 new DnsResolverUnsolicitedEventCallback(); 2955 2956 private void registerDnsResolverUnsolicitedEventListener() { 2957 try { 2958 mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); 2959 } catch (Exception e) { 2960 loge("Error registering DnsResolver unsolicited event callback: " + e); 2961 } 2962 } 2963 2964 private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() { 2965 @Override 2966 public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 2967 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED, 2968 uid, blockedReasons)); 2969 } 2970 }; 2971 2972 private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) { 2973 maybeNotifyNetworkBlockedForNewState(uid, blockedReasons); 2974 setUidBlockedReasons(uid, blockedReasons); 2975 } 2976 2977 static final class UidFrozenStateChangedArgs { 2978 final int[] mUids; 2979 final int[] mFrozenStates; 2980 2981 UidFrozenStateChangedArgs(int[] uids, int[] frozenStates) { 2982 mUids = uids; 2983 mFrozenStates = frozenStates; 2984 } 2985 } 2986 2987 private void handleFrozenUids(int[] uids, int[] frozenStates) { 2988 final ArraySet<Range<Integer>> ranges = new ArraySet<>(); 2989 2990 for (int i = 0; i < uids.length; i++) { 2991 if (frozenStates[i] == UID_FROZEN_STATE_FROZEN) { 2992 Integer uidAsInteger = Integer.valueOf(uids[i]); 2993 ranges.add(new Range(uidAsInteger, uidAsInteger)); 2994 } 2995 } 2996 2997 if (!ranges.isEmpty()) { 2998 final Set<Integer> exemptUids = new ArraySet<>(); 2999 try { 3000 mDeps.destroyLiveTcpSockets(ranges, exemptUids); 3001 } catch (Exception e) { 3002 loge("Exception in socket destroy: " + e); 3003 } 3004 } 3005 } 3006 3007 @VisibleForTesting 3008 static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version"; 3009 3010 private void enforceInternetPermission() { 3011 mContext.enforceCallingOrSelfPermission( 3012 android.Manifest.permission.INTERNET, 3013 "ConnectivityService"); 3014 } 3015 3016 private void enforceAccessPermission() { 3017 mContext.enforceCallingOrSelfPermission( 3018 android.Manifest.permission.ACCESS_NETWORK_STATE, 3019 "ConnectivityService"); 3020 } 3021 3022 private boolean checkAccessPermission(int pid, int uid) { 3023 return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid) 3024 == PERMISSION_GRANTED; 3025 } 3026 3027 /** 3028 * Performs a strict and comprehensive check of whether a calling package is allowed to 3029 * change the state of network, as the condition differs for pre-M, M+, and 3030 * privileged/preinstalled apps. The caller is expected to have either the 3031 * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these 3032 * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and 3033 * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal 3034 * permission and cannot be revoked. See http://b/23597341 3035 * 3036 * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation 3037 * of this app will be updated to the current time. 3038 */ 3039 private void enforceChangePermission(String callingPkg, String callingAttributionTag) { 3040 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) 3041 == PackageManager.PERMISSION_GRANTED) { 3042 return; 3043 } 3044 3045 if (callingPkg == null) { 3046 throw new SecurityException("Calling package name is null."); 3047 } 3048 3049 final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class); 3050 final int uid = mDeps.getCallingUid(); 3051 final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid, 3052 callingPkg, callingAttributionTag, null /* message */); 3053 3054 if (mode == AppOpsManager.MODE_ALLOWED) { 3055 return; 3056 } 3057 3058 if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission( 3059 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) { 3060 return; 3061 } 3062 3063 throw new SecurityException(callingPkg + " was not granted either of these permissions:" 3064 + android.Manifest.permission.CHANGE_NETWORK_STATE + "," 3065 + android.Manifest.permission.WRITE_SETTINGS + "."); 3066 } 3067 3068 private void enforceSettingsPermission() { 3069 enforceAnyPermissionOf(mContext, 3070 android.Manifest.permission.NETWORK_SETTINGS, 3071 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3072 } 3073 3074 private void enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission() { 3075 enforceAnyPermissionOf(mContext, 3076 android.Manifest.permission.NETWORK_SETTINGS, 3077 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3078 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3079 Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS); 3080 } 3081 3082 private void enforceNetworkFactoryPermission() { 3083 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3084 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3085 enforceAnyPermissionOf(mContext, 3086 android.Manifest.permission.NETWORK_FACTORY, 3087 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3088 } 3089 3090 private void enforceNetworkFactoryOrSettingsPermission() { 3091 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3092 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3093 enforceAnyPermissionOf(mContext, 3094 android.Manifest.permission.NETWORK_SETTINGS, 3095 android.Manifest.permission.NETWORK_FACTORY, 3096 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3097 } 3098 3099 private void enforceNetworkFactoryOrTestNetworksPermission() { 3100 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. 3101 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; 3102 enforceAnyPermissionOf(mContext, 3103 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3104 android.Manifest.permission.NETWORK_FACTORY, 3105 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3106 } 3107 3108 private boolean checkNetworkFactoryOrSettingsPermission(int pid, int uid) { 3109 return PERMISSION_GRANTED == mContext.checkPermission( 3110 android.Manifest.permission.NETWORK_FACTORY, pid, uid) 3111 || PERMISSION_GRANTED == mContext.checkPermission( 3112 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3113 || PERMISSION_GRANTED == mContext.checkPermission( 3114 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid) 3115 || UserHandle.getAppId(uid) == Process.BLUETOOTH_UID; 3116 } 3117 3118 private boolean checkSettingsPermission() { 3119 return PermissionUtils.checkAnyPermissionOf(mContext, 3120 android.Manifest.permission.NETWORK_SETTINGS, 3121 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3122 } 3123 3124 private boolean checkSettingsPermission(int pid, int uid) { 3125 return PERMISSION_GRANTED == mContext.checkPermission( 3126 android.Manifest.permission.NETWORK_SETTINGS, pid, uid) 3127 || PERMISSION_GRANTED == mContext.checkPermission( 3128 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid); 3129 } 3130 3131 private void enforceNetworkStackOrSettingsPermission() { 3132 enforceNetworkStackPermissionOr(mContext, 3133 android.Manifest.permission.NETWORK_SETTINGS); 3134 } 3135 3136 private void enforceNetworkStackSettingsOrSetup() { 3137 enforceNetworkStackPermissionOr(mContext, 3138 android.Manifest.permission.NETWORK_SETTINGS, 3139 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3140 } 3141 3142 private void enforceAirplaneModePermission() { 3143 enforceNetworkStackPermissionOr(mContext, 3144 android.Manifest.permission.NETWORK_AIRPLANE_MODE, 3145 android.Manifest.permission.NETWORK_SETTINGS, 3146 android.Manifest.permission.NETWORK_SETUP_WIZARD); 3147 } 3148 3149 private void enforceOemNetworkPreferencesPermission() { 3150 mContext.enforceCallingOrSelfPermission( 3151 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, 3152 "ConnectivityService"); 3153 } 3154 3155 private void enforceManageTestNetworksPermission() { 3156 mContext.enforceCallingOrSelfPermission( 3157 android.Manifest.permission.MANAGE_TEST_NETWORKS, 3158 "ConnectivityService"); 3159 } 3160 3161 private boolean checkNetworkStackPermission() { 3162 return PermissionUtils.checkAnyPermissionOf(mContext, 3163 android.Manifest.permission.NETWORK_STACK, 3164 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3165 } 3166 3167 private boolean checkNetworkStackPermission(int pid, int uid) { 3168 return checkAnyPermissionOf(mContext, pid, uid, 3169 android.Manifest.permission.NETWORK_STACK, 3170 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); 3171 } 3172 3173 private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { 3174 return checkAnyPermissionOf(mContext, pid, uid, 3175 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, 3176 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3177 android.Manifest.permission.NETWORK_SETTINGS); 3178 } 3179 3180 private boolean checkConnectivityRestrictedNetworksPermission(int callingUid, 3181 boolean checkUidsAllowedList) { 3182 if (PermissionUtils.checkAnyPermissionOf(mContext, 3183 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)) { 3184 return true; 3185 } 3186 3187 // fallback to ConnectivityInternalPermission 3188 // TODO: Remove this fallback check after all apps have declared 3189 // CONNECTIVITY_USE_RESTRICTED_NETWORKS. 3190 if (PermissionUtils.checkAnyPermissionOf(mContext, 3191 android.Manifest.permission.CONNECTIVITY_INTERNAL)) { 3192 return true; 3193 } 3194 3195 // Check whether uid is in allowed on restricted networks list. 3196 if (checkUidsAllowedList 3197 && mPermissionMonitor.isUidAllowedOnRestrictedNetworks(callingUid)) { 3198 return true; 3199 } 3200 return false; 3201 } 3202 3203 private void enforceConnectivityRestrictedNetworksPermission(boolean checkUidsAllowedList) { 3204 final int callingUid = mDeps.getCallingUid(); 3205 if (!checkConnectivityRestrictedNetworksPermission(callingUid, checkUidsAllowedList)) { 3206 throw new SecurityException("ConnectivityService: user " + callingUid 3207 + " has no permission to access restricted network."); 3208 } 3209 } 3210 3211 private void enforceKeepalivePermission() { 3212 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 3213 } 3214 3215 private boolean checkLocalMacAddressPermission(int pid, int uid) { 3216 return PERMISSION_GRANTED == mContext.checkPermission( 3217 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid); 3218 } 3219 3220 private void sendConnectedBroadcast(NetworkInfo info) { 3221 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 3222 } 3223 3224 private void sendInetConditionBroadcast(NetworkInfo info) { 3225 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 3226 } 3227 3228 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 3229 Intent intent = new Intent(bcastType); 3230 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 3231 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 3232 if (info.isFailover()) { 3233 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 3234 info.setFailover(false); 3235 } 3236 if (info.getReason() != null) { 3237 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 3238 } 3239 if (info.getExtraInfo() != null) { 3240 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 3241 info.getExtraInfo()); 3242 } 3243 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 3244 return intent; 3245 } 3246 3247 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 3248 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 3249 } 3250 3251 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 3252 @SuppressLint("NewApi") 3253 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 3254 @TargetApi(Build.VERSION_CODES.S) 3255 private void sendStickyBroadcast(Intent intent) { 3256 synchronized (this) { 3257 if (!mSystemReady 3258 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 3259 mInitialBroadcast = new Intent(intent); 3260 } 3261 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3262 if (VDBG) { 3263 log("sendStickyBroadcast: action=" + intent.getAction()); 3264 } 3265 3266 Bundle options = null; 3267 final long ident = Binder.clearCallingIdentity(); 3268 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 3269 final NetworkInfo ni = intent.getParcelableExtra( 3270 ConnectivityManager.EXTRA_NETWORK_INFO); 3271 final BroadcastOptions opts = BroadcastOptions.makeBasic(); 3272 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 3273 applyMostRecentPolicyForConnectivityAction(opts, ni); 3274 options = opts.toBundle(); 3275 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 3276 } 3277 try { 3278 mUserAllContext.sendStickyBroadcast(intent, options); 3279 } finally { 3280 Binder.restoreCallingIdentity(ident); 3281 } 3282 } 3283 } 3284 3285 private void applyMostRecentPolicyForConnectivityAction(BroadcastOptions options, 3286 NetworkInfo info) { 3287 // Delivery group policy APIs are only available on U+. 3288 if (!mDeps.isAtLeastU()) return; 3289 3290 final BroadcastOptionsShim optsShim = mDeps.makeBroadcastOptionsShim(options); 3291 try { 3292 // This allows us to discard older broadcasts still waiting to be delivered 3293 // which have the same namespace and key. 3294 optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT); 3295 optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION, 3296 createDeliveryGroupKeyForConnectivityAction(info)); 3297 optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE); 3298 } catch (UnsupportedApiLevelException e) { 3299 Log.wtf(TAG, "Using unsupported API" + e); 3300 } 3301 } 3302 3303 @VisibleForTesting 3304 static String createDeliveryGroupKeyForConnectivityAction(NetworkInfo info) { 3305 final StringBuilder sb = new StringBuilder(); 3306 sb.append(info.getType()).append(DELIVERY_GROUP_KEY_DELIMITER); 3307 sb.append(info.getSubtype()).append(DELIVERY_GROUP_KEY_DELIMITER); 3308 sb.append(info.getExtraInfo()); 3309 return sb.toString(); 3310 } 3311 3312 /** 3313 * Called by SystemServer through ConnectivityManager when the system is ready. 3314 */ 3315 @Override 3316 public void systemReady() { 3317 if (mDeps.getCallingUid() != Process.SYSTEM_UID) { 3318 throw new SecurityException("Calling Uid is not system uid."); 3319 } 3320 systemReadyInternal(); 3321 } 3322 3323 /** 3324 * Called when ConnectivityService can initialize remaining components. 3325 */ 3326 @VisibleForTesting 3327 public void systemReadyInternal() { 3328 // Load flags after PackageManager is ready to query module version 3329 mFlags.loadFlags(mDeps, mContext); 3330 3331 // Since mApps in PermissionMonitor needs to be populated first to ensure that 3332 // listening network request which is sent by MultipathPolicyTracker won't be added 3333 // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must 3334 // be called after PermissionMonitor#startMonitoring(). 3335 // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the 3336 // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady() 3337 // to ensure the tracking will be initialized correctly. 3338 final ConditionVariable startMonitoringDone = new ConditionVariable(); 3339 mHandler.post(() -> { 3340 mPermissionMonitor.startMonitoring(); 3341 startMonitoringDone.open(); 3342 }); 3343 mProxyTracker.loadGlobalProxy(); 3344 registerDnsResolverUnsolicitedEventListener(); 3345 3346 synchronized (this) { 3347 mSystemReady = true; 3348 if (mInitialBroadcast != null) { 3349 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 3350 mInitialBroadcast = null; 3351 } 3352 } 3353 3354 // Create network requests for always-on networks. 3355 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); 3356 3357 // Update mobile data preference if necessary. 3358 // Note that updating can be skipped here if the list is empty only because no uid 3359 // rules are applied before system ready. Normally, the empty uid list means to clear 3360 // the uids rules on netd. 3361 if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) { 3362 updateMobileDataPreferredUids(); 3363 } 3364 3365 // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom 3366 if (mDeps.isAtLeastT()) { 3367 mBpfNetMaps.setPullAtomCallback(mContext); 3368 } 3369 // Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't 3370 // have permission problem. While CV#block() is unbounded in time and can in principle block 3371 // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which 3372 // could have blocked forever too. 3373 startMonitoringDone.block(); 3374 } 3375 3376 /** 3377 * Start listening for default data network activity state changes. 3378 */ 3379 @Override 3380 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 3381 mNetworkActivityTracker.registerNetworkActivityListener(l); 3382 } 3383 3384 /** 3385 * Stop listening for default data network activity state changes. 3386 */ 3387 @Override 3388 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 3389 mNetworkActivityTracker.unregisterNetworkActivityListener(l); 3390 } 3391 3392 /** 3393 * Check whether the default network radio is currently active. 3394 */ 3395 @Override 3396 public boolean isDefaultNetworkActive() { 3397 return mNetworkActivityTracker.isDefaultNetworkActive(); 3398 } 3399 3400 /** 3401 * Reads the network specific MTU size from resources. 3402 * and set it on it's iface. 3403 */ 3404 private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 3405 final String iface = newLp.getInterfaceName(); 3406 final int mtu = newLp.getMtu(); 3407 if (mtu == 0) { 3408 // Silently ignore unset MTU value. 3409 return; 3410 } 3411 if (oldLp != null && newLp.isIdenticalMtu(oldLp) 3412 && TextUtils.equals(oldLp.getInterfaceName(), iface)) { 3413 if (VDBG) log("identical MTU and iface - not setting"); 3414 return; 3415 } 3416 // Cannot set MTU without interface name 3417 if (TextUtils.isEmpty(iface)) { 3418 if (VDBG) log("Setting MTU size with null iface."); 3419 return; 3420 } 3421 3422 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) { 3423 loge("Unexpected mtu value: " + mtu + ", " + iface); 3424 return; 3425 } 3426 3427 try { 3428 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); 3429 mNetd.interfaceSetMtu(iface, mtu); 3430 } catch (RemoteException | ServiceSpecificException e) { 3431 loge("exception in interfaceSetMtu()" + e); 3432 } 3433 } 3434 3435 @VisibleForTesting 3436 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 3437 3438 private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) { 3439 String[] values = null; 3440 if (tcpBufferSizes != null) { 3441 values = tcpBufferSizes.split(","); 3442 } 3443 3444 if (values == null || values.length != 6) { 3445 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 3446 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 3447 values = tcpBufferSizes.split(","); 3448 } 3449 3450 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 3451 3452 try { 3453 if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes); 3454 3455 String rmemValues = String.join(" ", values[0], values[1], values[2]); 3456 String wmemValues = String.join(" ", values[3], values[4], values[5]); 3457 mNetd.setTcpRWmemorySize(rmemValues, wmemValues); 3458 mCurrentTcpBufferSizes = tcpBufferSizes; 3459 } catch (RemoteException | ServiceSpecificException e) { 3460 loge("Can't set TCP buffer sizes:" + e); 3461 } 3462 } 3463 3464 @Override 3465 public int getRestoreDefaultNetworkDelay(int networkType) { 3466 String restoreDefaultNetworkDelayStr = mSystemProperties.get( 3467 NETWORK_RESTORE_DELAY_PROP_NAME); 3468 if(restoreDefaultNetworkDelayStr != null && 3469 restoreDefaultNetworkDelayStr.length() != 0) { 3470 try { 3471 return Integer.parseInt(restoreDefaultNetworkDelayStr); 3472 } catch (NumberFormatException e) { 3473 } 3474 } 3475 // if the system property isn't set, use the value for the apn type 3476 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 3477 3478 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 3479 ret = mLegacyTypeTracker.getRestoreTimerForType(networkType); 3480 } 3481 return ret; 3482 } 3483 3484 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 3485 final List<NetworkDiagnostics> netDiags = new ArrayList<>(); 3486 final long DIAG_TIME_MS = 5000; 3487 for (NetworkAgentInfo nai : networksSortedById()) { 3488 PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network); 3489 // Start gathering diagnostic information. 3490 netDiags.add(new NetworkDiagnostics( 3491 nai.network, 3492 new LinkProperties(nai.linkProperties), // Must be a copy. 3493 privateDnsCfg, 3494 DIAG_TIME_MS)); 3495 } 3496 3497 for (NetworkDiagnostics netDiag : netDiags) { 3498 pw.println(); 3499 netDiag.waitForMeasurements(); 3500 netDiag.dump(pw); 3501 } 3502 } 3503 3504 @Override 3505 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, 3506 @Nullable String[] args) { 3507 if (!checkDumpPermission(mContext, TAG, writer)) return; 3508 3509 mPriorityDumper.dump(fd, writer, args); 3510 } 3511 3512 private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) { 3513 if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 3514 != PackageManager.PERMISSION_GRANTED) { 3515 pw.println("Permission Denial: can't dump " + tag + " from from pid=" 3516 + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid() 3517 + " due to missing android.permission.DUMP permission"); 3518 return false; 3519 } else { 3520 return true; 3521 } 3522 } 3523 3524 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) { 3525 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 3526 3527 if (CollectionUtils.contains(args, DIAG_ARG)) { 3528 dumpNetworkDiagnostics(pw); 3529 return; 3530 } else if (CollectionUtils.contains(args, NETWORK_ARG)) { 3531 dumpNetworks(pw); 3532 return; 3533 } else if (CollectionUtils.contains(args, REQUEST_ARG)) { 3534 dumpNetworkRequests(pw); 3535 return; 3536 } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) { 3537 boolean verbose = !CollectionUtils.contains(args, SHORT_ARG); 3538 dumpTrafficController(pw, fd, verbose); 3539 return; 3540 } 3541 3542 pw.println("NetworkProviders for:"); 3543 pw.increaseIndent(); 3544 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 3545 pw.println(npi.providerId + ": " + npi.name); 3546 } 3547 pw.decreaseIndent(); 3548 pw.println(); 3549 3550 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 3551 pw.print("Active default network: "); 3552 if (defaultNai == null) { 3553 pw.println("none"); 3554 } else { 3555 pw.println(defaultNai.network.getNetId()); 3556 } 3557 pw.println(); 3558 3559 pw.println("Current network preferences: "); 3560 pw.increaseIndent(); 3561 dumpNetworkPreferences(pw); 3562 pw.decreaseIndent(); 3563 pw.println(); 3564 3565 pw.println("Current Networks:"); 3566 pw.increaseIndent(); 3567 dumpNetworks(pw); 3568 pw.decreaseIndent(); 3569 pw.println(); 3570 3571 pw.println("Status for known UIDs:"); 3572 pw.increaseIndent(); 3573 final int size = mUidBlockedReasons.size(); 3574 for (int i = 0; i < size; i++) { 3575 // Don't crash if the array is modified while dumping in bugreports. 3576 try { 3577 final int uid = mUidBlockedReasons.keyAt(i); 3578 final int blockedReasons = mUidBlockedReasons.valueAt(i); 3579 pw.println("UID=" + uid + " blockedReasons=" 3580 + Integer.toHexString(blockedReasons)); 3581 } catch (ArrayIndexOutOfBoundsException e) { 3582 pw.println(" ArrayIndexOutOfBoundsException"); 3583 } catch (ConcurrentModificationException e) { 3584 pw.println(" ConcurrentModificationException"); 3585 } 3586 } 3587 pw.println(); 3588 pw.decreaseIndent(); 3589 3590 pw.println("Network Requests:"); 3591 pw.increaseIndent(); 3592 dumpNetworkRequests(pw); 3593 pw.decreaseIndent(); 3594 pw.println(); 3595 3596 pw.println("Network Offers:"); 3597 pw.increaseIndent(); 3598 for (final NetworkOfferInfo offerInfo : mNetworkOffers) { 3599 pw.println(offerInfo.offer); 3600 } 3601 pw.decreaseIndent(); 3602 pw.println(); 3603 3604 mLegacyTypeTracker.dump(pw); 3605 3606 pw.println(); 3607 mKeepaliveTracker.dump(pw); 3608 3609 pw.println(); 3610 dumpAvoidBadWifiSettings(pw); 3611 3612 pw.println(); 3613 3614 if (!CollectionUtils.contains(args, SHORT_ARG)) { 3615 pw.println(); 3616 pw.println("mNetworkRequestInfoLogs (most recent first):"); 3617 pw.increaseIndent(); 3618 mNetworkRequestInfoLogs.reverseDump(pw); 3619 pw.decreaseIndent(); 3620 3621 pw.println(); 3622 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 3623 pw.increaseIndent(); 3624 mNetworkInfoBlockingLogs.reverseDump(pw); 3625 pw.decreaseIndent(); 3626 3627 pw.println(); 3628 pw.println("NetTransition WakeLock activity (most recent first):"); 3629 pw.increaseIndent(); 3630 pw.println("total acquisitions: " + mTotalWakelockAcquisitions); 3631 pw.println("total releases: " + mTotalWakelockReleases); 3632 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s"); 3633 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s"); 3634 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) { 3635 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 3636 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); 3637 } 3638 mWakelockLogs.reverseDump(pw); 3639 3640 pw.println(); 3641 pw.println("bandwidth update requests (by uid):"); 3642 pw.increaseIndent(); 3643 synchronized (mBandwidthRequests) { 3644 for (int i = 0; i < mBandwidthRequests.size(); i++) { 3645 pw.println("[" + mBandwidthRequests.keyAt(i) 3646 + "]: " + mBandwidthRequests.valueAt(i)); 3647 } 3648 } 3649 pw.decreaseIndent(); 3650 pw.decreaseIndent(); 3651 3652 pw.println(); 3653 pw.println("mOemNetworkPreferencesLogs (most recent first):"); 3654 pw.increaseIndent(); 3655 mOemNetworkPreferencesLogs.reverseDump(pw); 3656 pw.decreaseIndent(); 3657 } 3658 3659 pw.println(); 3660 3661 pw.println(); 3662 pw.println("Permission Monitor:"); 3663 pw.increaseIndent(); 3664 mPermissionMonitor.dump(pw); 3665 pw.decreaseIndent(); 3666 3667 pw.println(); 3668 pw.println("Legacy network activity:"); 3669 pw.increaseIndent(); 3670 mNetworkActivityTracker.dump(pw); 3671 pw.decreaseIndent(); 3672 } 3673 3674 private void dumpNetworks(IndentingPrintWriter pw) { 3675 for (NetworkAgentInfo nai : networksSortedById()) { 3676 pw.println(nai.toString()); 3677 pw.increaseIndent(); 3678 pw.println("Nat464Xlat:"); 3679 pw.increaseIndent(); 3680 nai.dumpNat464Xlat(pw); 3681 pw.decreaseIndent(); 3682 pw.println(String.format( 3683 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d", 3684 nai.numForegroundNetworkRequests(), 3685 nai.numNetworkRequests() - nai.numRequestNetworkRequests(), 3686 nai.numBackgroundNetworkRequests(), 3687 nai.numNetworkRequests())); 3688 pw.increaseIndent(); 3689 for (int i = 0; i < nai.numNetworkRequests(); i++) { 3690 pw.println(nai.requestAt(i).toString()); 3691 } 3692 pw.decreaseIndent(); 3693 pw.println("Inactivity Timers:"); 3694 pw.increaseIndent(); 3695 nai.dumpInactivityTimers(pw); 3696 pw.decreaseIndent(); 3697 pw.decreaseIndent(); 3698 } 3699 } 3700 3701 private void dumpNetworkPreferences(IndentingPrintWriter pw) { 3702 if (!mProfileNetworkPreferences.isEmpty()) { 3703 pw.println("Profile preferences:"); 3704 pw.increaseIndent(); 3705 pw.println(mProfileNetworkPreferences); 3706 pw.decreaseIndent(); 3707 } 3708 if (!mOemNetworkPreferences.isEmpty()) { 3709 pw.println("OEM preferences:"); 3710 pw.increaseIndent(); 3711 pw.println(mOemNetworkPreferences); 3712 pw.decreaseIndent(); 3713 } 3714 if (!mMobileDataPreferredUids.isEmpty()) { 3715 pw.println("Mobile data preferred UIDs:"); 3716 pw.increaseIndent(); 3717 pw.println(mMobileDataPreferredUids); 3718 pw.decreaseIndent(); 3719 } 3720 3721 pw.println("Default requests:"); 3722 pw.increaseIndent(); 3723 dumpPerAppDefaultRequests(pw); 3724 pw.decreaseIndent(); 3725 } 3726 3727 private void dumpPerAppDefaultRequests(IndentingPrintWriter pw) { 3728 for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) { 3729 if (mDefaultRequest == defaultRequest) { 3730 continue; 3731 } 3732 3733 final NetworkAgentInfo satisfier = defaultRequest.getSatisfier(); 3734 final String networkOutput; 3735 if (null == satisfier) { 3736 networkOutput = "null"; 3737 } else if (mNoServiceNetwork.equals(satisfier)) { 3738 networkOutput = "no service network"; 3739 } else { 3740 networkOutput = String.valueOf(satisfier.network.netId); 3741 } 3742 final String asUidString = (defaultRequest.mAsUid == defaultRequest.mUid) 3743 ? "" : " asUid: " + defaultRequest.mAsUid; 3744 final String requestInfo = "Request: [uid/pid:" + defaultRequest.mUid + "/" 3745 + defaultRequest.mPid + asUidString + "]"; 3746 final String satisfierOutput = "Satisfier: [" + networkOutput + "]" 3747 + " Preference order: " + defaultRequest.mPreferenceOrder 3748 + " Tracked UIDs: " + defaultRequest.getUids(); 3749 pw.println(requestInfo + " - " + satisfierOutput); 3750 } 3751 } 3752 3753 private void dumpNetworkRequests(IndentingPrintWriter pw) { 3754 NetworkRequestInfo[] infos = null; 3755 while (infos == null) { 3756 try { 3757 infos = requestsSortedById(); 3758 } catch (ConcurrentModificationException e) { 3759 // mNetworkRequests should only be accessed from handler thread, except dump(). 3760 // As dump() is never called in normal usage, it would be needlessly expensive 3761 // to lock the collection only for its benefit. Instead, retry getting the 3762 // requests if ConcurrentModificationException is thrown during dump(). 3763 } 3764 } 3765 for (NetworkRequestInfo nri : infos) { 3766 pw.println(nri.toString()); 3767 } 3768 } 3769 3770 private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd, 3771 boolean verbose) { 3772 try { 3773 mBpfNetMaps.dump(pw, fd, verbose); 3774 } catch (ServiceSpecificException e) { 3775 pw.println(e.getMessage()); 3776 } catch (IOException e) { 3777 loge("Dump BPF maps failed, " + e); 3778 } 3779 } 3780 3781 private void dumpAllRequestInfoLogsToLogcat() { 3782 try (PrintWriter logPw = new PrintWriter(new Writer() { 3783 @Override 3784 public void write(final char[] cbuf, final int off, final int len) { 3785 // This method is called with 0-length and 1-length arrays for empty strings 3786 // or strings containing only the DEL character. 3787 if (len <= 1) return; 3788 Log.e(TAG, new String(cbuf, off, len)); 3789 } 3790 @Override public void flush() {} 3791 @Override public void close() {} 3792 })) { 3793 mNetworkRequestInfoLogs.dump(logPw); 3794 } 3795 } 3796 3797 /** 3798 * Return an array of all current NetworkAgentInfos sorted by network id. 3799 */ 3800 private NetworkAgentInfo[] networksSortedById() { 3801 NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; 3802 networks = mNetworkAgentInfos.toArray(networks); 3803 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId())); 3804 return networks; 3805 } 3806 3807 /** 3808 * Return an array of all current NetworkRequest sorted by request id. 3809 */ 3810 @VisibleForTesting 3811 NetworkRequestInfo[] requestsSortedById() { 3812 NetworkRequestInfo[] requests = new NetworkRequestInfo[0]; 3813 requests = getNrisFromGlobalRequests().toArray(requests); 3814 // Sort the array based off the NRI containing the min requestId in its requests. 3815 Arrays.sort(requests, 3816 Comparator.comparingInt(nri -> Collections.min(nri.mRequests, 3817 Comparator.comparingInt(req -> req.requestId)).requestId 3818 ) 3819 ); 3820 return requests; 3821 } 3822 3823 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 3824 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 3825 if (officialNai != null && officialNai.equals(nai)) return true; 3826 if (officialNai != null || VDBG) { 3827 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 3828 " - " + nai); 3829 } 3830 return false; 3831 } 3832 3833 private boolean isDisconnectRequest(Message msg) { 3834 if (msg.what != NetworkAgent.EVENT_NETWORK_INFO_CHANGED) return false; 3835 final NetworkInfo info = (NetworkInfo) ((Pair) msg.obj).second; 3836 return info.getState() == NetworkInfo.State.DISCONNECTED; 3837 } 3838 3839 // must be stateless - things change under us. 3840 private class NetworkStateTrackerHandler extends Handler { 3841 public NetworkStateTrackerHandler(Looper looper) { 3842 super(looper); 3843 } 3844 3845 private void maybeHandleNetworkAgentMessage(Message msg) { 3846 final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj; 3847 final NetworkAgentInfo nai = arg.first; 3848 if (!mNetworkAgentInfos.contains(nai)) { 3849 if (VDBG) { 3850 log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); 3851 } 3852 return; 3853 } 3854 3855 // If the network has been destroyed, the only thing that it can do is disconnect. 3856 if (nai.isDestroyed() && !isDisconnectRequest(msg)) { 3857 return; 3858 } 3859 3860 switch (msg.what) { 3861 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 3862 nai.setDeclaredCapabilities((NetworkCapabilities) arg.second); 3863 final NetworkCapabilities sanitized = 3864 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator); 3865 maybeUpdateWifiRoamTimestamp(nai, sanitized); 3866 updateCapabilities(nai.getScore(), nai, sanitized); 3867 break; 3868 } 3869 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 3870 LinkProperties newLp = (LinkProperties) arg.second; 3871 processLinkPropertiesFromAgent(nai, newLp); 3872 handleUpdateLinkProperties(nai, newLp); 3873 break; 3874 } 3875 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 3876 NetworkInfo info = (NetworkInfo) arg.second; 3877 updateNetworkInfo(nai, info); 3878 break; 3879 } 3880 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 3881 updateNetworkScore(nai, (NetworkScore) arg.second); 3882 break; 3883 } 3884 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 3885 if (nai.everConnected()) { 3886 loge("ERROR: cannot call explicitlySelected on already-connected network"); 3887 // Note that if the NAI had been connected, this would affect the 3888 // score, and therefore would require re-mixing the score and performing 3889 // a rematch. 3890 } 3891 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1); 3892 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2); 3893 // Mark the network as temporarily accepting partial connectivity so that it 3894 // will be validated (and possibly become default) even if it only provides 3895 // partial internet access. Note that if user connects to partial connectivity 3896 // and choose "don't ask again", then wifi disconnected by some reasons(maybe 3897 // out of wifi coverage) and if the same wifi is available again, the device 3898 // will auto connect to this wifi even though the wifi has "no internet". 3899 // TODO: Evaluate using a separate setting in IpMemoryStore. 3900 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2); 3901 break; 3902 } 3903 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { 3904 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2); 3905 break; 3906 } 3907 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { 3908 // TODO: prevent loops, e.g., if a network declares itself as underlying. 3909 final List<Network> underlying = (List<Network>) arg.second; 3910 3911 if (isLegacyLockdownNai(nai) 3912 && (underlying == null || underlying.size() != 1)) { 3913 Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString() 3914 + " must have exactly one underlying network: " + underlying); 3915 } 3916 3917 final Network[] oldUnderlying = nai.declaredUnderlyingNetworks; 3918 nai.declaredUnderlyingNetworks = (underlying != null) 3919 ? underlying.toArray(new Network[0]) : null; 3920 3921 if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) { 3922 if (DBG) { 3923 log(nai.toShortString() + " changed underlying networks to " 3924 + Arrays.toString(nai.declaredUnderlyingNetworks)); 3925 } 3926 updateCapabilitiesForNetwork(nai); 3927 notifyIfacesChangedForNetworkStats(); 3928 } 3929 break; 3930 } 3931 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: { 3932 if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 3933 nai.teardownDelayMs = msg.arg1; 3934 } else { 3935 logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1); 3936 } 3937 break; 3938 } 3939 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: { 3940 nai.setLingerDuration((int) arg.second); 3941 break; 3942 } 3943 case NetworkAgent.EVENT_ADD_DSCP_POLICY: { 3944 DscpPolicy policy = (DscpPolicy) arg.second; 3945 if (mDscpPolicyTracker != null) { 3946 mDscpPolicyTracker.addDscpPolicy(nai, policy); 3947 } 3948 break; 3949 } 3950 case NetworkAgent.EVENT_REMOVE_DSCP_POLICY: { 3951 if (mDscpPolicyTracker != null) { 3952 mDscpPolicyTracker.removeDscpPolicy(nai, (int) arg.second); 3953 } 3954 break; 3955 } 3956 case NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES: { 3957 if (mDscpPolicyTracker != null) { 3958 mDscpPolicyTracker.removeAllDscpPolicies(nai, true); 3959 } 3960 break; 3961 } 3962 case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: { 3963 if (!nai.everConnected()) { 3964 Log.d(TAG, "unregisterAfterReplacement on never-connected " 3965 + nai.toShortString() + ", tearing down instead"); 3966 teardownUnneededNetwork(nai); 3967 break; 3968 } 3969 3970 if (nai.isDestroyed()) { 3971 Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString() 3972 + ", ignoring"); 3973 break; 3974 } 3975 3976 final int timeoutMs = (int) arg.second; 3977 if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) { 3978 Log.e(TAG, "Invalid network replacement timer " + timeoutMs 3979 + ", must be between 0 and " + NetworkAgent.MAX_TEARDOWN_DELAY_MS); 3980 } 3981 3982 // Marking a network awaiting replacement is used to ensure that any requests 3983 // satisfied by the network do not switch to another network until a 3984 // replacement is available or the wait for a replacement times out. 3985 // If the network is inactive (i.e., nascent or lingering), then there are no 3986 // such requests, and there is no point keeping it. Just tear it down. 3987 // Note that setLingerDuration(0) cannot be used to do this because the network 3988 // could be nascent. 3989 nai.clearInactivityState(); 3990 if (unneeded(nai, UnneededFor.TEARDOWN)) { 3991 Log.d(TAG, nai.toShortString() 3992 + " marked awaiting replacement is unneeded, tearing down instead"); 3993 teardownUnneededNetwork(nai); 3994 break; 3995 } 3996 3997 Log.d(TAG, "Marking " + nai.toShortString() 3998 + " destroyed, awaiting replacement within " + timeoutMs + "ms"); 3999 destroyNativeNetwork(nai); 4000 4001 // TODO: deduplicate this call with the one in disconnectAndDestroyNetwork. 4002 // This is not trivial because KeepaliveTracker#handleStartKeepalive does not 4003 // consider the fact that the network could already have disconnected or been 4004 // destroyed. Fix the code to send ERROR_INVALID_NETWORK when this happens 4005 // (taking care to ensure no dup'd FD leaks), then remove the code duplication 4006 // and move this code to a sensible location (destroyNativeNetwork perhaps?). 4007 mKeepaliveTracker.handleStopAllKeepalives(nai, 4008 SocketKeepalive.ERROR_INVALID_NETWORK); 4009 4010 nai.updateScoreForNetworkAgentUpdate(); 4011 // This rematch is almost certainly not going to result in any changes, because 4012 // the destroyed flag is only just above the "current satisfier wins" 4013 // tie-breaker. But technically anything that affects scoring should rematch. 4014 rematchAllNetworksAndRequests(); 4015 mHandler.postDelayed(() -> nai.disconnect(), timeoutMs); 4016 break; 4017 } 4018 } 4019 } 4020 4021 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 4022 final int netId = msg.arg2; 4023 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); 4024 // If a network has already been destroyed, all NetworkMonitor updates are ignored. 4025 if (nai != null && nai.isDestroyed()) return true; 4026 switch (msg.what) { 4027 default: 4028 return false; 4029 case EVENT_PROBE_STATUS_CHANGED: { 4030 if (nai == null) { 4031 break; 4032 } 4033 final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first; 4034 final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second; 4035 final boolean probePrivateDnsCompleted = 4036 ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0); 4037 final boolean privateDnsBroken = 4038 ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0); 4039 if (probePrivateDnsCompleted) { 4040 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) { 4041 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken); 4042 updateCapabilitiesForNetwork(nai); 4043 } 4044 // Only show the notification when the private DNS is broken and the 4045 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid. 4046 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) { 4047 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN); 4048 } 4049 nai.networkAgentConfig.hasShownBroken = privateDnsBroken; 4050 } else if (nai.networkCapabilities.isPrivateDnsBroken()) { 4051 // If probePrivateDnsCompleted is false but nai.networkCapabilities says 4052 // private DNS is broken, it means this network is being reevaluated. 4053 // Either probing private DNS is not necessary any more or it hasn't been 4054 // done yet. In either case, the networkCapabilities should be updated to 4055 // reflect the new status. 4056 nai.networkCapabilities.setPrivateDnsBroken(false); 4057 updateCapabilitiesForNetwork(nai); 4058 nai.networkAgentConfig.hasShownBroken = false; 4059 } 4060 break; 4061 } 4062 case EVENT_NETWORK_TESTED: { 4063 final NetworkTestedResults results = (NetworkTestedResults) msg.obj; 4064 4065 if (nai == null) break; 4066 4067 handleNetworkTested(nai, results.mTestResult, 4068 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl); 4069 break; 4070 } 4071 case EVENT_PROVISIONING_NOTIFICATION: { 4072 final boolean visible = toBool(msg.arg1); 4073 // If captive portal status has changed, update capabilities or disconnect. 4074 if (!visible) { 4075 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other 4076 // notifications belong to the same network may be cleared unexpectedly. 4077 mNotifier.clearNotification(netId, NotificationType.SIGN_IN); 4078 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH); 4079 } else { 4080 if (nai == null) { 4081 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 4082 break; 4083 } 4084 if (!nai.networkAgentConfig.provisioningNotificationDisabled) { 4085 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 4086 (PendingIntent) msg.obj, 4087 nai.networkAgentConfig.explicitlySelected); 4088 } 4089 } 4090 break; 4091 } 4092 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { 4093 if (nai == null) break; 4094 4095 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); 4096 break; 4097 } 4098 case EVENT_CAPPORT_DATA_CHANGED: { 4099 if (nai == null) break; 4100 handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj); 4101 break; 4102 } 4103 } 4104 return true; 4105 } 4106 4107 private void handleNetworkTested( 4108 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) { 4109 final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0; 4110 final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0; 4111 final boolean portal = !TextUtils.isEmpty(redirectUrl); 4112 4113 // If there is any kind of working networking, then the NAI has been evaluated 4114 // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is 4115 // the first time this ever happened. 4116 final boolean someConnectivity = (valid || partial || portal); 4117 final boolean becameEvaluated = someConnectivity && nai.setEvaluated(); 4118 // Because of b/245893397, if the score is updated when updateCapabilities is called, 4119 // any callback that receives onAvailable for that rematch receives an extra caps 4120 // callback. To prevent that, update the score in the agent so the updates below won't 4121 // see an update to both caps and score at the same time. 4122 // TODO : fix b/245893397 and remove this. 4123 if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate(); 4124 4125 if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) { 4126 // Assume the validation failure is due to a temporary failure after roaming 4127 // and ignore it. NetworkMonitor will continue to retry validation. If it 4128 // continues to fail after the block timeout expires, the network will be 4129 // marked unvalidated. If it succeeds, then validation state will not change. 4130 return; 4131 } 4132 4133 final boolean wasValidated = nai.isValidated(); 4134 final boolean wasPartial = nai.partialConnectivity(); 4135 final boolean wasPortal = nai.captivePortalDetected(); 4136 nai.setPartialConnectivity(partial); 4137 nai.setCaptivePortalDetected(portal); 4138 nai.updateScoreForNetworkAgentUpdate(); 4139 final boolean partialConnectivityChanged = (wasPartial != partial); 4140 final boolean portalChanged = (wasPortal != portal); 4141 4142 if (DBG) { 4143 final String logMsg = !TextUtils.isEmpty(redirectUrl) 4144 ? " with redirect to " + redirectUrl 4145 : ""; 4146 log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg); 4147 } 4148 if (valid != wasValidated) { 4149 final FullScore oldScore = nai.getScore(); 4150 nai.setValidated(valid); 4151 updateCapabilities(oldScore, nai, nai.networkCapabilities); 4152 if (valid) { 4153 handleFreshlyValidatedNetwork(nai); 4154 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and 4155 // LOST_INTERNET notifications if network becomes valid. 4156 mNotifier.clearNotification(nai.network.getNetId(), 4157 NotificationType.NO_INTERNET); 4158 mNotifier.clearNotification(nai.network.getNetId(), 4159 NotificationType.LOST_INTERNET); 4160 mNotifier.clearNotification(nai.network.getNetId(), 4161 NotificationType.PARTIAL_CONNECTIVITY); 4162 mNotifier.clearNotification(nai.network.getNetId(), 4163 NotificationType.PRIVATE_DNS_BROKEN); 4164 // If network becomes valid, the hasShownBroken should be reset for 4165 // that network so that the notification will be fired when the private 4166 // DNS is broken again. 4167 nai.networkAgentConfig.hasShownBroken = false; 4168 } 4169 } else if (partialConnectivityChanged) { 4170 updateCapabilitiesForNetwork(nai); 4171 } else if (portalChanged) { 4172 if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID 4173 == getCaptivePortalMode()) { 4174 if (DBG) log("Avoiding captive portal network: " + nai.toShortString()); 4175 nai.onPreventAutomaticReconnect(); 4176 teardownUnneededNetwork(nai); 4177 return; 4178 } else { 4179 updateCapabilitiesForNetwork(nai); 4180 } 4181 } else if (becameEvaluated) { 4182 // If valid or partial connectivity changed, updateCapabilities* has 4183 // done the rematch. 4184 rematchAllNetworksAndRequests(); 4185 } 4186 updateInetCondition(nai); 4187 4188 // Let the NetworkAgent know the state of its network 4189 // TODO: Evaluate to update partial connectivity to status to NetworkAgent. 4190 nai.onValidationStatusChanged( 4191 valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK, 4192 redirectUrl); 4193 4194 // If NetworkMonitor detects partial connectivity before 4195 // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification 4196 // immediately. Re-notify partial connectivity silently if no internet 4197 // notification already there. 4198 if (!wasPartial && nai.partialConnectivity()) { 4199 // Remove delayed message if there is a pending message. 4200 mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network); 4201 handleInitialEvaluationTimeout(nai.network); 4202 } 4203 4204 if (wasValidated && !nai.isValidated()) { 4205 handleNetworkUnvalidated(nai); 4206 } 4207 } 4208 4209 private int getCaptivePortalMode() { 4210 return Settings.Global.getInt(mContext.getContentResolver(), 4211 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, 4212 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 4213 } 4214 4215 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 4216 switch (msg.what) { 4217 default: 4218 return false; 4219 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 4220 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 4221 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 4222 handleLingerComplete(nai); 4223 } 4224 break; 4225 } 4226 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: { 4227 handleNetworkAgentRegistered(msg); 4228 break; 4229 } 4230 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: { 4231 handleNetworkAgentDisconnected(msg); 4232 break; 4233 } 4234 } 4235 return true; 4236 } 4237 4238 @Override 4239 public void handleMessage(@NonNull Message msg) { 4240 if (!maybeHandleNetworkMonitorMessage(msg) 4241 && !maybeHandleNetworkAgentInfoMessage(msg)) { 4242 maybeHandleNetworkAgentMessage(msg); 4243 } 4244 } 4245 } 4246 4247 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub { 4248 private final int mNetId; 4249 private final AutodestructReference<NetworkAgentInfo> mNai; 4250 4251 private NetworkMonitorCallbacks(NetworkAgentInfo nai) { 4252 mNetId = nai.network.getNetId(); 4253 mNai = new AutodestructReference<>(nai); 4254 } 4255 4256 @Override 4257 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 4258 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, 4259 new Pair<>(mNai.getAndDestroy(), networkMonitor))); 4260 } 4261 4262 @Override 4263 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { 4264 // Legacy version of notifyNetworkTestedWithExtras. 4265 // Would only be called if the system has a NetworkStack module older than the 4266 // framework, which does not happen in practice. 4267 Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken"); 4268 } 4269 4270 @Override 4271 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) { 4272 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use 4273 // the same looper so messages will be processed in sequence. 4274 final Message msg = mTrackerHandler.obtainMessage( 4275 EVENT_NETWORK_TESTED, 4276 0, mNetId, 4277 new NetworkTestedResults( 4278 mNetId, p.result, p.timestampMillis, p.redirectUrl)); 4279 mTrackerHandler.sendMessage(msg); 4280 4281 // Invoke ConnectivityReport generation for this Network test event. 4282 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId); 4283 if (nai == null) return; 4284 4285 // NetworkMonitor reports the network validation result as a bitmask while 4286 // ConnectivityDiagnostics treats this value as an int. Convert the result to a single 4287 // logical value for ConnectivityDiagnostics. 4288 final int validationResult = networkMonitorValidationResultToConnDiagsValidationResult( 4289 p.result); 4290 4291 final PersistableBundle extras = new PersistableBundle(); 4292 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, validationResult); 4293 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded); 4294 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted); 4295 4296 ConnectivityReportEvent reportEvent = 4297 new ConnectivityReportEvent(p.timestampMillis, nai, extras); 4298 final Message m = mConnectivityDiagnosticsHandler.obtainMessage( 4299 ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent); 4300 mConnectivityDiagnosticsHandler.sendMessage(m); 4301 } 4302 4303 @Override 4304 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) { 4305 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 4306 EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 4307 0, mNetId, PrivateDnsConfig.fromParcel(config))); 4308 } 4309 4310 @Override 4311 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) { 4312 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 4313 EVENT_PROBE_STATUS_CHANGED, 4314 0, mNetId, new Pair<>(probesCompleted, probesSucceeded))); 4315 } 4316 4317 @Override 4318 public void notifyCaptivePortalDataChanged(CaptivePortalData data) { 4319 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 4320 EVENT_CAPPORT_DATA_CHANGED, 4321 0, mNetId, data)); 4322 } 4323 4324 @Override 4325 public void showProvisioningNotification(String action, String packageName) { 4326 final Intent intent = new Intent(action); 4327 intent.setPackage(packageName); 4328 4329 final PendingIntent pendingIntent; 4330 // Only the system server can register notifications with package "android" 4331 final long token = Binder.clearCallingIdentity(); 4332 try { 4333 pendingIntent = PendingIntent.getBroadcast( 4334 mContext, 4335 0 /* requestCode */, 4336 intent, 4337 PendingIntent.FLAG_IMMUTABLE); 4338 } finally { 4339 Binder.restoreCallingIdentity(token); 4340 } 4341 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 4342 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW, 4343 mNetId, pendingIntent)); 4344 } 4345 4346 @Override 4347 public void hideProvisioningNotification() { 4348 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage( 4349 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); 4350 } 4351 4352 @Override 4353 public void notifyDataStallSuspected(DataStallReportParcelable p) { 4354 ConnectivityService.this.notifyDataStallSuspected(p, mNetId); 4355 } 4356 4357 @Override 4358 public int getInterfaceVersion() { 4359 return this.VERSION; 4360 } 4361 4362 @Override 4363 public String getInterfaceHash() { 4364 return this.HASH; 4365 } 4366 } 4367 4368 /** 4369 * Converts the given NetworkMonitor-specific validation result bitmask to a 4370 * ConnectivityDiagnostics-specific validation result int. 4371 */ 4372 private int networkMonitorValidationResultToConnDiagsValidationResult(int validationResult) { 4373 if ((validationResult & NETWORK_VALIDATION_RESULT_SKIPPED) != 0) { 4374 return ConnectivityReport.NETWORK_VALIDATION_RESULT_SKIPPED; 4375 } 4376 if ((validationResult & NETWORK_VALIDATION_RESULT_VALID) == 0) { 4377 return ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID; 4378 } 4379 return (validationResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0 4380 ? ConnectivityReport.NETWORK_VALIDATION_RESULT_PARTIALLY_VALID 4381 : ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID; 4382 } 4383 4384 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) { 4385 log("Data stall detected with methods: " + p.detectionMethod); 4386 4387 final PersistableBundle extras = new PersistableBundle(); 4388 int detectionMethod = 0; 4389 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 4390 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); 4391 detectionMethod |= DETECTION_METHOD_DNS_EVENTS; 4392 } 4393 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 4394 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); 4395 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, 4396 p.tcpMetricsCollectionPeriodMillis); 4397 detectionMethod |= DETECTION_METHOD_TCP_METRICS; 4398 } 4399 4400 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( 4401 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId, 4402 new Pair<>(p.timestampMillis, extras)); 4403 4404 // NetworkStateTrackerHandler currently doesn't take any actions based on data 4405 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid 4406 // the cost of going through two handlers. 4407 mConnectivityDiagnosticsHandler.sendMessage(msg); 4408 } 4409 4410 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) { 4411 return (p.detectionMethod & detectionMethod) != 0; 4412 } 4413 4414 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { 4415 return isPrivateDnsValidationRequired(nai.networkCapabilities); 4416 } 4417 4418 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { 4419 if (nai == null) return; 4420 // If the Private DNS mode is opportunistic, reprogram the DNS servers 4421 // in order to restart a validation pass from within netd. 4422 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 4423 if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) { 4424 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 4425 } 4426 } 4427 4428 private void handlePrivateDnsSettingsChanged() { 4429 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 4430 4431 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 4432 handlePerNetworkPrivateDnsConfig(nai, cfg); 4433 if (networkRequiresPrivateDnsValidation(nai)) { 4434 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 4435 } 4436 } 4437 } 4438 4439 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 4440 // Private DNS only ever applies to networks that might provide 4441 // Internet access and therefore also require validation. 4442 if (!networkRequiresPrivateDnsValidation(nai)) return; 4443 4444 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or 4445 // schedule DNS resolutions. If a DNS resolution is required the 4446 // result will be sent back to us. 4447 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel()); 4448 4449 // With Private DNS bypass support, we can proceed to update the 4450 // Private DNS config immediately, even if we're in strict mode 4451 // and have not yet resolved the provider name into a set of IPs. 4452 updatePrivateDns(nai, cfg); 4453 } 4454 4455 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 4456 mDnsManager.updatePrivateDns(nai.network, newCfg); 4457 updateDnses(nai.linkProperties, null, nai.network.getNetId()); 4458 } 4459 4460 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 4461 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 4462 if (nai == null) { 4463 return; 4464 } 4465 mDnsManager.updatePrivateDnsValidation(update); 4466 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 4467 } 4468 4469 private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, 4470 int prefixLength) { 4471 NetworkAgentInfo nai = mNetworkForNetId.get(netId); 4472 if (nai == null) return; 4473 4474 log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", 4475 netId, operation, prefixAddress, prefixLength)); 4476 4477 IpPrefix prefix = null; 4478 if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { 4479 try { 4480 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), 4481 prefixLength); 4482 } catch (IllegalArgumentException e) { 4483 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); 4484 return; 4485 } 4486 } 4487 4488 nai.clatd.setNat64PrefixFromDns(prefix); 4489 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 4490 } 4491 4492 private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai, 4493 @Nullable final CaptivePortalData data) { 4494 nai.capportApiData = data; 4495 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo 4496 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 4497 } 4498 4499 /** 4500 * Updates the inactivity state from the network requests inside the NAI. 4501 * @param nai the agent info to update 4502 * @param now the timestamp of the event causing this update 4503 * @return whether the network was inactive as a result of this update 4504 */ 4505 private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) { 4506 // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm. 4507 // 2. If the network was inactive and there are now requests, unset inactive. 4508 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 4509 // one lingered request, set inactive. 4510 nai.updateInactivityTimer(); 4511 if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) { 4512 if (DBG) log("Unsetting inactive " + nai.toShortString()); 4513 nai.unsetInactive(); 4514 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 4515 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) { 4516 if (DBG) { 4517 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 4518 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms"); 4519 } 4520 nai.setInactive(); 4521 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 4522 return true; 4523 } 4524 return false; 4525 } 4526 4527 private void handleNetworkAgentRegistered(Message msg) { 4528 final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 4529 if (!mNetworkAgentInfos.contains(nai)) { 4530 return; 4531 } 4532 4533 if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) { 4534 if (VDBG) log("NetworkAgent registered"); 4535 } else { 4536 loge("Error connecting NetworkAgent"); 4537 mNetworkAgentInfos.remove(nai); 4538 if (nai != null) { 4539 final boolean wasDefault = isDefaultNetwork(nai); 4540 synchronized (mNetworkForNetId) { 4541 mNetworkForNetId.remove(nai.network.getNetId()); 4542 } 4543 mNetIdManager.releaseNetId(nai.network.getNetId()); 4544 // Just in case. 4545 mLegacyTypeTracker.remove(nai, wasDefault); 4546 } 4547 } 4548 } 4549 4550 @VisibleForTesting 4551 protected static boolean shouldCreateNetworksImmediately() { 4552 // The feature of creating the networks immediately was slated for U, but race conditions 4553 // detected late required this was flagged off. 4554 // TODO : enable this in a Mainline update or in V, and re-enable the test for this 4555 // in NetworkAgentTest. 4556 return false; 4557 } 4558 4559 private static boolean shouldCreateNativeNetwork(@NonNull NetworkAgentInfo nai, 4560 @NonNull NetworkInfo.State state) { 4561 if (nai.isCreated()) return false; 4562 if (state == NetworkInfo.State.CONNECTED) return true; 4563 if (state != NetworkInfo.State.CONNECTING) { 4564 // TODO: throw if no WTFs are observed in the field. 4565 if (shouldCreateNetworksImmediately()) { 4566 Log.wtf(TAG, "Uncreated network in invalid state: " + state); 4567 } 4568 return false; 4569 } 4570 return nai.isVPN() || shouldCreateNetworksImmediately(); 4571 } 4572 4573 private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 4574 return nai.isCreated() && !nai.isDestroyed(); 4575 } 4576 4577 @VisibleForTesting 4578 boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) { 4579 // T+ devices should use unregisterAfterReplacement. 4580 if (mDeps.isAtLeastT()) return false; 4581 4582 // If the network never roamed, return false. The check below is not sufficient if time 4583 // since boot is less than blockTimeOut, though that's extremely unlikely to happen. 4584 if (nai.lastRoamTime == 0) return false; 4585 4586 final long blockTimeOut = Long.valueOf(mResources.get().getInteger( 4587 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis)); 4588 if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS 4589 && blockTimeOut >= 0) { 4590 final long currentTimeMs = SystemClock.elapsedRealtime(); 4591 long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime; 4592 if (timeSinceLastRoam <= blockTimeOut) { 4593 log ("blocked because only " + timeSinceLastRoam + "ms after roam"); 4594 return true; 4595 } 4596 } 4597 return false; 4598 } 4599 4600 private void handleNetworkAgentDisconnected(Message msg) { 4601 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 4602 disconnectAndDestroyNetwork(nai); 4603 } 4604 4605 // Destroys a network, remove references to it from the internal state managed by 4606 // ConnectivityService, free its interfaces and clean up. 4607 // Must be called on the Handler thread. 4608 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 4609 ensureRunningOnConnectivityServiceThread(); 4610 4611 if (!mNetworkAgentInfos.contains(nai)) return; 4612 4613 if (DBG) { 4614 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests()); 4615 } 4616 // Clear all notifications of this network. 4617 mNotifier.clearNotification(nai.network.getNetId()); 4618 // A network agent has disconnected. 4619 // TODO - if we move the logic to the network agent (have them disconnect 4620 // because they lost all their requests or because their score isn't good) 4621 // then they would disconnect organically, report their new state and then 4622 // disconnect the channel. 4623 if (nai.networkInfo.isConnected() || nai.networkInfo.isSuspended()) { 4624 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 4625 null, null); 4626 } 4627 final boolean wasDefault = isDefaultNetwork(nai); 4628 if (wasDefault) { 4629 mDefaultInetConditionPublished = 0; 4630 } 4631 notifyIfacesChangedForNetworkStats(); 4632 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 4633 // by other networks that are already connected. Perhaps that can be done by 4634 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 4635 // of rematchAllNetworksAndRequests 4636 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 4637 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK); 4638 4639 mQosCallbackTracker.handleNetworkReleased(nai.network); 4640 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 4641 // Disable wakeup packet monitoring for each interface. 4642 wakeupModifyInterface(iface, nai, false); 4643 } 4644 nai.networkMonitor().notifyNetworkDisconnected(); 4645 mNetworkAgentInfos.remove(nai); 4646 nai.clatd.update(); 4647 synchronized (mNetworkForNetId) { 4648 // Remove the NetworkAgent, but don't mark the netId as 4649 // available until we've told netd to delete it below. 4650 mNetworkForNetId.remove(nai.network.getNetId()); 4651 } 4652 propagateUnderlyingNetworkCapabilities(nai.network); 4653 // Update allowed network lists in netd. This should be called after removing nai 4654 // from mNetworkAgentInfos. 4655 updateProfileAllowedNetworks(); 4656 // Remove all previously satisfied requests. 4657 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4658 final NetworkRequest request = nai.requestAt(i); 4659 final NetworkRequestInfo nri = mNetworkRequests.get(request); 4660 final NetworkAgentInfo currentNetwork = nri.getSatisfier(); 4661 if (currentNetwork != null 4662 && currentNetwork.network.getNetId() == nai.network.getNetId()) { 4663 // uid rules for this network will be removed in destroyNativeNetwork(nai). 4664 // TODO : setting the satisfier is in fact the job of the rematch. Teach the 4665 // rematch not to keep disconnected agents instead of setting it here ; this 4666 // will also allow removing updating the offers below. 4667 nri.setSatisfier(null, null); 4668 for (final NetworkOfferInfo noi : mNetworkOffers) { 4669 informOffer(nri, noi.offer, mNetworkRanker); 4670 } 4671 4672 if (mDefaultRequest == nri) { 4673 // TODO : make battery stats aware that since 2013 multiple interfaces may be 4674 // active at the same time. For now keep calling this with the default 4675 // network, because while incorrect this is the closest to the old (also 4676 // incorrect) behavior. 4677 mNetworkActivityTracker.updateDataActivityTracking( 4678 null /* newNetwork */, nai); 4679 ensureNetworkTransitionWakelock(nai.toShortString()); 4680 } 4681 } 4682 } 4683 nai.clearInactivityState(); 4684 // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after. 4685 // Currently, deleting it breaks tests that check for the default network disconnecting. 4686 // Find out why, fix the rematch code, and delete this. 4687 mLegacyTypeTracker.remove(nai, wasDefault); 4688 rematchAllNetworksAndRequests(); 4689 mLingerMonitor.noteDisconnect(nai); 4690 4691 if (null == getDefaultNetwork() && nai.linkProperties.getHttpProxy() != null) { 4692 // The obvious place to do this would be in makeDefault(), however makeDefault() is 4693 // not called by the rematch in this case. This is because the code above unset 4694 // this network from the default request's satisfier, and that is what the rematch 4695 // is using as its source data to know what the old satisfier was. So as far as the 4696 // rematch above is concerned, the old default network was null. 4697 // Therefore if there is no new default, the default network was null and is still 4698 // null, thus there was no change so makeDefault() is not called. So if the old 4699 // network had a proxy and there is no new default, the proxy tracker should be told 4700 // that there is no longer a default proxy. 4701 // Strictly speaking this is not essential because having a proxy setting when 4702 // there is no network is harmless, but it's still counter-intuitive so reset to null. 4703 mProxyTracker.setDefaultProxy(null); 4704 } 4705 4706 // Immediate teardown. 4707 if (nai.teardownDelayMs == 0) { 4708 destroyNetwork(nai); 4709 return; 4710 } 4711 4712 // Delayed teardown. 4713 if (nai.isCreated()) { 4714 try { 4715 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM); 4716 } catch (RemoteException e) { 4717 Log.d(TAG, "Error marking network restricted during teardown: ", e); 4718 } 4719 } 4720 mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs); 4721 } 4722 4723 private void destroyNetwork(NetworkAgentInfo nai) { 4724 if (shouldDestroyNativeNetwork(nai)) { 4725 // Tell netd to clean up the configuration for this network 4726 // (routing rules, DNS, etc). 4727 // This may be slow as it requires a lot of netd shelling out to ip and 4728 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 4729 // after we've rematched networks with requests (which might change the default 4730 // network or service a new request from an app), so network traffic isn't interrupted 4731 // for an unnecessarily long time. 4732 destroyNativeNetwork(nai); 4733 } 4734 if (!nai.isCreated() && !mDeps.isAtLeastT()) { 4735 // Backwards compatibility: send onNetworkDestroyed even if network was never created. 4736 // This can never run if the code above runs because shouldDestroyNativeNetwork is 4737 // false if the network was never created. 4738 // TODO: delete when S is no longer supported. 4739 nai.onNetworkDestroyed(); 4740 } 4741 mNetIdManager.releaseNetId(nai.network.getNetId()); 4742 } 4743 4744 private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) { 4745 try { 4746 // This should never fail. Specifying an already in use NetID will cause failure. 4747 final NativeNetworkConfig config; 4748 if (nai.isVPN()) { 4749 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) { 4750 Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString()); 4751 return false; 4752 } 4753 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL, 4754 INetd.PERMISSION_NONE, 4755 !nai.networkAgentConfig.allowBypass /* secure */, 4756 getVpnType(nai), nai.networkAgentConfig.excludeLocalRouteVpn); 4757 } else { 4758 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL, 4759 getNetworkPermission(nai.networkCapabilities), 4760 false /* secure */, 4761 VpnManager.TYPE_VPN_NONE, 4762 false /* excludeLocalRoutes */); 4763 } 4764 mNetd.networkCreate(config); 4765 mDnsResolver.createNetworkCache(nai.network.getNetId()); 4766 mDnsManager.updateTransportsForNetwork(nai.network.getNetId(), 4767 nai.networkCapabilities.getTransportTypes()); 4768 return true; 4769 } catch (RemoteException | ServiceSpecificException e) { 4770 loge("Error creating network " + nai.toShortString() + ": " + e.getMessage()); 4771 return false; 4772 } 4773 } 4774 4775 private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) { 4776 if (mDscpPolicyTracker != null) { 4777 mDscpPolicyTracker.removeAllDscpPolicies(nai, false); 4778 } 4779 try { 4780 mNetd.networkDestroy(nai.network.getNetId()); 4781 } catch (RemoteException | ServiceSpecificException e) { 4782 loge("Exception destroying network(networkDestroy): " + e); 4783 } 4784 try { 4785 mDnsResolver.destroyNetworkCache(nai.network.getNetId()); 4786 } catch (RemoteException | ServiceSpecificException e) { 4787 loge("Exception destroying network: " + e); 4788 } 4789 // TODO: defer calling this until the network is removed from mNetworkAgentInfos. 4790 // Otherwise, a private DNS configuration update for a destroyed network, or one that never 4791 // gets created, could add data to DnsManager data structures that will never get deleted. 4792 mDnsManager.removeNetwork(nai.network); 4793 4794 // clean up tc police filters on interface. 4795 if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) { 4796 mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName()); 4797 } 4798 4799 nai.setDestroyed(); 4800 nai.onNetworkDestroyed(); 4801 } 4802 4803 // If this method proves to be too slow then we can maintain a separate 4804 // pendingIntent => NetworkRequestInfo map. 4805 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. 4806 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 4807 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 4808 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 4809 if (existingPendingIntent != null && 4810 mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) { 4811 return entry.getValue(); 4812 } 4813 } 4814 return null; 4815 } 4816 4817 private void checkNrisConsistency(final NetworkRequestInfo nri) { 4818 if (mDeps.isAtLeastT()) { 4819 for (final NetworkRequestInfo n : mNetworkRequests.values()) { 4820 if (n.mBinder != null && n.mBinder == nri.mBinder) { 4821 // Temporary help to debug b/194394697 ; TODO : remove this function when the 4822 // bug is fixed. 4823 dumpAllRequestInfoLogsToLogcat(); 4824 throw new IllegalStateException("This NRI is already registered. New : " + nri 4825 + ", existing : " + n); 4826 } 4827 } 4828 } 4829 } 4830 4831 private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid, 4832 @NonNull final NetworkCapabilities caps) { 4833 if (mCarrierPrivilegeAuthenticator != null) { 4834 return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities( 4835 callingUid, caps); 4836 } 4837 return false; 4838 } 4839 4840 private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) { 4841 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 4842 // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests. 4843 ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent"); 4844 final NetworkRequestInfo existingRequest = 4845 findExistingNetworkRequestInfo(nri.mPendingIntent); 4846 if (existingRequest != null) { // remove the existing request. 4847 if (DBG) { 4848 log("Replacing " + existingRequest.mRequests.get(0) + " with " 4849 + nri.mRequests.get(0) + " because their intents matched."); 4850 } 4851 handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(), 4852 /* callOnUnavailable */ false); 4853 } 4854 handleRegisterNetworkRequest(nri); 4855 } 4856 4857 private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) { 4858 handleRegisterNetworkRequests(Collections.singleton(nri)); 4859 } 4860 4861 private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 4862 ensureRunningOnConnectivityServiceThread(); 4863 for (final NetworkRequestInfo nri : nris) { 4864 mNetworkRequestInfoLogs.log("REGISTER " + nri); 4865 checkNrisConsistency(nri); 4866 for (final NetworkRequest req : nri.mRequests) { 4867 mNetworkRequests.put(req, nri); 4868 // TODO: Consider update signal strength for other types. 4869 if (req.isListen()) { 4870 for (final NetworkAgentInfo network : mNetworkAgentInfos) { 4871 if (req.networkCapabilities.hasSignalStrength() 4872 && network.satisfiesImmutableCapabilitiesOf(req)) { 4873 updateSignalStrengthThresholds(network, "REGISTER", req); 4874 } 4875 } 4876 } 4877 } 4878 4879 // If this NRI has a satisfier already, it is replacing an older request that 4880 // has been removed. Track it. 4881 final NetworkRequest activeRequest = nri.getActiveRequest(); 4882 if (null != activeRequest) { 4883 // If there is an active request, then for sure there is a satisfier. 4884 nri.getSatisfier().addRequest(activeRequest); 4885 } 4886 } 4887 4888 if (mFlags.noRematchAllRequestsOnRegister()) { 4889 rematchNetworksAndRequests(nris); 4890 } else { 4891 rematchAllNetworksAndRequests(); 4892 } 4893 4894 // Requests that have not been matched to a network will not have been sent to the 4895 // providers, because the old satisfier and the new satisfier are the same (null in this 4896 // case). Send these requests to the providers. 4897 for (final NetworkRequestInfo nri : nris) { 4898 for (final NetworkOfferInfo noi : mNetworkOffers) { 4899 informOffer(nri, noi.offer, mNetworkRanker); 4900 } 4901 } 4902 } 4903 4904 private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent, 4905 final int callingUid) { 4906 final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 4907 if (nri != null) { 4908 // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests. 4909 ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent"); 4910 handleReleaseNetworkRequest( 4911 nri.mRequests.get(0), 4912 callingUid, 4913 /* callOnUnavailable */ false); 4914 } 4915 } 4916 4917 // Determines whether the network is the best (or could become the best, if it validated), for 4918 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 4919 // on the value of reason: 4920 // 4921 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 4922 // then it should be torn down. 4923 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 4924 // then it should be lingered. 4925 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 4926 ensureRunningOnConnectivityServiceThread(); 4927 4928 if (!nai.everConnected() || nai.isVPN() || nai.isInactive() 4929 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) { 4930 return false; 4931 } 4932 4933 final int numRequests; 4934 switch (reason) { 4935 case TEARDOWN: 4936 numRequests = nai.numRequestNetworkRequests(); 4937 break; 4938 case LINGER: 4939 numRequests = nai.numForegroundNetworkRequests(); 4940 break; 4941 default: 4942 Log.wtf(TAG, "Invalid reason. Cannot happen."); 4943 return true; 4944 } 4945 4946 if (numRequests > 0) return false; 4947 4948 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 4949 if (reason == UnneededFor.LINGER 4950 && !nri.isMultilayerRequest() 4951 && nri.mRequests.get(0).isBackgroundRequest()) { 4952 // Background requests don't affect lingering. 4953 continue; 4954 } 4955 4956 if (isNetworkPotentialSatisfier(nai, nri)) { 4957 return false; 4958 } 4959 } 4960 return true; 4961 } 4962 4963 private boolean isNetworkPotentialSatisfier( 4964 @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) { 4965 // listen requests won't keep up a network satisfying it. If this is not a multilayer 4966 // request, return immediately. For multilayer requests, check to see if any of the 4967 // multilayer requests may have a potential satisfier. 4968 if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen() 4969 || nri.mRequests.get(0).isListenForBest())) { 4970 return false; 4971 } 4972 for (final NetworkRequest req : nri.mRequests) { 4973 // This multilayer listen request is satisfied therefore no further requests need to be 4974 // evaluated deeming this network not a potential satisfier. 4975 if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) { 4976 return false; 4977 } 4978 // As non-multilayer listen requests have already returned, the below would only happen 4979 // for a multilayer request therefore continue to the next request if available. 4980 if (req.isListen() || req.isListenForBest()) { 4981 continue; 4982 } 4983 // If this Network is already the best Network for a request, or if 4984 // there is hope for it to become one if it validated, then it is needed. 4985 if (candidate.satisfies(req)) { 4986 // As soon as a network is found that satisfies a request, return. Specifically for 4987 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request 4988 // is important so as to not evaluate lower priority requests further in 4989 // nri.mRequests. 4990 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest()) 4991 ? nri.getSatisfier() : null; 4992 // Note that this catches two important cases: 4993 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 4994 // is currently satisfying the request. This is desirable when 4995 // cellular ends up validating but WiFi does not. 4996 // 2. Unvalidated WiFi will not be reaped when validated cellular 4997 // is currently satisfying the request. This is desirable when 4998 // WiFi ends up validating and out scoring cellular. 4999 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable()); 5000 } 5001 } 5002 5003 return false; 5004 } 5005 5006 private NetworkRequestInfo getNriForAppRequest( 5007 NetworkRequest request, int callingUid, String requestedOperation) { 5008 // Looking up the app passed param request in mRequests isn't possible since it may return 5009 // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to 5010 // do the lookup since that will also find per-app default managed requests. 5011 // Additionally, this lookup needs to be relatively fast (hence the lookup optimization) 5012 // to avoid potential race conditions when validating a package->uid mapping when sending 5013 // the callback on the very low-chance that an application shuts down prior to the callback 5014 // being sent. 5015 final NetworkRequestInfo nri = mNetworkRequests.get(request) != null 5016 ? mNetworkRequests.get(request) : getNriForAppRequest(request); 5017 5018 if (nri != null) { 5019 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 5020 log(String.format("UID %d attempted to %s for unowned request %s", 5021 callingUid, requestedOperation, nri)); 5022 return null; 5023 } 5024 } 5025 5026 return nri; 5027 } 5028 5029 private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri, 5030 final String callingMethod) { 5031 if (nri.isMultilayerRequest()) { 5032 throw new IllegalStateException( 5033 callingMethod + " does not support multilayer requests."); 5034 } 5035 } 5036 5037 private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5038 ensureRunningOnConnectivityServiceThread(); 5039 // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a 5040 // single NetworkRequest and thus does not apply to multilayer requests. 5041 ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest"); 5042 if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { 5043 return; 5044 } 5045 if (nri.isBeingSatisfied()) { 5046 return; 5047 } 5048 if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) { 5049 log("releasing " + nri.mRequests.get(0) + " (timeout)"); 5050 } 5051 handleRemoveNetworkRequest(nri); 5052 callCallbackForRequest( 5053 nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 5054 } 5055 5056 private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request, 5057 final int callingUid, 5058 final boolean callOnUnavailable) { 5059 final NetworkRequestInfo nri = 5060 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 5061 if (nri == null) { 5062 return; 5063 } 5064 if (VDBG || (DBG && request.isRequest())) { 5065 log("releasing " + request + " (release request)"); 5066 } 5067 handleRemoveNetworkRequest(nri); 5068 if (callOnUnavailable) { 5069 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 5070 } 5071 } 5072 5073 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) { 5074 ensureRunningOnConnectivityServiceThread(); 5075 for (final NetworkRequest req : nri.mRequests) { 5076 if (null == mNetworkRequests.remove(req)) { 5077 logw("Attempted removal of untracked request " + req + " for nri " + nri); 5078 continue; 5079 } 5080 if (req.isListen()) { 5081 removeListenRequestFromNetworks(req); 5082 } 5083 } 5084 nri.unlinkDeathRecipient(); 5085 if (mDefaultNetworkRequests.remove(nri)) { 5086 // If this request was one of the defaults, then the UID rules need to be updated 5087 // WARNING : if the app(s) for which this network request is the default are doing 5088 // traffic, this will kill their connected sockets, even if an equivalent request 5089 // is going to be reinstated right away ; unconnected traffic will go on the default 5090 // until the new default is set, which will happen very soon. 5091 // TODO : The only way out of this is to diff old defaults and new defaults, and only 5092 // remove ranges for those requests that won't have a replacement 5093 final NetworkAgentInfo satisfier = nri.getSatisfier(); 5094 if (null != satisfier) { 5095 try { 5096 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 5097 satisfier.network.getNetId(), 5098 toUidRangeStableParcels(nri.getUids()), 5099 nri.getPreferenceOrderForNetd())); 5100 } catch (RemoteException e) { 5101 loge("Exception setting network preference default network", e); 5102 } 5103 } 5104 } 5105 5106 nri.mPerUidCounter.decrementCount(nri.mUid); 5107 mNetworkRequestInfoLogs.log("RELEASE " + nri); 5108 checkNrisConsistency(nri); 5109 5110 if (null != nri.getActiveRequest()) { 5111 if (!nri.getActiveRequest().isListen()) { 5112 removeSatisfiedNetworkRequestFromNetwork(nri); 5113 } 5114 } 5115 5116 // For all outstanding offers, cancel any of the layers of this NRI that used to be 5117 // needed for this offer. 5118 for (final NetworkOfferInfo noi : mNetworkOffers) { 5119 for (final NetworkRequest req : nri.mRequests) { 5120 if (req.isRequest() && noi.offer.neededFor(req)) { 5121 noi.offer.onNetworkUnneeded(req); 5122 } 5123 } 5124 } 5125 } 5126 5127 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 5128 for (final NetworkRequestInfo nri : nris) { 5129 if (mDefaultRequest == nri) { 5130 // Make sure we never remove the default request. 5131 continue; 5132 } 5133 handleRemoveNetworkRequest(nri); 5134 } 5135 } 5136 5137 private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) { 5138 // listens don't have a singular affected Network. Check all networks to see 5139 // if this listen request applies and remove it. 5140 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 5141 nai.removeRequest(req.requestId); 5142 if (req.networkCapabilities.hasSignalStrength() 5143 && nai.satisfiesImmutableCapabilitiesOf(req)) { 5144 updateSignalStrengthThresholds(nai, "RELEASE", req); 5145 } 5146 } 5147 } 5148 5149 /** 5150 * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and 5151 * manage the necessary upkeep (linger, teardown networks, etc.) when doing so. 5152 * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo 5153 */ 5154 private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) { 5155 boolean wasKept = false; 5156 final NetworkAgentInfo nai = nri.getSatisfier(); 5157 if (nai != null) { 5158 final int requestLegacyType = nri.getActiveRequest().legacyType; 5159 final boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 5160 nai.removeRequest(nri.getActiveRequest().requestId); 5161 if (VDBG || DDBG) { 5162 log(" Removing from current network " + nai.toShortString() 5163 + ", leaving " + nai.numNetworkRequests() + " requests."); 5164 } 5165 // If there are still lingered requests on this network, don't tear it down, 5166 // but resume lingering instead. 5167 final long now = SystemClock.elapsedRealtime(); 5168 if (updateInactivityState(nai, now)) { 5169 notifyNetworkLosing(nai, now); 5170 } 5171 if (unneeded(nai, UnneededFor.TEARDOWN)) { 5172 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting"); 5173 teardownUnneededNetwork(nai); 5174 } else { 5175 wasKept = true; 5176 } 5177 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 5178 // Went from foreground to background. 5179 updateCapabilitiesForNetwork(nai); 5180 } 5181 5182 // Maintain the illusion. When this request arrived, we might have pretended 5183 // that a network connected to serve it, even though the network was already 5184 // connected. Now that this request has gone away, we might have to pretend 5185 // that the network disconnected. LegacyTypeTracker will generate that 5186 // phantom disconnect for this type. 5187 if (requestLegacyType != TYPE_NONE) { 5188 boolean doRemove = true; 5189 if (wasKept) { 5190 // check if any of the remaining requests for this network are for the 5191 // same legacy type - if so, don't remove the nai 5192 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5193 NetworkRequest otherRequest = nai.requestAt(i); 5194 if (otherRequest.legacyType == requestLegacyType 5195 && otherRequest.isRequest()) { 5196 if (DBG) log(" still have other legacy request - leaving"); 5197 doRemove = false; 5198 } 5199 } 5200 } 5201 5202 if (doRemove) { 5203 mLegacyTypeTracker.remove(requestLegacyType, nai, false); 5204 } 5205 } 5206 } 5207 } 5208 5209 private RequestInfoPerUidCounter getRequestCounter(NetworkRequestInfo nri) { 5210 return checkAnyPermissionOf(mContext, 5211 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) 5212 ? mSystemNetworkRequestCounter : mNetworkRequestCounter; 5213 } 5214 5215 @Override 5216 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 5217 enforceNetworkStackSettingsOrSetup(); 5218 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 5219 encodeBool(accept), encodeBool(always), network)); 5220 } 5221 5222 @Override 5223 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { 5224 enforceNetworkStackSettingsOrSetup(); 5225 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY, 5226 encodeBool(accept), encodeBool(always), network)); 5227 } 5228 5229 @Override 5230 public void setAvoidUnvalidated(Network network) { 5231 enforceNetworkStackSettingsOrSetup(); 5232 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 5233 } 5234 5235 @Override 5236 public void setTestAllowBadWifiUntil(long timeMs) { 5237 enforceSettingsPermission(); 5238 if (!Build.isDebuggable()) { 5239 throw new IllegalStateException("Does not support in non-debuggable build"); 5240 } 5241 5242 if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) { 5243 throw new IllegalArgumentException("It should not exceed " 5244 + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now"); 5245 } 5246 5247 mHandler.sendMessage( 5248 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs)); 5249 } 5250 5251 @Override 5252 public void setTestLowTcpPollingTimerForKeepalive(long timeMs) { 5253 enforceSettingsPermission(); 5254 5255 if (timeMs > System.currentTimeMillis() + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS) { 5256 throw new IllegalArgumentException("Argument should not exceed " 5257 + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS + "ms from now"); 5258 } 5259 5260 mHandler.sendMessage( 5261 mHandler.obtainMessage(EVENT_SET_LOW_TCP_POLLING_UNTIL, timeMs)); 5262 } 5263 5264 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 5265 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 5266 " accept=" + accept + " always=" + always); 5267 5268 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5269 if (nai == null) { 5270 // Nothing to do. 5271 return; 5272 } 5273 5274 if (nai.everValidated()) { 5275 // The network validated while the dialog box was up. Take no action. 5276 return; 5277 } 5278 5279 if (!nai.networkAgentConfig.explicitlySelected) { 5280 Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 5281 } 5282 5283 if (accept != nai.networkAgentConfig.acceptUnvalidated) { 5284 nai.networkAgentConfig.acceptUnvalidated = accept; 5285 // If network becomes partial connectivity and user already accepted to use this 5286 // network, we should respect the user's option and don't need to popup the 5287 // PARTIAL_CONNECTIVITY notification to user again. 5288 nai.networkAgentConfig.acceptPartialConnectivity = accept; 5289 nai.updateScoreForNetworkAgentUpdate(); 5290 rematchAllNetworksAndRequests(); 5291 } 5292 5293 if (always) { 5294 nai.onSaveAcceptUnvalidated(accept); 5295 } 5296 5297 if (!accept) { 5298 // Tell the NetworkAgent to not automatically reconnect to the network. 5299 nai.onPreventAutomaticReconnect(); 5300 // Teardown the network. 5301 teardownUnneededNetwork(nai); 5302 } 5303 5304 } 5305 5306 private void handleSetAcceptPartialConnectivity(Network network, boolean accept, 5307 boolean always) { 5308 if (DBG) { 5309 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept 5310 + " always=" + always); 5311 } 5312 5313 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5314 if (nai == null) { 5315 // Nothing to do. 5316 return; 5317 } 5318 5319 if (nai.isValidated()) { 5320 // The network validated while the dialog box was up. Take no action. 5321 return; 5322 } 5323 5324 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) { 5325 nai.networkAgentConfig.acceptPartialConnectivity = accept; 5326 } 5327 5328 // TODO: Use the current design or save the user choice into IpMemoryStore. 5329 if (always) { 5330 nai.onSaveAcceptUnvalidated(accept); 5331 } 5332 5333 if (!accept) { 5334 // Tell the NetworkAgent to not automatically reconnect to the network. 5335 nai.onPreventAutomaticReconnect(); 5336 // Tear down the network. 5337 teardownUnneededNetwork(nai); 5338 } else { 5339 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely 5340 // result in a partial connectivity result which will be processed by 5341 // maybeHandleNetworkMonitorMessage. 5342 // 5343 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored 5344 // per network. Therefore, NetworkMonitor may still do https probe. 5345 nai.networkMonitor().setAcceptPartialConnectivity(); 5346 } 5347 } 5348 5349 private void handleSetAvoidUnvalidated(Network network) { 5350 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5351 if (nai == null || nai.isValidated()) { 5352 // Nothing to do. The network either disconnected or revalidated. 5353 return; 5354 } 5355 if (0L == nai.getAvoidUnvalidated()) { 5356 nai.setAvoidUnvalidated(); 5357 nai.updateScoreForNetworkAgentUpdate(); 5358 rematchAllNetworksAndRequests(); 5359 } 5360 } 5361 5362 /** Schedule evaluation timeout */ 5363 @VisibleForTesting 5364 public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) { 5365 mDeps.scheduleEvaluationTimeout(mHandler, network, delayMs); 5366 } 5367 5368 @Override 5369 public void startCaptivePortalApp(Network network) { 5370 enforceNetworkStackOrSettingsPermission(); 5371 mHandler.post(() -> { 5372 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5373 if (nai == null) return; 5374 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 5375 nai.networkMonitor().launchCaptivePortalApp(); 5376 }); 5377 } 5378 5379 /** 5380 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this 5381 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. 5382 * @param network Network on which the captive portal was detected. 5383 * @param appExtras Bundle to use as intent extras for the captive portal application. 5384 * Must be treated as opaque to avoid preventing the captive portal app to 5385 * update its arguments. 5386 */ 5387 @Override 5388 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { 5389 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 5390 "ConnectivityService"); 5391 5392 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); 5393 appIntent.putExtras(appExtras); 5394 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, 5395 new CaptivePortal(new CaptivePortalImpl(network).asBinder())); 5396 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); 5397 5398 final long token = Binder.clearCallingIdentity(); 5399 try { 5400 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT); 5401 } finally { 5402 Binder.restoreCallingIdentity(token); 5403 } 5404 } 5405 5406 private class CaptivePortalImpl extends ICaptivePortal.Stub { 5407 private final Network mNetwork; 5408 5409 private CaptivePortalImpl(Network network) { 5410 mNetwork = network; 5411 } 5412 5413 @Override 5414 public void appResponse(final int response) { 5415 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { 5416 enforceSettingsPermission(); 5417 } else if (response == CaptivePortal.APP_RETURN_UNWANTED) { 5418 mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork)); 5419 // Since the network will be disconnected, skip notifying NetworkMonitor 5420 return; 5421 } 5422 5423 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 5424 if (nm == null) return; 5425 nm.notifyCaptivePortalAppFinished(response); 5426 } 5427 5428 @Override 5429 public void appRequest(final int request) { 5430 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); 5431 if (nm == null) return; 5432 5433 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) { 5434 checkNetworkStackPermission(); 5435 nm.forceReevaluation(mDeps.getCallingUid()); 5436 } 5437 } 5438 5439 @Nullable 5440 private NetworkMonitorManager getNetworkMonitorManager(final Network network) { 5441 // getNetworkAgentInfoForNetwork is thread-safe 5442 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5443 if (nai == null) return null; 5444 5445 // nai.networkMonitor() is thread-safe 5446 return nai.networkMonitor(); 5447 } 5448 } 5449 5450 public boolean avoidBadWifi() { 5451 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 5452 } 5453 5454 private boolean activelyPreferBadWifi() { 5455 return mMultinetworkPolicyTracker.getActivelyPreferBadWifi(); 5456 } 5457 5458 /** 5459 * Return whether the device should maintain continuous, working connectivity by switching away 5460 * from WiFi networks having no connectivity. 5461 * @see MultinetworkPolicyTracker#getAvoidBadWifi() 5462 */ 5463 public boolean shouldAvoidBadWifi() { 5464 if (!checkNetworkStackPermission()) { 5465 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); 5466 } 5467 return avoidBadWifi(); 5468 } 5469 5470 private void updateAvoidBadWifi() { 5471 ensureRunningOnConnectivityServiceThread(); 5472 // Agent info scores and offer scores depend on whether cells yields to bad wifi. 5473 final boolean avoidBadWifi = avoidBadWifi(); 5474 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 5475 nai.updateScoreForNetworkAgentUpdate(); 5476 if (avoidBadWifi) { 5477 // If the device is now avoiding bad wifi, remove notifications that might have 5478 // been put up when the device didn't. 5479 mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET); 5480 } 5481 } 5482 // UpdateOfferScore will update mNetworkOffers inline, so make a copy first. 5483 final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers); 5484 for (final NetworkOfferInfo noi : offersToUpdate) { 5485 updateOfferScore(noi.offer); 5486 } 5487 mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi())); 5488 rematchAllNetworksAndRequests(); 5489 } 5490 5491 // TODO: Evaluate whether this is of interest to other consumers of 5492 // MultinetworkPolicyTracker and worth moving out of here. 5493 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 5494 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 5495 if (!configRestrict) { 5496 pw.println("Bad Wi-Fi avoidance: unrestricted"); 5497 return; 5498 } 5499 5500 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 5501 pw.increaseIndent(); 5502 pw.println("Config restrict: " + configRestrict); 5503 pw.println("Actively prefer bad wifi: " + activelyPreferBadWifi()); 5504 5505 final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 5506 String description; 5507 // Can't use a switch statement because strings are legal case labels, but null is not. 5508 if ("0".equals(settingValue)) { 5509 description = "get stuck"; 5510 } else if (settingValue == null) { 5511 description = "prompt"; 5512 } else if ("1".equals(settingValue)) { 5513 description = "avoid"; 5514 } else { 5515 description = settingValue + " (?)"; 5516 } 5517 pw.println("Avoid bad wifi setting: " + description); 5518 5519 final Boolean configValue = BinderUtils.withCleanCallingIdentity( 5520 () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi()); 5521 if (null == configValue) { 5522 description = "unset"; 5523 } else if (configValue) { 5524 description = "force true"; 5525 } else { 5526 description = "force false"; 5527 } 5528 pw.println("Actively prefer bad wifi conf: " + description); 5529 pw.println(); 5530 pw.println("Network overrides:"); 5531 pw.increaseIndent(); 5532 for (NetworkAgentInfo nai : networksSortedById()) { 5533 if (0L != nai.getAvoidUnvalidated()) { 5534 pw.println(nai.toShortString()); 5535 } 5536 } 5537 pw.decreaseIndent(); 5538 pw.decreaseIndent(); 5539 } 5540 5541 // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to 5542 // unify the method. 5543 private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) { 5544 final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS); 5545 final ComponentName settingsComponent = settingsIntent.resolveActivity(pm); 5546 return settingsComponent != null 5547 ? settingsComponent.getPackageName() : "com.android.settings"; 5548 } 5549 5550 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) { 5551 final String action; 5552 final boolean highPriority; 5553 switch (type) { 5554 case NO_INTERNET: 5555 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 5556 // High priority because it is only displayed for explicitly selected networks. 5557 highPriority = true; 5558 break; 5559 case PRIVATE_DNS_BROKEN: 5560 action = Settings.ACTION_WIRELESS_SETTINGS; 5561 // High priority because we should let user know why there is no internet. 5562 highPriority = true; 5563 break; 5564 case LOST_INTERNET: 5565 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 5566 // High priority because it could help the user avoid unexpected data usage. 5567 highPriority = true; 5568 break; 5569 case PARTIAL_CONNECTIVITY: 5570 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY; 5571 // Don't bother the user with a high-priority notification if the network was not 5572 // explicitly selected by the user. 5573 highPriority = nai.networkAgentConfig.explicitlySelected; 5574 break; 5575 default: 5576 Log.wtf(TAG, "Unknown notification type " + type); 5577 return; 5578 } 5579 5580 Intent intent = new Intent(action); 5581 if (type != NotificationType.PRIVATE_DNS_BROKEN) { 5582 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network); 5583 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5584 // Some OEMs have their own Settings package. Thus, need to get the current using 5585 // Settings package name instead of just use default name "com.android.settings". 5586 final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager()); 5587 intent.setClassName(settingsPkgName, 5588 settingsPkgName + ".wifi.WifiNoInternetDialog"); 5589 } 5590 5591 PendingIntent pendingIntent = PendingIntent.getActivity( 5592 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 5593 0 /* requestCode */, 5594 intent, 5595 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 5596 5597 mNotifier.showNotification( 5598 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority); 5599 } 5600 5601 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) { 5602 // Don't prompt if the network is validated, and don't prompt on captive portals 5603 // because we're already prompting the user to sign in. 5604 if (nai.everValidated() || nai.everCaptivePortalDetected()) { 5605 return false; 5606 } 5607 5608 // If a network has partial connectivity, always prompt unless the user has already accepted 5609 // partial connectivity and selected don't ask again. This ensures that if the device 5610 // automatically connects to a network that has partial Internet access, the user will 5611 // always be able to use it, either because they've already chosen "don't ask again" or 5612 // because we have prompted them. 5613 if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) { 5614 return true; 5615 } 5616 5617 // If a network has no Internet access, only prompt if the network was explicitly selected 5618 // and if the user has not already told us to use the network regardless of whether it 5619 // validated or not. 5620 if (nai.networkAgentConfig.explicitlySelected 5621 && !nai.networkAgentConfig.acceptUnvalidated) { 5622 return true; 5623 } 5624 5625 return false; 5626 } 5627 5628 private void handleInitialEvaluationTimeout(@NonNull final Network network) { 5629 if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network); 5630 5631 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5632 if (null == nai) return; 5633 5634 if (nai.setEvaluated()) { 5635 // If setEvaluated() returned true, the network never had any form of connectivity. 5636 // This may have an impact on request matching if bad WiFi avoidance is off and the 5637 // network was found not to have Internet access. 5638 nai.updateScoreForNetworkAgentUpdate(); 5639 rematchAllNetworksAndRequests(); 5640 5641 // Also, if this is WiFi and it should be preferred actively, now is the time to 5642 // prompt the user that they walked past and connected to a bad WiFi. 5643 if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI) 5644 && !avoidBadWifi() 5645 && activelyPreferBadWifi()) { 5646 // The notification will be removed if the network validates or disconnects. 5647 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 5648 return; 5649 } 5650 } 5651 5652 if (!shouldPromptUnvalidated(nai)) return; 5653 5654 // Stop automatically reconnecting to this network in the future. Automatically connecting 5655 // to a network that provides no or limited connectivity is not useful, because the user 5656 // cannot use that network except through the notification shown by this method, and the 5657 // notification is only shown if the network is explicitly selected by the user. 5658 nai.onPreventAutomaticReconnect(); 5659 5660 if (nai.partialConnectivity()) { 5661 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); 5662 } else { 5663 showNetworkNotification(nai, NotificationType.NO_INTERNET); 5664 } 5665 } 5666 5667 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 5668 NetworkCapabilities nc = nai.networkCapabilities; 5669 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc); 5670 5671 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 5672 return; 5673 } 5674 5675 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 5676 showNetworkNotification(nai, NotificationType.LOST_INTERNET); 5677 } 5678 } 5679 5680 @Override 5681 public int getMultipathPreference(Network network) { 5682 enforceAccessPermission(); 5683 5684 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 5685 if (nai != null && nai.networkCapabilities 5686 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 5687 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 5688 } 5689 5690 final NetworkPolicyManager netPolicyManager = 5691 mContext.getSystemService(NetworkPolicyManager.class); 5692 5693 final long token = Binder.clearCallingIdentity(); 5694 final int networkPreference; 5695 try { 5696 networkPreference = netPolicyManager.getMultipathPreference(network); 5697 } finally { 5698 Binder.restoreCallingIdentity(token); 5699 } 5700 if (networkPreference != 0) { 5701 return networkPreference; 5702 } 5703 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 5704 } 5705 5706 @Override 5707 public NetworkRequest getDefaultRequest() { 5708 return mDefaultRequest.mRequests.get(0); 5709 } 5710 5711 private class InternalHandler extends Handler { 5712 public InternalHandler(Looper looper) { 5713 super(looper); 5714 } 5715 5716 @Override 5717 public void handleMessage(Message msg) { 5718 switch (msg.what) { 5719 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 5720 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 5721 handleReleaseNetworkTransitionWakelock(msg.what); 5722 break; 5723 } 5724 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 5725 mProxyTracker.loadDeprecatedGlobalHttpProxy(); 5726 break; 5727 } 5728 case EVENT_PAC_PROXY_HAS_CHANGED: { 5729 final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj; 5730 handlePacProxyServiceStarted(arg.first, arg.second); 5731 break; 5732 } 5733 case EVENT_REGISTER_NETWORK_PROVIDER: { 5734 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); 5735 break; 5736 } 5737 case EVENT_UNREGISTER_NETWORK_PROVIDER: { 5738 handleUnregisterNetworkProvider((Messenger) msg.obj); 5739 break; 5740 } 5741 case EVENT_REGISTER_NETWORK_OFFER: { 5742 handleRegisterNetworkOffer((NetworkOffer) msg.obj); 5743 break; 5744 } 5745 case EVENT_UNREGISTER_NETWORK_OFFER: { 5746 final NetworkOfferInfo offer = 5747 findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj); 5748 if (null != offer) { 5749 handleUnregisterNetworkOffer(offer); 5750 } 5751 break; 5752 } 5753 case EVENT_REGISTER_NETWORK_AGENT: { 5754 final Pair<NetworkAgentInfo, INetworkMonitor> arg = 5755 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; 5756 handleRegisterNetworkAgent(arg.first, arg.second); 5757 break; 5758 } 5759 case EVENT_REGISTER_NETWORK_REQUEST: 5760 case EVENT_REGISTER_NETWORK_LISTENER: { 5761 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 5762 break; 5763 } 5764 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 5765 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 5766 handleRegisterNetworkRequestWithIntent(msg); 5767 break; 5768 } 5769 case EVENT_TIMEOUT_NETWORK_REQUEST: { 5770 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 5771 handleTimedOutNetworkRequest(nri); 5772 break; 5773 } 5774 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 5775 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 5776 break; 5777 } 5778 case EVENT_RELEASE_NETWORK_REQUEST: { 5779 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1, 5780 /* callOnUnavailable */ false); 5781 break; 5782 } 5783 case EVENT_SET_ACCEPT_UNVALIDATED: { 5784 Network network = (Network) msg.obj; 5785 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 5786 break; 5787 } 5788 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: { 5789 Network network = (Network) msg.obj; 5790 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1), 5791 toBool(msg.arg2)); 5792 break; 5793 } 5794 case EVENT_SET_AVOID_UNVALIDATED: { 5795 handleSetAvoidUnvalidated((Network) msg.obj); 5796 break; 5797 } 5798 case EVENT_INITIAL_EVALUATION_TIMEOUT: { 5799 handleInitialEvaluationTimeout((Network) msg.obj); 5800 break; 5801 } 5802 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { 5803 handleConfigureAlwaysOnNetworks(); 5804 break; 5805 } 5806 // Sent by AutomaticOnOffKeepaliveTracker to process an app request on the 5807 // handler thread. 5808 case AutomaticOnOffKeepaliveTracker.CMD_REQUEST_START_KEEPALIVE: { 5809 mKeepaliveTracker.handleStartKeepalive(msg); 5810 break; 5811 } 5812 case AutomaticOnOffKeepaliveTracker.CMD_MONITOR_AUTOMATIC_KEEPALIVE: { 5813 final AutomaticOnOffKeepalive ki = 5814 mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj); 5815 if (null == ki) return; // The callback was unregistered before the alarm fired 5816 5817 final Network underpinnedNetwork = ki.getUnderpinnedNetwork(); 5818 final Network network = ki.getNetwork(); 5819 boolean networkFound = false; 5820 boolean underpinnedNetworkFound = false; 5821 for (NetworkAgentInfo n : mNetworkAgentInfos) { 5822 if (n.network.equals(network)) networkFound = true; 5823 if (n.everConnected() && n.network.equals(underpinnedNetwork)) { 5824 underpinnedNetworkFound = true; 5825 } 5826 } 5827 5828 // If the network no longer exists, then the keepalive should have been 5829 // cleaned up already. There is no point trying to resume keepalives. 5830 if (!networkFound) return; 5831 5832 if (underpinnedNetworkFound) { 5833 mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki, 5834 underpinnedNetwork.netId); 5835 } else { 5836 // If no underpinned network, then make sure the keepalive is running. 5837 mKeepaliveTracker.handleMaybeResumeKeepalive(ki); 5838 } 5839 break; 5840 } 5841 // Sent by KeepaliveTracker to process an app request on the state machine thread. 5842 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: { 5843 final AutomaticOnOffKeepalive ki = mKeepaliveTracker.getKeepaliveForBinder( 5844 (IBinder) msg.obj); 5845 if (ki == null) { 5846 Log.e(TAG, "Attempt to stop an already stopped keepalive"); 5847 return; 5848 } 5849 final int reason = msg.arg2; 5850 mKeepaliveTracker.handleStopKeepalive(ki, reason); 5851 break; 5852 } 5853 case EVENT_REPORT_NETWORK_CONNECTIVITY: { 5854 handleReportNetworkConnectivity((NetworkAgentInfo) msg.obj, msg.arg1, 5855 toBool(msg.arg2)); 5856 break; 5857 } 5858 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 5859 handlePrivateDnsSettingsChanged(); 5860 break; 5861 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 5862 handlePrivateDnsValidationUpdate( 5863 (PrivateDnsValidationUpdate) msg.obj); 5864 break; 5865 case EVENT_UID_BLOCKED_REASON_CHANGED: 5866 handleUidBlockedReasonChanged(msg.arg1, msg.arg2); 5867 break; 5868 case EVENT_SET_REQUIRE_VPN_FOR_UIDS: 5869 handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); 5870 break; 5871 case EVENT_SET_OEM_NETWORK_PREFERENCE: { 5872 final Pair<OemNetworkPreferences, IOnCompleteListener> arg = 5873 (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj; 5874 handleSetOemNetworkPreference(arg.first, arg.second); 5875 break; 5876 } 5877 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: { 5878 final Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener> arg = 5879 (Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener>) msg.obj; 5880 handleSetProfileNetworkPreference(arg.first, arg.second); 5881 break; 5882 } 5883 case EVENT_REPORT_NETWORK_ACTIVITY: 5884 mNetworkActivityTracker.handleReportNetworkActivity(); 5885 break; 5886 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED: 5887 handleMobileDataPreferredUidsChanged(); 5888 break; 5889 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL: 5890 final long timeMs = ((Long) msg.obj).longValue(); 5891 mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs); 5892 break; 5893 case EVENT_INGRESS_RATE_LIMIT_CHANGED: 5894 handleIngressRateLimitChanged(); 5895 break; 5896 case EVENT_USER_DOES_NOT_WANT: 5897 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 5898 if (nai == null) break; 5899 nai.onPreventAutomaticReconnect(); 5900 nai.disconnect(); 5901 break; 5902 case EVENT_SET_VPN_NETWORK_PREFERENCE: 5903 handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj); 5904 break; 5905 case EVENT_SET_LOW_TCP_POLLING_UNTIL: { 5906 final long time = ((Long) msg.obj).longValue(); 5907 mKeepaliveTracker.handleSetTestLowTcpPollingTimer(time); 5908 break; 5909 } 5910 case EVENT_UID_FROZEN_STATE_CHANGED: 5911 UidFrozenStateChangedArgs args = (UidFrozenStateChangedArgs) msg.obj; 5912 handleFrozenUids(args.mUids, args.mFrozenStates); 5913 break; 5914 } 5915 } 5916 } 5917 5918 @Override 5919 @Deprecated 5920 public int getLastTetherError(String iface) { 5921 enforceAccessPermission(); 5922 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5923 Context.TETHERING_SERVICE); 5924 return tm.getLastTetherError(iface); 5925 } 5926 5927 @Override 5928 @Deprecated 5929 public String[] getTetherableIfaces() { 5930 enforceAccessPermission(); 5931 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5932 Context.TETHERING_SERVICE); 5933 return tm.getTetherableIfaces(); 5934 } 5935 5936 @Override 5937 @Deprecated 5938 public String[] getTetheredIfaces() { 5939 enforceAccessPermission(); 5940 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5941 Context.TETHERING_SERVICE); 5942 return tm.getTetheredIfaces(); 5943 } 5944 5945 5946 @Override 5947 @Deprecated 5948 public String[] getTetheringErroredIfaces() { 5949 enforceAccessPermission(); 5950 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5951 Context.TETHERING_SERVICE); 5952 5953 return tm.getTetheringErroredIfaces(); 5954 } 5955 5956 @Override 5957 @Deprecated 5958 public String[] getTetherableUsbRegexs() { 5959 enforceAccessPermission(); 5960 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5961 Context.TETHERING_SERVICE); 5962 5963 return tm.getTetherableUsbRegexs(); 5964 } 5965 5966 @Override 5967 @Deprecated 5968 public String[] getTetherableWifiRegexs() { 5969 enforceAccessPermission(); 5970 final TetheringManager tm = (TetheringManager) mContext.getSystemService( 5971 Context.TETHERING_SERVICE); 5972 return tm.getTetherableWifiRegexs(); 5973 } 5974 5975 // Called when we lose the default network and have no replacement yet. 5976 // This will automatically be cleared after X seconds or a new default network 5977 // becomes CONNECTED, whichever happens first. The timer is started by the 5978 // first caller and not restarted by subsequent callers. 5979 private void ensureNetworkTransitionWakelock(String forWhom) { 5980 synchronized (this) { 5981 if (mNetTransitionWakeLock.isHeld()) { 5982 return; 5983 } 5984 mNetTransitionWakeLock.acquire(); 5985 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 5986 mTotalWakelockAcquisitions++; 5987 } 5988 mWakelockLogs.log("ACQUIRE for " + forWhom); 5989 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 5990 final int lockTimeout = mResources.get().getInteger( 5991 R.integer.config_networkTransitionTimeout); 5992 mHandler.sendMessageDelayed(msg, lockTimeout); 5993 } 5994 5995 // Called when we gain a new default network to release the network transition wakelock in a 5996 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 5997 // message is cancelled. 5998 private void scheduleReleaseNetworkTransitionWakelock() { 5999 synchronized (this) { 6000 if (!mNetTransitionWakeLock.isHeld()) { 6001 return; // expiry message released the lock first. 6002 } 6003 } 6004 // Cancel self timeout on wakelock hold. 6005 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 6006 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 6007 mHandler.sendMessageDelayed(msg, 1000); 6008 } 6009 6010 // Called when either message of ensureNetworkTransitionWakelock or 6011 // scheduleReleaseNetworkTransitionWakelock is processed. 6012 private void handleReleaseNetworkTransitionWakelock(int eventId) { 6013 String event = eventName(eventId); 6014 synchronized (this) { 6015 if (!mNetTransitionWakeLock.isHeld()) { 6016 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 6017 Log.w(TAG, "expected Net Transition WakeLock to be held"); 6018 return; 6019 } 6020 mNetTransitionWakeLock.release(); 6021 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 6022 mTotalWakelockDurationMs += lockDuration; 6023 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 6024 mTotalWakelockReleases++; 6025 } 6026 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 6027 } 6028 6029 // 100 percent is full good, 0 is full bad. 6030 @Override 6031 public void reportInetCondition(int networkType, int percentage) { 6032 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 6033 if (nai == null) return; 6034 reportNetworkConnectivity(nai.network, percentage > 50); 6035 } 6036 6037 @Override 6038 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 6039 enforceAccessPermission(); 6040 enforceInternetPermission(); 6041 final int uid = mDeps.getCallingUid(); 6042 final int connectivityInfo = encodeBool(hasConnectivity); 6043 6044 final NetworkAgentInfo nai; 6045 if (network == null) { 6046 nai = getDefaultNetwork(); 6047 } else { 6048 nai = getNetworkAgentInfoForNetwork(network); 6049 } 6050 6051 mHandler.sendMessage( 6052 mHandler.obtainMessage( 6053 EVENT_REPORT_NETWORK_CONNECTIVITY, uid, connectivityInfo, nai)); 6054 } 6055 6056 private void handleReportNetworkConnectivity( 6057 @Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) { 6058 if (nai == null 6059 || nai != getNetworkAgentInfoForNetwork(nai.network) 6060 || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 6061 return; 6062 } 6063 // Revalidate if the app report does not match our current validated state. 6064 if (hasConnectivity == nai.isValidated()) { 6065 mConnectivityDiagnosticsHandler.sendMessage( 6066 mConnectivityDiagnosticsHandler.obtainMessage( 6067 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 6068 new ReportedNetworkConnectivityInfo( 6069 hasConnectivity, false /* isNetworkRevalidating */, uid, nai))); 6070 return; 6071 } 6072 if (DBG) { 6073 int netid = nai.network.getNetId(); 6074 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 6075 } 6076 // Validating a network that has not yet connected could result in a call to 6077 // rematchNetworkAndRequests() which is not meant to work on such networks. 6078 if (!nai.everConnected()) { 6079 return; 6080 } 6081 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 6082 if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) { 6083 return; 6084 } 6085 6086 // Send CONNECTIVITY_REPORTED event before re-validating the Network to force an ordering of 6087 // ConnDiags events. This ensures that #onNetworkConnectivityReported() will be called 6088 // before #onConnectivityReportAvailable(), which is called once Network evaluation is 6089 // completed. 6090 mConnectivityDiagnosticsHandler.sendMessage( 6091 mConnectivityDiagnosticsHandler.obtainMessage( 6092 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED, 6093 new ReportedNetworkConnectivityInfo( 6094 hasConnectivity, true /* isNetworkRevalidating */, uid, nai))); 6095 nai.networkMonitor().forceReevaluation(uid); 6096 } 6097 6098 // TODO: call into netd. 6099 private boolean queryUserAccess(int uid, Network network) { 6100 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6101 if (nai == null) return false; 6102 6103 // Any UID can use its default network. 6104 if (nai == getDefaultNetworkForUid(uid)) return true; 6105 6106 // Privileged apps can use any network. 6107 if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) { 6108 return true; 6109 } 6110 6111 // An unprivileged UID can use a VPN iff the VPN applies to it. 6112 if (nai.isVPN()) { 6113 return nai.networkCapabilities.appliesToUid(uid); 6114 } 6115 6116 // An unprivileged UID can bypass the VPN that applies to it only if it can protect its 6117 // sockets, i.e., if it is the owner. 6118 final NetworkAgentInfo vpn = getVpnForUid(uid); 6119 if (vpn != null && !vpn.networkAgentConfig.allowBypass 6120 && uid != vpn.networkCapabilities.getOwnerUid()) { 6121 return false; 6122 } 6123 6124 // The UID's permission must be at least sufficient for the network. Since the restricted 6125 // permission was already checked above, that just leaves background networks. 6126 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { 6127 return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid); 6128 } 6129 6130 // Unrestricted network. Anyone gets to use it. 6131 return true; 6132 } 6133 6134 /** 6135 * Returns information about the proxy a certain network is using. If given a null network, it 6136 * it will return the proxy for the bound network for the caller app or the default proxy if 6137 * none. 6138 * 6139 * @param network the network we want to get the proxy information for. 6140 * @return Proxy information if a network has a proxy configured, or otherwise null. 6141 */ 6142 @Override 6143 public ProxyInfo getProxyForNetwork(Network network) { 6144 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy(); 6145 if (globalProxy != null) return globalProxy; 6146 if (network == null) { 6147 // Get the network associated with the calling UID. 6148 final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(), 6149 true); 6150 if (activeNetwork == null) { 6151 return null; 6152 } 6153 return getLinkPropertiesProxyInfo(activeNetwork); 6154 } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) { 6155 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 6156 // caller may not have. 6157 return getLinkPropertiesProxyInfo(network); 6158 } 6159 // No proxy info available if the calling UID does not have network access. 6160 return null; 6161 } 6162 6163 6164 private ProxyInfo getLinkPropertiesProxyInfo(Network network) { 6165 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 6166 if (nai == null) return null; 6167 synchronized (nai) { 6168 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy(); 6169 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy); 6170 } 6171 } 6172 6173 @Override 6174 public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) { 6175 enforceNetworkStackPermission(mContext); 6176 mProxyTracker.setGlobalProxy(proxyProperties); 6177 } 6178 6179 @Override 6180 @Nullable 6181 public ProxyInfo getGlobalProxy() { 6182 return mProxyTracker.getGlobalProxy(); 6183 } 6184 6185 private void handlePacProxyServiceStarted(@Nullable Network net, @Nullable ProxyInfo proxy) { 6186 mProxyTracker.setDefaultProxy(proxy); 6187 final NetworkAgentInfo nai = getDefaultNetwork(); 6188 // TODO : this method should check that net == nai.network, unfortunately at this point 6189 // 'net' is always null in practice (see PacProxyService#sendPacBroadcast). PAC proxy 6190 // is only ever installed on the default network so in practice this is okay. 6191 if (null == nai) return; 6192 // PAC proxies only work on the default network. Therefore, only the default network 6193 // should have its link properties fixed up for PAC proxies. 6194 mProxyTracker.updateDefaultNetworkProxyPortForPAC(nai.linkProperties, nai.network); 6195 if (nai.everConnected()) { 6196 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_IP_CHANGED); 6197 } 6198 } 6199 6200 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called 6201 // when any network changes proxy. 6202 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a 6203 // multi-network world where an app might be bound to a non-default network. 6204 private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) { 6205 ProxyInfo newProxyInfo = newLp.getHttpProxy(); 6206 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 6207 6208 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 6209 mProxyTracker.sendProxyBroadcast(); 6210 } 6211 } 6212 6213 private static class SettingsObserver extends ContentObserver { 6214 final private HashMap<Uri, Integer> mUriEventMap; 6215 final private Context mContext; 6216 final private Handler mHandler; 6217 6218 SettingsObserver(Context context, Handler handler) { 6219 super(null); 6220 mUriEventMap = new HashMap<>(); 6221 mContext = context; 6222 mHandler = handler; 6223 } 6224 6225 void observe(Uri uri, int what) { 6226 mUriEventMap.put(uri, what); 6227 final ContentResolver resolver = mContext.getContentResolver(); 6228 resolver.registerContentObserver(uri, false, this); 6229 } 6230 6231 @Override 6232 public void onChange(boolean selfChange) { 6233 Log.wtf(TAG, "Should never be reached."); 6234 } 6235 6236 @Override 6237 public void onChange(boolean selfChange, Uri uri) { 6238 final Integer what = mUriEventMap.get(uri); 6239 if (what != null) { 6240 mHandler.obtainMessage(what).sendToTarget(); 6241 } else { 6242 loge("No matching event to send for URI=" + uri); 6243 } 6244 } 6245 } 6246 6247 private static void log(String s) { 6248 Log.d(TAG, s); 6249 } 6250 6251 private static void logw(String s) { 6252 Log.w(TAG, s); 6253 } 6254 6255 private static void logwtf(String s) { 6256 Log.wtf(TAG, s); 6257 } 6258 6259 private static void logwtf(String s, Throwable t) { 6260 Log.wtf(TAG, s, t); 6261 } 6262 6263 private static void loge(String s) { 6264 Log.e(TAG, s); 6265 } 6266 6267 private static void loge(String s, Throwable t) { 6268 Log.e(TAG, s, t); 6269 } 6270 6271 /** 6272 * Return the information of all ongoing VPNs. 6273 * 6274 * <p>This method is used to update NetworkStatsService. 6275 * 6276 * <p>Must be called on the handler thread. 6277 */ 6278 private UnderlyingNetworkInfo[] getAllVpnInfo() { 6279 ensureRunningOnConnectivityServiceThread(); 6280 if (mLockdownEnabled) { 6281 return new UnderlyingNetworkInfo[0]; 6282 } 6283 List<UnderlyingNetworkInfo> infoList = new ArrayList<>(); 6284 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 6285 UnderlyingNetworkInfo info = createVpnInfo(nai); 6286 if (info != null) { 6287 infoList.add(info); 6288 } 6289 } 6290 return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]); 6291 } 6292 6293 /** 6294 * @return VPN information for accounting, or null if we can't retrieve all required 6295 * information, e.g underlying ifaces. 6296 */ 6297 private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) { 6298 Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; 6299 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 6300 // the underlyingNetworks list. 6301 // TODO: stop using propagateUnderlyingCapabilities here, for example, by always 6302 // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array. 6303 if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) { 6304 final NetworkAgentInfo defaultNai = getDefaultNetworkForUid( 6305 nai.networkCapabilities.getOwnerUid()); 6306 if (defaultNai != null) { 6307 underlyingNetworks = new Network[] { defaultNai.network }; 6308 } 6309 } 6310 6311 if (CollectionUtils.isEmpty(underlyingNetworks)) return null; 6312 6313 List<String> interfaces = new ArrayList<>(); 6314 for (Network network : underlyingNetworks) { 6315 NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network); 6316 if (underlyingNai == null) continue; 6317 LinkProperties lp = underlyingNai.linkProperties; 6318 for (String iface : lp.getAllInterfaceNames()) { 6319 if (!TextUtils.isEmpty(iface)) { 6320 interfaces.add(iface); 6321 } 6322 } 6323 } 6324 6325 if (interfaces.isEmpty()) return null; 6326 6327 // Must be non-null or NetworkStatsService will crash. 6328 // Cannot happen in production code because Vpn only registers the NetworkAgent after the 6329 // tun or ipsec interface is created. 6330 // TODO: Remove this check. 6331 if (nai.linkProperties.getInterfaceName() == null) return null; 6332 6333 return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(), 6334 nai.linkProperties.getInterfaceName(), interfaces); 6335 } 6336 6337 // TODO This needs to be the default network that applies to the NAI. 6338 private Network[] underlyingNetworksOrDefault(final int ownerUid, 6339 Network[] underlyingNetworks) { 6340 final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid)); 6341 if (underlyingNetworks == null && defaultNetwork != null) { 6342 // null underlying networks means to track the default. 6343 underlyingNetworks = new Network[] { defaultNetwork }; 6344 } 6345 return underlyingNetworks; 6346 } 6347 6348 // Returns true iff |network| is an underlying network of |nai|. 6349 private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) { 6350 // TODO: support more than one level of underlying networks, either via a fixed-depth search 6351 // (e.g., 2 levels of underlying networks), or via loop detection, or.... 6352 if (!nai.propagateUnderlyingCapabilities()) return false; 6353 final Network[] underlying = underlyingNetworksOrDefault( 6354 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks); 6355 return CollectionUtils.contains(underlying, network); 6356 } 6357 6358 /** 6359 * Recompute the capabilities for any networks that had a specific network as underlying. 6360 * 6361 * When underlying networks change, such networks may have to update capabilities to reflect 6362 * things like the metered bit, their transports, and so on. The capabilities are calculated 6363 * immediately. This method runs on the ConnectivityService thread. 6364 */ 6365 private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) { 6366 ensureRunningOnConnectivityServiceThread(); 6367 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 6368 if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) { 6369 updateCapabilitiesForNetwork(nai); 6370 } 6371 } 6372 } 6373 6374 private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) { 6375 // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies 6376 // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when 6377 // a VPN is not up. 6378 final NetworkAgentInfo vpnNai = getVpnForUid(uid); 6379 if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false; 6380 for (UidRange range : blockedUidRanges) { 6381 if (range.contains(uid)) return true; 6382 } 6383 return false; 6384 } 6385 6386 @Override 6387 public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 6388 enforceNetworkStackOrSettingsPermission(); 6389 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS, 6390 encodeBool(requireVpn), 0 /* arg2 */, ranges)); 6391 } 6392 6393 private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) { 6394 if (DBG) { 6395 Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: " 6396 + Arrays.toString(ranges)); 6397 } 6398 // Cannot use a Set since the list of UID ranges might contain duplicates. 6399 final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges); 6400 for (int i = 0; i < ranges.length; i++) { 6401 if (requireVpn) { 6402 newVpnBlockedUidRanges.add(ranges[i]); 6403 } else { 6404 newVpnBlockedUidRanges.remove(ranges[i]); 6405 } 6406 } 6407 6408 try { 6409 mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges)); 6410 } catch (RemoteException | ServiceSpecificException e) { 6411 Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", " 6412 + Arrays.toString(ranges) + "): netd command failed: " + e); 6413 } 6414 6415 if (mDeps.isAtLeastT()) { 6416 mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges); 6417 } 6418 6419 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 6420 final boolean curMetered = nai.networkCapabilities.isMetered(); 6421 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, 6422 mVpnBlockedUidRanges, newVpnBlockedUidRanges); 6423 } 6424 6425 mVpnBlockedUidRanges = newVpnBlockedUidRanges; 6426 } 6427 6428 @Override 6429 public void setLegacyLockdownVpnEnabled(boolean enabled) { 6430 enforceNetworkStackOrSettingsPermission(); 6431 mHandler.post(() -> mLockdownEnabled = enabled); 6432 } 6433 6434 private boolean isLegacyLockdownNai(NetworkAgentInfo nai) { 6435 return mLockdownEnabled 6436 && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY 6437 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID); 6438 } 6439 6440 private NetworkAgentInfo getLegacyLockdownNai() { 6441 if (!mLockdownEnabled) { 6442 return null; 6443 } 6444 // The legacy lockdown VPN always only applies to userId 0. 6445 final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID); 6446 if (nai == null || !isLegacyLockdownNai(nai)) return null; 6447 6448 // The legacy lockdown VPN must always have exactly one underlying network. 6449 // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in 6450 // a local variable. There is no need to make a copy because its contents cannot change. 6451 final Network[] underlying = nai.declaredUnderlyingNetworks; 6452 if (underlying == null || underlying.length != 1) { 6453 return null; 6454 } 6455 6456 // The legacy lockdown VPN always uses the default network. 6457 // If the VPN's underlying network is no longer the current default network, it means that 6458 // the default network has just switched, and the VPN is about to disconnect. 6459 // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten 6460 // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED. 6461 final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 6462 if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) { 6463 return null; 6464 } 6465 6466 return nai; 6467 }; 6468 6469 // TODO: move all callers to filterForLegacyLockdown and delete this method. 6470 // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of 6471 // just a DetailedState object. 6472 private DetailedState getLegacyLockdownState(DetailedState origState) { 6473 if (origState != DetailedState.CONNECTED) { 6474 return origState; 6475 } 6476 return (mLockdownEnabled && getLegacyLockdownNai() == null) 6477 ? DetailedState.CONNECTING 6478 : DetailedState.CONNECTED; 6479 } 6480 6481 private void filterForLegacyLockdown(NetworkInfo ni) { 6482 if (!mLockdownEnabled || !ni.isConnected()) return; 6483 // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the 6484 // state of its VPN. This is to ensure that when an underlying network connects, apps will 6485 // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN 6486 // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying 6487 // network, this time with a state of CONNECTED. 6488 // 6489 // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access 6490 // to the internal state of the Vpn object, always replace the state with CONNECTING. This 6491 // is not too far off the truth, since an always-on VPN, when not connected, is always 6492 // trying to reconnect. 6493 if (getLegacyLockdownNai() == null) { 6494 ni.setDetailedState(DetailedState.CONNECTING, "", null); 6495 } 6496 } 6497 6498 @Override 6499 public void setProvisioningNotificationVisible(boolean visible, int networkType, 6500 String action) { 6501 enforceSettingsPermission(); 6502 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 6503 return; 6504 } 6505 final long ident = Binder.clearCallingIdentity(); 6506 try { 6507 // Concatenate the range of types onto the range of NetIDs. 6508 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 6509 mNotifier.setProvNotificationVisible(visible, id, action); 6510 } finally { 6511 Binder.restoreCallingIdentity(ident); 6512 } 6513 } 6514 6515 @Override 6516 public void setAirplaneMode(boolean enable) { 6517 enforceAirplaneModePermission(); 6518 final long ident = Binder.clearCallingIdentity(); 6519 try { 6520 final ContentResolver cr = mContext.getContentResolver(); 6521 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 6522 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 6523 intent.putExtra("state", enable); 6524 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 6525 } finally { 6526 Binder.restoreCallingIdentity(ident); 6527 } 6528 } 6529 6530 private void onUserAdded(@NonNull final UserHandle user) { 6531 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 6532 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 6533 } 6534 updateProfileAllowedNetworks(); 6535 } 6536 6537 private void onUserRemoved(@NonNull final UserHandle user) { 6538 // If there was a network preference for this user, remove it. 6539 handleSetProfileNetworkPreference( 6540 List.of(new ProfileNetworkPreferenceInfo(user, null, true, 6541 false /* blockingNonEnterprise */)), 6542 null /* listener */); 6543 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) { 6544 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 6545 } 6546 } 6547 6548 private void onPackageChanged(@NonNull final String packageName) { 6549 // This is necessary in case a package is added or removed, but also when it's replaced to 6550 // run as a new UID by its manifest rules. Also, if a separate package shares the same UID 6551 // as one in the preferences, then it should follow the same routing as that other package, 6552 // which means updating the rules is never to be needed in this case (whether it joins or 6553 // leaves a UID with a preference). 6554 if (isMappedInOemNetworkPreference(packageName)) { 6555 handleSetOemNetworkPreference(mOemNetworkPreferences, null); 6556 } 6557 6558 // Invalidates cache entry when the package is updated. 6559 synchronized (mSelfCertifiedCapabilityCache) { 6560 mSelfCertifiedCapabilityCache.remove(packageName); 6561 } 6562 } 6563 6564 private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 6565 @Override 6566 public void onReceive(Context context, Intent intent) { 6567 ensureRunningOnConnectivityServiceThread(); 6568 final String action = intent.getAction(); 6569 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 6570 6571 // User should be filled for below intents, check the existence. 6572 if (user == null) { 6573 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER"); 6574 return; 6575 } 6576 6577 if (Intent.ACTION_USER_ADDED.equals(action)) { 6578 onUserAdded(user); 6579 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 6580 onUserRemoved(user); 6581 } else { 6582 Log.wtf(TAG, "received unexpected intent: " + action); 6583 } 6584 } 6585 }; 6586 6587 private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { 6588 @Override 6589 public void onReceive(Context context, Intent intent) { 6590 ensureRunningOnConnectivityServiceThread(); 6591 switch (intent.getAction()) { 6592 case Intent.ACTION_PACKAGE_ADDED: 6593 case Intent.ACTION_PACKAGE_REMOVED: 6594 case Intent.ACTION_PACKAGE_REPLACED: 6595 onPackageChanged(intent.getData().getSchemeSpecificPart()); 6596 break; 6597 default: 6598 Log.wtf(TAG, "received unexpected intent: " + intent.getAction()); 6599 } 6600 } 6601 }; 6602 6603 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); 6604 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); 6605 6606 private static class NetworkProviderInfo { 6607 public final String name; 6608 public final Messenger messenger; 6609 private final IBinder.DeathRecipient mDeathRecipient; 6610 public final int providerId; 6611 6612 NetworkProviderInfo(String name, Messenger messenger, int providerId, 6613 @NonNull IBinder.DeathRecipient deathRecipient) { 6614 this.name = name; 6615 this.messenger = messenger; 6616 this.providerId = providerId; 6617 mDeathRecipient = deathRecipient; 6618 6619 if (mDeathRecipient == null) { 6620 throw new AssertionError("Must pass a deathRecipient"); 6621 } 6622 } 6623 6624 void connect(Context context, Handler handler) { 6625 try { 6626 messenger.getBinder().linkToDeath(mDeathRecipient, 0); 6627 } catch (RemoteException e) { 6628 mDeathRecipient.binderDied(); 6629 } 6630 } 6631 } 6632 6633 private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) { 6634 for (int i = 0; i < requests.size(); i++) { 6635 ensureNetworkRequestHasType(requests.get(i)); 6636 } 6637 } 6638 6639 private void ensureNetworkRequestHasType(NetworkRequest request) { 6640 if (request.type == NetworkRequest.Type.NONE) { 6641 throw new IllegalArgumentException( 6642 "All NetworkRequests in ConnectivityService must have a type"); 6643 } 6644 } 6645 6646 /** 6647 * Tracks info about the requester. 6648 * Also used to notice when the calling process dies so as to self-expire 6649 */ 6650 @VisibleForTesting 6651 protected class NetworkRequestInfo implements IBinder.DeathRecipient { 6652 // The requests to be satisfied in priority order. Non-multilayer requests will only have a 6653 // single NetworkRequest in mRequests. 6654 final List<NetworkRequest> mRequests; 6655 6656 // mSatisfier and mActiveRequest rely on one another therefore set them together. 6657 void setSatisfier( 6658 @Nullable final NetworkAgentInfo satisfier, 6659 @Nullable final NetworkRequest activeRequest) { 6660 mSatisfier = satisfier; 6661 mActiveRequest = activeRequest; 6662 } 6663 6664 // The network currently satisfying this NRI. Only one request in an NRI can have a 6665 // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier. 6666 @Nullable 6667 private NetworkAgentInfo mSatisfier; 6668 NetworkAgentInfo getSatisfier() { 6669 return mSatisfier; 6670 } 6671 6672 // The request in mRequests assigned to a network agent. This is null if none of the 6673 // requests in mRequests can be satisfied. This member has the constraint of only being 6674 // accessible on the handler thread. 6675 @Nullable 6676 private NetworkRequest mActiveRequest; 6677 NetworkRequest getActiveRequest() { 6678 return mActiveRequest; 6679 } 6680 6681 final PendingIntent mPendingIntent; 6682 boolean mPendingIntentSent; 6683 @Nullable 6684 final Messenger mMessenger; 6685 6686 // Information about the caller that caused this object to be created. 6687 @Nullable 6688 private final IBinder mBinder; 6689 final int mPid; 6690 final int mUid; 6691 final @NetworkCallback.Flag int mCallbackFlags; 6692 @Nullable 6693 final String mCallingAttributionTag; 6694 6695 // Counter keeping track of this NRI. 6696 final RequestInfoPerUidCounter mPerUidCounter; 6697 6698 // Effective UID of this request. This is different from mUid when a privileged process 6699 // files a request on behalf of another UID. This UID is used to determine blocked status, 6700 // UID matching, and so on. mUid above is used for permission checks and to enforce the 6701 // maximum limit of registered callbacks per UID. 6702 final int mAsUid; 6703 6704 // Preference order of this request. 6705 final int mPreferenceOrder; 6706 6707 // In order to preserve the mapping of NetworkRequest-to-callback when apps register 6708 // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be 6709 // maintained for keying off of. This is only a concern when the original nri 6710 // mNetworkRequests changes which happens currently for apps that register callbacks to 6711 // track the default network. In those cases, the nri is updated to have mNetworkRequests 6712 // that match the per-app default nri that currently tracks the calling app's uid so that 6713 // callbacks are fired at the appropriate time. When the callbacks fire, 6714 // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When 6715 // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue. 6716 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 6717 @NonNull 6718 private final NetworkRequest mNetworkRequestForCallback; 6719 NetworkRequest getNetworkRequestForCallback() { 6720 return mNetworkRequestForCallback; 6721 } 6722 6723 /** 6724 * Get the list of UIDs this nri applies to. 6725 */ 6726 @NonNull 6727 Set<UidRange> getUids() { 6728 // networkCapabilities.getUids() returns a defensive copy. 6729 // multilayer requests will all have the same uids so return the first one. 6730 final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges(); 6731 return (null == uids) ? new ArraySet<>() : uids; 6732 } 6733 6734 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, 6735 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) { 6736 this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag, 6737 PREFERENCE_ORDER_INVALID); 6738 } 6739 6740 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 6741 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi, 6742 @Nullable String callingAttributionTag, final int preferenceOrder) { 6743 ensureAllNetworkRequestsHaveType(r); 6744 mRequests = initializeRequests(r); 6745 mNetworkRequestForCallback = requestForCallback; 6746 mPendingIntent = pi; 6747 mMessenger = null; 6748 mBinder = null; 6749 mPid = getCallingPid(); 6750 mUid = mDeps.getCallingUid(); 6751 mAsUid = asUid; 6752 mPerUidCounter = getRequestCounter(this); 6753 mPerUidCounter.incrementCountOrThrow(mUid); 6754 /** 6755 * Location sensitive data not included in pending intent. Only included in 6756 * {@link NetworkCallback}. 6757 */ 6758 mCallbackFlags = NetworkCallback.FLAG_NONE; 6759 mCallingAttributionTag = callingAttributionTag; 6760 mPreferenceOrder = preferenceOrder; 6761 } 6762 6763 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m, 6764 @Nullable final IBinder binder, 6765 @NetworkCallback.Flag int callbackFlags, 6766 @Nullable String callingAttributionTag) { 6767 this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags, 6768 callingAttributionTag); 6769 } 6770 6771 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 6772 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m, 6773 @Nullable final IBinder binder, 6774 @NetworkCallback.Flag int callbackFlags, 6775 @Nullable String callingAttributionTag) { 6776 super(); 6777 ensureAllNetworkRequestsHaveType(r); 6778 mRequests = initializeRequests(r); 6779 mNetworkRequestForCallback = requestForCallback; 6780 mMessenger = m; 6781 mBinder = binder; 6782 mPid = getCallingPid(); 6783 mUid = mDeps.getCallingUid(); 6784 mAsUid = asUid; 6785 mPendingIntent = null; 6786 mPerUidCounter = getRequestCounter(this); 6787 mPerUidCounter.incrementCountOrThrow(mUid); 6788 mCallbackFlags = callbackFlags; 6789 mCallingAttributionTag = callingAttributionTag; 6790 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 6791 linkDeathRecipient(); 6792 } 6793 6794 NetworkRequestInfo(@NonNull final NetworkRequestInfo nri, 6795 @NonNull final List<NetworkRequest> r) { 6796 super(); 6797 ensureAllNetworkRequestsHaveType(r); 6798 mRequests = initializeRequests(r); 6799 mNetworkRequestForCallback = nri.getNetworkRequestForCallback(); 6800 final NetworkAgentInfo satisfier = nri.getSatisfier(); 6801 if (null != satisfier) { 6802 // If the old NRI was satisfied by an NAI, then it may have had an active request. 6803 // The active request is necessary to figure out what callbacks to send, in 6804 // particular when a network updates its capabilities. 6805 // As this code creates a new NRI with a new set of requests, figure out which of 6806 // the list of requests should be the active request. It is always the first 6807 // request of the list that can be satisfied by the satisfier since the order of 6808 // requests is a priority order. 6809 // Note even in the presence of a satisfier there may not be an active request, 6810 // when the satisfier is the no-service network. 6811 NetworkRequest activeRequest = null; 6812 for (final NetworkRequest candidate : r) { 6813 if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) { 6814 activeRequest = candidate; 6815 break; 6816 } 6817 } 6818 setSatisfier(satisfier, activeRequest); 6819 } 6820 mMessenger = nri.mMessenger; 6821 mBinder = nri.mBinder; 6822 mPid = nri.mPid; 6823 mUid = nri.mUid; 6824 mAsUid = nri.mAsUid; 6825 mPendingIntent = nri.mPendingIntent; 6826 mPerUidCounter = nri.mPerUidCounter; 6827 mPerUidCounter.incrementCountOrThrow(mUid); 6828 mCallbackFlags = nri.mCallbackFlags; 6829 mCallingAttributionTag = nri.mCallingAttributionTag; 6830 mPreferenceOrder = PREFERENCE_ORDER_INVALID; 6831 linkDeathRecipient(); 6832 } 6833 6834 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) { 6835 this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID); 6836 } 6837 6838 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r, 6839 final int preferenceOrder) { 6840 this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */, 6841 preferenceOrder); 6842 } 6843 6844 // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer 6845 // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning 6846 // false. 6847 boolean isBeingSatisfied() { 6848 return (null != mSatisfier && null != mActiveRequest); 6849 } 6850 6851 boolean isMultilayerRequest() { 6852 return mRequests.size() > 1; 6853 } 6854 6855 private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) { 6856 // Creating a defensive copy to prevent the sender from modifying the list being 6857 // reflected in the return value of this method. 6858 final List<NetworkRequest> tempRequests = new ArrayList<>(r); 6859 return Collections.unmodifiableList(tempRequests); 6860 } 6861 6862 void linkDeathRecipient() { 6863 if (null != mBinder) { 6864 try { 6865 mBinder.linkToDeath(this, 0); 6866 } catch (RemoteException e) { 6867 binderDied(); 6868 } 6869 } 6870 } 6871 6872 void unlinkDeathRecipient() { 6873 if (null != mBinder) { 6874 try { 6875 mBinder.unlinkToDeath(this, 0); 6876 } catch (NoSuchElementException e) { 6877 // Temporary workaround for b/194394697 pending analysis of additional logs 6878 Log.wtf(TAG, "unlinkToDeath for already unlinked NRI " + this); 6879 } 6880 } 6881 } 6882 6883 boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) { 6884 // Compare two preference orders. 6885 return mPreferenceOrder < target.mPreferenceOrder; 6886 } 6887 6888 int getPreferenceOrderForNetd() { 6889 if (mPreferenceOrder >= PREFERENCE_ORDER_NONE 6890 && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) { 6891 return mPreferenceOrder; 6892 } 6893 return PREFERENCE_ORDER_NONE; 6894 } 6895 6896 @Override 6897 public void binderDied() { 6898 // As an immutable collection, mRequests cannot change by the time the 6899 // lambda is evaluated on the handler thread so calling .get() from a binder thread 6900 // is acceptable. Use handleReleaseNetworkRequest and not directly 6901 // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case 6902 // the app already unregistered the request. 6903 mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0), 6904 mUid, false /* callOnUnavailable */)); 6905 } 6906 6907 @Override 6908 public String toString() { 6909 final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid; 6910 return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: " 6911 + (mActiveRequest == null ? null : mActiveRequest.requestId) 6912 + " callbackRequest: " 6913 + mNetworkRequestForCallback.requestId 6914 + " " + mRequests 6915 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent) 6916 + " callback flags: " + mCallbackFlags 6917 + " order: " + mPreferenceOrder; 6918 } 6919 } 6920 6921 // Keep backward compatibility since the ServiceSpecificException is used by 6922 // the API surface, see {@link ConnectivityManager#convertServiceException}. 6923 public static class RequestInfoPerUidCounter extends PerUidCounter { 6924 RequestInfoPerUidCounter(int maxCountPerUid) { 6925 super(maxCountPerUid); 6926 } 6927 6928 @Override 6929 public synchronized void incrementCountOrThrow(int uid) { 6930 try { 6931 super.incrementCountOrThrow(uid); 6932 } catch (IllegalStateException e) { 6933 throw new ServiceSpecificException( 6934 ConnectivityManager.Errors.TOO_MANY_REQUESTS, 6935 "Uid " + uid + " exceeded its allotted requests limit"); 6936 } 6937 } 6938 6939 @Override 6940 public synchronized void decrementCountOrThrow(int uid) { 6941 throw new UnsupportedOperationException("Use decrementCount instead."); 6942 } 6943 6944 public synchronized void decrementCount(int uid) { 6945 try { 6946 super.decrementCountOrThrow(uid); 6947 } catch (IllegalStateException e) { 6948 logwtf("Exception when decrement per uid request count: ", e); 6949 } 6950 } 6951 } 6952 6953 // This checks that the passed capabilities either do not request a 6954 // specific SSID/SignalStrength, or the calling app has permission to do so. 6955 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 6956 int callerPid, int callerUid, String callerPackageName) { 6957 if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) { 6958 throw new SecurityException("Insufficient permissions to request a specific SSID"); 6959 } 6960 6961 if (nc.hasSignalStrength() 6962 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { 6963 throw new SecurityException( 6964 "Insufficient permissions to request a specific signal strength"); 6965 } 6966 mAppOpsManager.checkPackage(callerUid, callerPackageName); 6967 6968 if (!nc.getSubscriptionIds().isEmpty()) { 6969 enforceNetworkFactoryPermission(); 6970 } 6971 } 6972 6973 private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { 6974 final SortedSet<Integer> thresholds = new TreeSet<>(); 6975 synchronized (nai) { 6976 // mNetworkRequests may contain the same value multiple times in case of 6977 // multilayer requests. It won't matter in this case because the thresholds 6978 // will then be the same and be deduplicated as they enter the `thresholds` set. 6979 // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like. 6980 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 6981 for (final NetworkRequest req : nri.mRequests) { 6982 if (req.networkCapabilities.hasSignalStrength() 6983 && nai.satisfiesImmutableCapabilitiesOf(req)) { 6984 thresholds.add(req.networkCapabilities.getSignalStrength()); 6985 } 6986 } 6987 } 6988 } 6989 return CollectionUtils.toIntArray(new ArrayList<>(thresholds)); 6990 } 6991 6992 private void updateSignalStrengthThresholds( 6993 NetworkAgentInfo nai, String reason, NetworkRequest request) { 6994 final int[] thresholdsArray = getSignalStrengthThresholds(nai); 6995 6996 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 6997 String detail; 6998 if (request != null && request.networkCapabilities.hasSignalStrength()) { 6999 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 7000 } else { 7001 detail = reason; 7002 } 7003 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 7004 detail, Arrays.toString(thresholdsArray), nai.toShortString())); 7005 } 7006 7007 nai.onSignalStrengthThresholdsUpdated(thresholdsArray); 7008 } 7009 7010 private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 7011 if (nc == null) { 7012 return; 7013 } 7014 NetworkSpecifier ns = nc.getNetworkSpecifier(); 7015 if (ns == null) { 7016 return; 7017 } 7018 if (ns instanceof MatchAllNetworkSpecifier) { 7019 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); 7020 } 7021 } 7022 7023 private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) { 7024 ensureValidNetworkSpecifier(nc); 7025 if (nc.isPrivateDnsBroken()) { 7026 throw new IllegalArgumentException("Can't request broken private DNS"); 7027 } 7028 if (nc.hasAllowedUids()) { 7029 throw new IllegalArgumentException("Can't request access UIDs"); 7030 } 7031 } 7032 7033 private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) { 7034 ensureListenableCapabilities(nc); 7035 final String badCapability = nc.describeFirstNonRequestableCapability(); 7036 if (badCapability != null) { 7037 throw new IllegalArgumentException("Cannot request network with " + badCapability); 7038 } 7039 } 7040 7041 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed. 7042 @TargetApi(Build.VERSION_CODES.S) 7043 private boolean isTargetSdkAtleast(int version, int callingUid, 7044 @NonNull String callingPackageName) { 7045 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 7046 final PackageManager pm = 7047 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager(); 7048 try { 7049 final int callingVersion = pm.getTargetSdkVersion(callingPackageName); 7050 if (callingVersion < version) return false; 7051 } catch (PackageManager.NameNotFoundException e) { } 7052 return true; 7053 } 7054 7055 @Override 7056 public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities, 7057 int reqTypeInt, Messenger messenger, int timeoutMs, final IBinder binder, 7058 int legacyType, int callbackFlags, @NonNull String callingPackageName, 7059 @Nullable String callingAttributionTag) { 7060 if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) { 7061 if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(), 7062 callingPackageName)) { 7063 throw new SecurityException("Insufficient permissions to specify legacy type"); 7064 } 7065 } 7066 final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities; 7067 final int callingUid = mDeps.getCallingUid(); 7068 // Privileged callers can track the default network of another UID by passing in a UID. 7069 if (asUid != Process.INVALID_UID) { 7070 enforceSettingsPermission(); 7071 } else { 7072 asUid = callingUid; 7073 } 7074 final NetworkRequest.Type reqType; 7075 try { 7076 reqType = NetworkRequest.Type.values()[reqTypeInt]; 7077 } catch (ArrayIndexOutOfBoundsException e) { 7078 throw new IllegalArgumentException("Unsupported request type " + reqTypeInt); 7079 } 7080 switch (reqType) { 7081 case TRACK_DEFAULT: 7082 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities} 7083 // is unused and will be replaced by ones appropriate for the UID (usually, the 7084 // calling app). This allows callers to keep track of the default network. 7085 networkCapabilities = copyDefaultNetworkCapabilitiesForUid( 7086 defaultNc, asUid, callingUid, callingPackageName); 7087 enforceAccessPermission(); 7088 break; 7089 case TRACK_SYSTEM_DEFAULT: 7090 enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission(); 7091 networkCapabilities = new NetworkCapabilities(defaultNc); 7092 break; 7093 case BACKGROUND_REQUEST: 7094 enforceNetworkStackOrSettingsPermission(); 7095 // Fall-through since other checks are the same with normal requests. 7096 case REQUEST: 7097 networkCapabilities = new NetworkCapabilities(networkCapabilities); 7098 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 7099 callingAttributionTag, callingUid); 7100 // TODO: this is incorrect. We mark the request as metered or not depending on 7101 // the state of the app when the request is filed, but we never change the 7102 // request if the app changes network state. http://b/29964605 7103 enforceMeteredApnPolicy(networkCapabilities); 7104 break; 7105 case LISTEN_FOR_BEST: 7106 enforceAccessPermission(); 7107 networkCapabilities = new NetworkCapabilities(networkCapabilities); 7108 break; 7109 default: 7110 throw new IllegalArgumentException("Unsupported request type " + reqType); 7111 } 7112 ensureRequestableCapabilities(networkCapabilities); 7113 ensureSufficientPermissionsForRequest(networkCapabilities, 7114 Binder.getCallingPid(), callingUid, callingPackageName); 7115 7116 // Enforce FOREGROUND if the caller does not have permission to use background network. 7117 if (reqType == LISTEN_FOR_BEST) { 7118 restrictBackgroundRequestForCaller(networkCapabilities); 7119 } 7120 7121 // Set the UID range for this request to the single UID of the requester, unless the 7122 // requester has the permission to specify other UIDs. 7123 // This will overwrite any allowed UIDs in the requested capabilities. Though there 7124 // are no visible methods to set the UIDs, an app could use reflection to try and get 7125 // networks for other apps so it's essential that the UIDs are overwritten. 7126 // Also set the requester UID and package name in the request. 7127 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 7128 callingUid, callingPackageName); 7129 7130 if (timeoutMs < 0) { 7131 throw new IllegalArgumentException("Bad timeout specified"); 7132 } 7133 7134 final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 7135 nextNetworkRequestId(), reqType); 7136 final NetworkRequestInfo nri = getNriToRegister( 7137 asUid, networkRequest, messenger, binder, callbackFlags, 7138 callingAttributionTag); 7139 if (DBG) log("requestNetwork for " + nri); 7140 7141 // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were 7142 // copied from the default request above. (This is necessary to ensure, for example, that 7143 // the callback does not leak sensitive information to unprivileged apps.) Check that the 7144 // changes don't alter request matching. 7145 if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT && 7146 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) { 7147 throw new IllegalStateException( 7148 "TRACK_SYSTEM_DEFAULT capabilities don't match default request: " 7149 + networkCapabilities + " vs. " + defaultNc); 7150 } 7151 7152 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); 7153 if (timeoutMs > 0) { 7154 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 7155 nri), timeoutMs); 7156 } 7157 return networkRequest; 7158 } 7159 7160 /** 7161 * Return the nri to be used when registering a network request. Specifically, this is used with 7162 * requests registered to track the default request. If there is currently a per-app default 7163 * tracking the app requestor, then we need to create a version of this nri that mirrors that of 7164 * the tracking per-app default so that callbacks are sent to the app requestor appropriately. 7165 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 7166 * when a privileged caller is tracking the default network for another uid. 7167 * @param nr the network request for the nri. 7168 * @param msgr the messenger for the nri. 7169 * @param binder the binder for the nri. 7170 * @param callingAttributionTag the calling attribution tag for the nri. 7171 * @return the nri to register. 7172 */ 7173 private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr, 7174 @Nullable final Messenger msgr, @Nullable final IBinder binder, 7175 @NetworkCallback.Flag int callbackFlags, 7176 @Nullable String callingAttributionTag) { 7177 final List<NetworkRequest> requests; 7178 if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) { 7179 requests = copyDefaultNetworkRequestsForUid( 7180 asUid, nr.getRequestorUid(), nr.getRequestorPackageName()); 7181 } else { 7182 requests = Collections.singletonList(nr); 7183 } 7184 return new NetworkRequestInfo( 7185 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag); 7186 } 7187 7188 private boolean shouldCheckCapabilitiesDeclaration( 7189 @NonNull final NetworkCapabilities networkCapabilities, final int callingUid, 7190 @NonNull final String callingPackageName) { 7191 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 7192 // Only run the check if the change is enabled. 7193 if (!mDeps.isChangeEnabled( 7194 ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION, 7195 callingPackageName, user)) { 7196 return false; 7197 } 7198 7199 return networkCapabilities.hasCapability( 7200 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 7201 || networkCapabilities.hasCapability( 7202 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY); 7203 } 7204 7205 private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName, 7206 @NonNull final NetworkCapabilities networkCapabilities) { 7207 // This check is added to fix the linter error for "current min is 30", which is not going 7208 // to happen because Connectivity service always run in S+. 7209 if (!mDeps.isAtLeastS()) { 7210 Log.wtf(TAG, "Connectivity service should always run in at least SDK S"); 7211 return; 7212 } 7213 ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities; 7214 final long ident = Binder.clearCallingIdentity(); 7215 try { 7216 synchronized (mSelfCertifiedCapabilityCache) { 7217 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get( 7218 callerPackageName); 7219 if (applicationNetworkCapabilities == null) { 7220 final PackageManager packageManager = mContext.getPackageManager(); 7221 final PackageManager.Property networkSliceProperty = packageManager.getProperty( 7222 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 7223 callerPackageName 7224 ); 7225 final XmlResourceParser parser = packageManager 7226 .getResourcesForApplication(callerPackageName) 7227 .getXml(networkSliceProperty.getResourceId()); 7228 applicationNetworkCapabilities = 7229 ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser); 7230 mSelfCertifiedCapabilityCache.put(callerPackageName, 7231 applicationNetworkCapabilities); 7232 } 7233 7234 } 7235 } catch (PackageManager.NameNotFoundException ne) { 7236 throw new SecurityException( 7237 "Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES 7238 + " property"); 7239 } catch (XmlPullParserException | IOException | InvalidTagException e) { 7240 throw new SecurityException(e.getMessage()); 7241 } finally { 7242 Binder.restoreCallingIdentity(ident); 7243 } 7244 7245 applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared( 7246 networkCapabilities); 7247 } 7248 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, 7249 String callingPackageName, String callingAttributionTag, final int callingUid) { 7250 if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid, 7251 callingPackageName)) { 7252 enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities); 7253 } 7254 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { 7255 // For T+ devices, callers with carrier privilege could request with CBS capabilities. 7256 if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS) 7257 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)) { 7258 return; 7259 } 7260 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */); 7261 } else { 7262 enforceChangePermission(callingPackageName, callingAttributionTag); 7263 } 7264 } 7265 7266 @Override 7267 public boolean requestBandwidthUpdate(Network network) { 7268 enforceAccessPermission(); 7269 NetworkAgentInfo nai = null; 7270 if (network == null) { 7271 return false; 7272 } 7273 synchronized (mNetworkForNetId) { 7274 nai = mNetworkForNetId.get(network.getNetId()); 7275 } 7276 if (nai != null) { 7277 nai.onBandwidthUpdateRequested(); 7278 synchronized (mBandwidthRequests) { 7279 final int uid = mDeps.getCallingUid(); 7280 Integer uidReqs = mBandwidthRequests.get(uid); 7281 if (uidReqs == null) { 7282 uidReqs = 0; 7283 } 7284 mBandwidthRequests.put(uid, ++uidReqs); 7285 } 7286 return true; 7287 } 7288 return false; 7289 } 7290 7291 private boolean isSystem(int uid) { 7292 return uid < Process.FIRST_APPLICATION_UID; 7293 } 7294 7295 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 7296 final int uid = mDeps.getCallingUid(); 7297 if (isSystem(uid)) { 7298 // Exemption for system uid. 7299 return; 7300 } 7301 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 7302 // Policy already enforced. 7303 return; 7304 } 7305 final long ident = Binder.clearCallingIdentity(); 7306 try { 7307 if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) { 7308 // If UID is restricted, don't allow them to bring up metered APNs. 7309 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 7310 } 7311 } finally { 7312 Binder.restoreCallingIdentity(ident); 7313 } 7314 } 7315 7316 @Override 7317 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 7318 PendingIntent operation, @NonNull String callingPackageName, 7319 @Nullable String callingAttributionTag) { 7320 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 7321 final int callingUid = mDeps.getCallingUid(); 7322 networkCapabilities = new NetworkCapabilities(networkCapabilities); 7323 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, 7324 callingAttributionTag, callingUid); 7325 enforceMeteredApnPolicy(networkCapabilities); 7326 ensureRequestableCapabilities(networkCapabilities); 7327 ensureSufficientPermissionsForRequest(networkCapabilities, 7328 Binder.getCallingPid(), callingUid, callingPackageName); 7329 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, 7330 callingUid, callingPackageName); 7331 7332 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 7333 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 7334 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 7335 callingAttributionTag); 7336 if (DBG) log("pendingRequest for " + nri); 7337 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, 7338 nri)); 7339 return networkRequest; 7340 } 7341 7342 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 7343 mHandler.sendMessageDelayed( 7344 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 7345 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 7346 } 7347 7348 @Override 7349 public void releasePendingNetworkRequest(PendingIntent operation) { 7350 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 7351 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 7352 mDeps.getCallingUid(), 0, operation)); 7353 } 7354 7355 // In order to implement the compatibility measure for pre-M apps that call 7356 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 7357 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 7358 // This ensures it has permission to do so. 7359 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 7360 if (nc == null) { 7361 return false; 7362 } 7363 int[] transportTypes = nc.getTransportTypes(); 7364 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 7365 return false; 7366 } 7367 try { 7368 mContext.enforceCallingOrSelfPermission( 7369 android.Manifest.permission.ACCESS_WIFI_STATE, 7370 "ConnectivityService"); 7371 } catch (SecurityException e) { 7372 return false; 7373 } 7374 return true; 7375 } 7376 7377 @Override 7378 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 7379 Messenger messenger, IBinder binder, 7380 @NetworkCallback.Flag int callbackFlags, 7381 @NonNull String callingPackageName, @NonNull String callingAttributionTag) { 7382 final int callingUid = mDeps.getCallingUid(); 7383 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 7384 enforceAccessPermission(); 7385 } 7386 7387 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 7388 ensureSufficientPermissionsForRequest(networkCapabilities, 7389 Binder.getCallingPid(), callingUid, callingPackageName); 7390 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 7391 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 7392 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 7393 // onLost and onAvailable callbacks when networks move in and out of the background. 7394 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 7395 // can't request networks. 7396 restrictBackgroundRequestForCaller(nc); 7397 ensureListenableCapabilities(nc); 7398 7399 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 7400 NetworkRequest.Type.LISTEN); 7401 NetworkRequestInfo nri = 7402 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags, 7403 callingAttributionTag); 7404 if (VDBG) log("listenForNetwork for " + nri); 7405 7406 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 7407 return networkRequest; 7408 } 7409 7410 @Override 7411 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 7412 PendingIntent operation, @NonNull String callingPackageName, 7413 @Nullable String callingAttributionTag) { 7414 Objects.requireNonNull(operation, "PendingIntent cannot be null."); 7415 final int callingUid = mDeps.getCallingUid(); 7416 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 7417 enforceAccessPermission(); 7418 } 7419 ensureListenableCapabilities(networkCapabilities); 7420 ensureSufficientPermissionsForRequest(networkCapabilities, 7421 Binder.getCallingPid(), callingUid, callingPackageName); 7422 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 7423 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 7424 7425 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 7426 NetworkRequest.Type.LISTEN); 7427 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation, 7428 callingAttributionTag); 7429 if (VDBG) log("pendingListenForNetwork for " + nri); 7430 7431 mHandler.sendMessage(mHandler.obtainMessage( 7432 EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri)); 7433 } 7434 7435 /** Returns the next Network provider ID. */ 7436 public final int nextNetworkProviderId() { 7437 return mNextNetworkProviderId.getAndIncrement(); 7438 } 7439 7440 @Override 7441 public void releaseNetworkRequest(NetworkRequest networkRequest) { 7442 ensureNetworkRequestHasType(networkRequest); 7443 mHandler.sendMessage(mHandler.obtainMessage( 7444 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest)); 7445 } 7446 7447 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { 7448 if (mNetworkProviderInfos.containsKey(npi.messenger)) { 7449 // Avoid creating duplicates. even if an app makes a direct AIDL call. 7450 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, 7451 // as that will throw if a duplicate provider is registered. 7452 loge("Attempt to register existing NetworkProviderInfo " 7453 + mNetworkProviderInfos.get(npi.messenger).name); 7454 return; 7455 } 7456 7457 if (DBG) log("Got NetworkProvider Messenger for " + npi.name); 7458 mNetworkProviderInfos.put(npi.messenger, npi); 7459 npi.connect(mContext, mTrackerHandler); 7460 } 7461 7462 @Override 7463 public int registerNetworkProvider(Messenger messenger, String name) { 7464 enforceNetworkFactoryOrSettingsPermission(); 7465 Objects.requireNonNull(messenger, "messenger must be non-null"); 7466 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, 7467 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); 7468 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); 7469 return npi.providerId; 7470 } 7471 7472 @Override 7473 public void unregisterNetworkProvider(Messenger messenger) { 7474 enforceNetworkFactoryOrSettingsPermission(); 7475 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); 7476 } 7477 7478 @Override 7479 public void offerNetwork(final int providerId, 7480 @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, 7481 @NonNull final INetworkOfferCallback callback) { 7482 Objects.requireNonNull(score); 7483 Objects.requireNonNull(caps); 7484 Objects.requireNonNull(callback); 7485 final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 7486 final NetworkOffer offer = new NetworkOffer( 7487 FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi), 7488 caps, callback, providerId); 7489 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer)); 7490 } 7491 7492 private void updateOfferScore(final NetworkOffer offer) { 7493 final boolean yieldToBadWiFi = 7494 offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi(); 7495 final NetworkOffer newOffer = new NetworkOffer( 7496 offer.score.withYieldToBadWiFi(yieldToBadWiFi), 7497 offer.caps, offer.callback, offer.providerId); 7498 if (offer.equals(newOffer)) return; 7499 handleRegisterNetworkOffer(newOffer); 7500 } 7501 7502 @Override 7503 public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { 7504 Objects.requireNonNull(callback); 7505 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback)); 7506 } 7507 7508 private void handleUnregisterNetworkProvider(Messenger messenger) { 7509 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); 7510 if (npi == null) { 7511 loge("Failed to find Messenger in unregisterNetworkProvider"); 7512 return; 7513 } 7514 // Unregister all the offers from this provider 7515 final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>(); 7516 for (final NetworkOfferInfo noi : mNetworkOffers) { 7517 if (noi.offer.providerId == npi.providerId) { 7518 // Can't call handleUnregisterNetworkOffer here because iteration is in progress 7519 toRemove.add(noi); 7520 } 7521 } 7522 for (final NetworkOfferInfo noi : toRemove) { 7523 handleUnregisterNetworkOffer(noi); 7524 } 7525 if (DBG) log("unregisterNetworkProvider for " + npi.name); 7526 } 7527 7528 @Override 7529 public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) { 7530 if (request.hasTransport(TRANSPORT_TEST)) { 7531 enforceNetworkFactoryOrTestNetworksPermission(); 7532 } else { 7533 enforceNetworkFactoryPermission(); 7534 } 7535 final NetworkRequestInfo nri = mNetworkRequests.get(request); 7536 if (nri != null) { 7537 // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests. 7538 ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable"); 7539 mHandler.post(() -> handleReleaseNetworkRequest( 7540 nri.mRequests.get(0), mDeps.getCallingUid(), true)); 7541 } 7542 } 7543 7544 // NOTE: Accessed on multiple threads, must be synchronized on itself. 7545 @GuardedBy("mNetworkForNetId") 7546 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); 7547 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 7548 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so 7549 // there may not be a strict 1:1 correlation between the two. 7550 private final NetIdManager mNetIdManager; 7551 7552 // Tracks all NetworkAgents that are currently registered. 7553 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 7554 private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>(); 7555 7556 // UID ranges for users that are currently blocked by VPNs. 7557 // This array is accessed and iterated on multiple threads without holding locks, so its 7558 // contents must never be mutated. When the ranges change, the array is replaced with a new one 7559 // (on the handler thread). 7560 private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>(); 7561 7562 // Must only be accessed on the handler thread 7563 @NonNull 7564 private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>(); 7565 7566 @GuardedBy("mBlockedAppUids") 7567 private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 7568 7569 // Current OEM network preferences. This object must only be written to on the handler thread. 7570 // Since it is immutable and always non-null, other threads may read it if they only care 7571 // about seeing a consistent object but not that it is current. 7572 @NonNull 7573 private OemNetworkPreferences mOemNetworkPreferences = 7574 new OemNetworkPreferences.Builder().build(); 7575 // Current per-profile network preferences. This object follows the same threading rules as 7576 // the OEM network preferences above. 7577 @NonNull 7578 private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> 7579 mProfileNetworkPreferences = new NetworkPreferenceList<>(); 7580 7581 // Current VPN network preferences. This object follows the same threading rules as the OEM 7582 // network preferences above. 7583 @NonNull 7584 private NetworkPreferenceList<String, VpnNetworkPreferenceInfo> 7585 mVpnNetworkPreferences = new NetworkPreferenceList<>(); 7586 7587 // A set of UIDs that should use mobile data preferentially if available. This object follows 7588 // the same threading rules as the OEM network preferences above. 7589 @NonNull 7590 private Set<Integer> mMobileDataPreferredUids = new ArraySet<>(); 7591 7592 // OemNetworkPreferences activity String log entries. 7593 private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20; 7594 @NonNull 7595 private final LocalLog mOemNetworkPreferencesLogs = 7596 new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS); 7597 7598 /** 7599 * Determine whether a given package has a mapping in the current OemNetworkPreferences. 7600 * @param packageName the package name to check existence of a mapping for. 7601 * @return true if a mapping exists, false otherwise 7602 */ 7603 private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) { 7604 return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName); 7605 } 7606 7607 // The always-on request for an Internet-capable network that apps without a specific default 7608 // fall back to. 7609 @VisibleForTesting 7610 @NonNull 7611 final NetworkRequestInfo mDefaultRequest; 7612 // Collection of NetworkRequestInfo's used for default networks. 7613 @VisibleForTesting 7614 @NonNull 7615 final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>(); 7616 7617 private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) { 7618 return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri); 7619 } 7620 7621 /** 7622 * Return the default network request currently tracking the given uid. 7623 * @param uid the uid to check. 7624 * @return the NetworkRequestInfo tracking the given uid. 7625 */ 7626 @NonNull 7627 private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) { 7628 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 7629 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 7630 // Checking the first request is sufficient as only multilayer requests will have more 7631 // than one request and for multilayer, all requests will track the same uids. 7632 if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) { 7633 // Find out the highest priority request. 7634 if (nri.hasHigherOrderThan(highestPriorityNri)) { 7635 highestPriorityNri = nri; 7636 } 7637 } 7638 } 7639 return highestPriorityNri; 7640 } 7641 7642 /** 7643 * Get a copy of the network requests of the default request that is currently tracking the 7644 * given uid. 7645 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 7646 * when a privileged caller is tracking the default network for another uid. 7647 * @param requestorUid the uid to check the default for. 7648 * @param requestorPackageName the requestor's package name. 7649 * @return a copy of the default's NetworkRequest that is tracking the given uid. 7650 */ 7651 @NonNull 7652 private List<NetworkRequest> copyDefaultNetworkRequestsForUid( 7653 final int asUid, final int requestorUid, @NonNull final String requestorPackageName) { 7654 return copyNetworkRequestsForUid( 7655 getDefaultRequestTrackingUid(asUid).mRequests, 7656 asUid, requestorUid, requestorPackageName); 7657 } 7658 7659 /** 7660 * Copy the given nri's NetworkRequest collection. 7661 * @param requestsToCopy the NetworkRequest collection to be copied. 7662 * @param asUid the uid on behalf of which to file the request. Different from requestorUid 7663 * when a privileged caller is tracking the default network for another uid. 7664 * @param requestorUid the uid to set on the copied collection. 7665 * @param requestorPackageName the package name to set on the copied collection. 7666 * @return the copied NetworkRequest collection. 7667 */ 7668 @NonNull 7669 private List<NetworkRequest> copyNetworkRequestsForUid( 7670 @NonNull final List<NetworkRequest> requestsToCopy, final int asUid, 7671 final int requestorUid, @NonNull final String requestorPackageName) { 7672 final List<NetworkRequest> requests = new ArrayList<>(); 7673 for (final NetworkRequest nr : requestsToCopy) { 7674 requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid( 7675 nr.networkCapabilities, asUid, requestorUid, requestorPackageName), 7676 nr.legacyType, nextNetworkRequestId(), nr.type)); 7677 } 7678 return requests; 7679 } 7680 7681 @NonNull 7682 private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid( 7683 @NonNull final NetworkCapabilities netCapToCopy, final int asUid, 7684 final int requestorUid, @NonNull final String requestorPackageName) { 7685 // These capabilities are for a TRACK_DEFAULT callback, so: 7686 // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between 7687 // mDefaultRequest and a per-UID default request. 7688 // TODO: stop depending on the fact that these two unrelated things happen to be the same 7689 // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will 7690 // not do this in the case of a privileged application. 7691 final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy); 7692 netCap.removeCapability(NET_CAPABILITY_NOT_VPN); 7693 netCap.setSingleUid(asUid); 7694 restrictRequestUidsForCallerAndSetRequestorInfo( 7695 netCap, requestorUid, requestorPackageName); 7696 return netCap; 7697 } 7698 7699 /** 7700 * Get the nri that is currently being tracked for callbacks by per-app defaults. 7701 * @param nr the network request to check for equality against. 7702 * @return the nri if one exists, null otherwise. 7703 */ 7704 @Nullable 7705 private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) { 7706 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 7707 if (nri.getNetworkRequestForCallback().equals(nr)) { 7708 return nri; 7709 } 7710 } 7711 return null; 7712 } 7713 7714 /** 7715 * Check if an nri is currently being managed by per-app default networking. 7716 * @param nri the nri to check. 7717 * @return true if this nri is currently being managed by per-app default networking. 7718 */ 7719 private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) { 7720 // nri.mRequests.get(0) is only different from the original request filed in 7721 // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default 7722 // functionality therefore if these two don't match, it means this particular nri is 7723 // currently being managed by a per-app default. 7724 return nri.getNetworkRequestForCallback() != nri.mRequests.get(0); 7725 } 7726 7727 /** 7728 * Determine if an nri is a managed default request that disallows default networking. 7729 * @param nri the request to evaluate 7730 * @return true if device-default networking is disallowed 7731 */ 7732 private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) { 7733 // Check if this nri is a managed default that supports the default network at its 7734 // lowest priority request. 7735 final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0); 7736 final NetworkCapabilities lowestPriorityNetCap = 7737 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities; 7738 return isPerAppDefaultRequest(nri) 7739 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities( 7740 lowestPriorityNetCap)); 7741 } 7742 7743 // Request used to optionally keep mobile data active even when higher 7744 // priority networks like Wi-Fi are active. 7745 private final NetworkRequest mDefaultMobileDataRequest; 7746 7747 // Request used to optionally keep wifi data active even when higher 7748 // priority networks like ethernet are active. 7749 private final NetworkRequest mDefaultWifiRequest; 7750 7751 // Request used to optionally keep vehicle internal network always active 7752 private final NetworkRequest mDefaultVehicleRequest; 7753 7754 // Sentinel NAI used to direct apps with default networks that should have no connectivity to a 7755 // network with no service. This NAI should never be matched against, nor should any public API 7756 // ever return the associated network. For this reason, this NAI is not in the list of available 7757 // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device 7758 // default requests that don't support using the device default network which will ultimately 7759 // allow ConnectivityService to use this no-service network when calling makeDefaultForApps(). 7760 @VisibleForTesting 7761 final NetworkAgentInfo mNoServiceNetwork; 7762 7763 // The NetworkAgentInfo currently satisfying the default request, if any. 7764 private NetworkAgentInfo getDefaultNetwork() { 7765 return mDefaultRequest.mSatisfier; 7766 } 7767 7768 private NetworkAgentInfo getDefaultNetworkForUid(final int uid) { 7769 NetworkRequestInfo highestPriorityNri = mDefaultRequest; 7770 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 7771 // Currently, all network requests will have the same uids therefore checking the first 7772 // one is sufficient. If/when uids are tracked at the nri level, this can change. 7773 final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges(); 7774 if (null == uids) { 7775 continue; 7776 } 7777 for (final UidRange range : uids) { 7778 if (range.contains(uid)) { 7779 if (nri.hasHigherOrderThan(highestPriorityNri)) { 7780 highestPriorityNri = nri; 7781 } 7782 } 7783 } 7784 } 7785 return highestPriorityNri.getSatisfier(); 7786 } 7787 7788 @Nullable 7789 private Network getNetwork(@Nullable NetworkAgentInfo nai) { 7790 return nai != null ? nai.network : null; 7791 } 7792 7793 private void ensureRunningOnConnectivityServiceThread() { 7794 if (mHandler.getLooper().getThread() != Thread.currentThread()) { 7795 throw new IllegalStateException( 7796 "Not running on ConnectivityService thread: " 7797 + Thread.currentThread().getName()); 7798 } 7799 } 7800 7801 @VisibleForTesting 7802 protected boolean isDefaultNetwork(NetworkAgentInfo nai) { 7803 return nai == getDefaultNetwork(); 7804 } 7805 7806 /** 7807 * Register a new agent with ConnectivityService to handle a network. 7808 * 7809 * @param na a reference for ConnectivityService to contact the agent asynchronously. 7810 * @param networkInfo the initial info associated with this network. It can be updated later : 7811 * see {@link #updateNetworkInfo}. 7812 * @param linkProperties the initial link properties of this network. They can be updated 7813 * later : see {@link #updateLinkProperties}. 7814 * @param networkCapabilities the initial capabilites of this network. They can be updated 7815 * later : see {@link #updateCapabilities}. 7816 * @param initialScore the initial score of the network. See {@link NetworkAgentInfo#getScore}. 7817 * @param networkAgentConfig metadata about the network. This is never updated. 7818 * @param providerId the ID of the provider owning this NetworkAgent. 7819 * @return the network created for this agent. 7820 */ 7821 public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, 7822 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 7823 @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, 7824 int providerId) { 7825 Objects.requireNonNull(networkInfo, "networkInfo must not be null"); 7826 Objects.requireNonNull(linkProperties, "linkProperties must not be null"); 7827 Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); 7828 Objects.requireNonNull(initialScore, "initialScore must not be null"); 7829 Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); 7830 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { 7831 enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS); 7832 } else { 7833 enforceNetworkFactoryPermission(); 7834 } 7835 7836 final int uid = mDeps.getCallingUid(); 7837 final long token = Binder.clearCallingIdentity(); 7838 try { 7839 return registerNetworkAgentInternal(na, networkInfo, linkProperties, 7840 networkCapabilities, initialScore, networkAgentConfig, providerId, uid); 7841 } finally { 7842 Binder.restoreCallingIdentity(token); 7843 } 7844 } 7845 7846 private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, 7847 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 7848 NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, 7849 int uid) { 7850 7851 // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them 7852 // and mutate them at any time. 7853 final NetworkInfo niCopy = new NetworkInfo(networkInfo); 7854 final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities); 7855 final LinkProperties lpCopy = new LinkProperties(linkProperties); 7856 7857 // At this point the capabilities/properties are untrusted and unverified, e.g. checks that 7858 // the capabilities' access UIDs comply with security limitations. They will be sanitized 7859 // as the NAI registration finishes, in handleRegisterNetworkAgent(). This is 7860 // because some of the checks must happen on the handler thread. 7861 final NetworkAgentInfo nai = new NetworkAgentInfo(na, 7862 new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy, 7863 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), 7864 this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs, 7865 mQosCallbackTracker, mDeps); 7866 7867 final String extraInfo = niCopy.getExtraInfo(); 7868 final String name = TextUtils.isEmpty(extraInfo) 7869 ? nai.networkCapabilities.getSsid() : extraInfo; 7870 if (DBG) log("registerNetworkAgent " + nai); 7871 mDeps.getNetworkStack().makeNetworkMonitor( 7872 nai.network, name, new NetworkMonitorCallbacks(nai)); 7873 // NetworkAgentInfo registration will finish when the NetworkMonitor is created. 7874 // If the network disconnects or sends any other event before that, messages are deferred by 7875 // NetworkAgent until nai.connect(), which will be called when finalizing the 7876 // registration. 7877 return nai.network; 7878 } 7879 7880 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { 7881 if (VDBG) log("Network Monitor created for " + nai); 7882 // Store a copy of the declared capabilities. 7883 nai.setDeclaredCapabilities(nai.networkCapabilities); 7884 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said. 7885 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, 7886 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator))); 7887 processLinkPropertiesFromAgent(nai, nai.linkProperties); 7888 7889 nai.onNetworkMonitorCreated(networkMonitor); 7890 7891 mNetworkAgentInfos.add(nai); 7892 synchronized (mNetworkForNetId) { 7893 mNetworkForNetId.put(nai.network.getNetId(), nai); 7894 } 7895 7896 try { 7897 networkMonitor.start(); 7898 } catch (RemoteException e) { 7899 e.rethrowAsRuntimeException(); 7900 } 7901 7902 nai.notifyRegistered(); 7903 NetworkInfo networkInfo = nai.networkInfo; 7904 updateNetworkInfo(nai, networkInfo); 7905 updateVpnUids(nai, null, nai.networkCapabilities); 7906 } 7907 7908 private class NetworkOfferInfo implements IBinder.DeathRecipient { 7909 @NonNull public final NetworkOffer offer; 7910 7911 NetworkOfferInfo(@NonNull final NetworkOffer offer) { 7912 this.offer = offer; 7913 } 7914 7915 @Override 7916 public void binderDied() { 7917 mHandler.post(() -> handleUnregisterNetworkOffer(this)); 7918 } 7919 } 7920 7921 private boolean isNetworkProviderWithIdRegistered(final int providerId) { 7922 for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) { 7923 if (npi.providerId == providerId) return true; 7924 } 7925 return false; 7926 } 7927 7928 /** 7929 * Register or update a network offer. 7930 * @param newOffer The new offer. If the callback member is the same as an existing 7931 * offer, it is an update of that offer. 7932 */ 7933 // TODO : rename this to handleRegisterOrUpdateNetworkOffer 7934 private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) { 7935 ensureRunningOnConnectivityServiceThread(); 7936 if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) { 7937 // This may actually happen if a provider updates its score or registers and then 7938 // immediately unregisters. The offer would still be in the handler queue, but the 7939 // provider would have been removed. 7940 if (DBG) log("Received offer from an unregistered provider"); 7941 return; 7942 } 7943 final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback); 7944 if (null != existingOffer) { 7945 handleUnregisterNetworkOffer(existingOffer); 7946 newOffer.migrateFrom(existingOffer.offer); 7947 if (DBG) { 7948 // handleUnregisterNetworkOffer has already logged the old offer 7949 log("update offer from providerId " + newOffer.providerId + " new : " + newOffer); 7950 } 7951 } else { 7952 if (DBG) { 7953 log("register offer from providerId " + newOffer.providerId + " : " + newOffer); 7954 } 7955 } 7956 final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer); 7957 try { 7958 noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */); 7959 } catch (RemoteException e) { 7960 noi.binderDied(); 7961 return; 7962 } 7963 mNetworkOffers.add(noi); 7964 issueNetworkNeeds(noi); 7965 } 7966 7967 private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) { 7968 ensureRunningOnConnectivityServiceThread(); 7969 if (DBG) { 7970 log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer); 7971 } 7972 7973 // If the provider removes the offer and dies immediately afterwards this 7974 // function may be called twice in a row, but the array will no longer contain 7975 // the offer. 7976 if (!mNetworkOffers.remove(noi)) return; 7977 noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */); 7978 } 7979 7980 @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback( 7981 @NonNull final INetworkOfferCallback callback) { 7982 ensureRunningOnConnectivityServiceThread(); 7983 for (final NetworkOfferInfo noi : mNetworkOffers) { 7984 if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi; 7985 } 7986 return null; 7987 } 7988 7989 /** 7990 * Called when receiving LinkProperties directly from a NetworkAgent. 7991 * Stores into |nai| any data coming from the agent that might also be written to the network's 7992 * LinkProperties by ConnectivityService itself. This ensures that the data provided by the 7993 * agent is not lost when updateLinkProperties is called. 7994 * This method should never alter the agent's LinkProperties, only store data in |nai|. 7995 */ 7996 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { 7997 lp.ensureDirectlyConnectedRoutes(); 7998 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix()); 7999 nai.networkAgentPortalData = lp.getCaptivePortalData(); 8000 } 8001 8002 private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp, 8003 @Nullable LinkProperties oldLp) { 8004 int netId = networkAgent.network.getNetId(); 8005 8006 // The NetworkAgent does not know whether clatd is running on its network or not, or whether 8007 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure 8008 // the LinkProperties for the network are accurate. 8009 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 8010 8011 updateInterfaces(newLp, oldLp, netId, networkAgent); 8012 8013 // update filtering rules, need to happen after the interface update so netd knows about the 8014 // new interface (the interface name -> index map becomes initialized) 8015 updateVpnFiltering(newLp, oldLp, networkAgent); 8016 8017 updateMtu(newLp, oldLp); 8018 // TODO - figure out what to do for clat 8019 // for (LinkProperties lp : newLp.getStackedLinks()) { 8020 // updateMtu(lp, null); 8021 // } 8022 if (isDefaultNetwork(networkAgent)) { 8023 mProxyTracker.updateDefaultNetworkProxyPortForPAC(newLp, null); 8024 updateTcpBufferSizes(newLp.getTcpBufferSizes()); 8025 } 8026 8027 updateRoutes(newLp, oldLp, netId); 8028 updateDnses(newLp, oldLp, netId); 8029 // Make sure LinkProperties represents the latest private DNS status. 8030 // This does not need to be done before updateDnses because the 8031 // LinkProperties are not the source of the private DNS configuration. 8032 // updateDnses will fetch the private DNS configuration from DnsManager. 8033 mDnsManager.updatePrivateDnsStatus(netId, newLp); 8034 8035 if (isDefaultNetwork(networkAgent)) { 8036 mProxyTracker.setDefaultProxy(newLp.getHttpProxy()); 8037 } else if (networkAgent.everConnected()) { 8038 updateProxy(newLp, oldLp); 8039 } 8040 8041 updateWakeOnLan(newLp); 8042 8043 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo. 8044 // It is not always contained in the LinkProperties sent from NetworkAgents, and if it 8045 // does, it needs to be merged here. 8046 newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData, 8047 networkAgent.capportApiData)); 8048 8049 // TODO - move this check to cover the whole function 8050 if (!Objects.equals(newLp, oldLp)) { 8051 synchronized (networkAgent) { 8052 networkAgent.linkProperties = newLp; 8053 } 8054 // Start or stop DNS64 detection and 464xlat according to network state. 8055 networkAgent.clatd.update(); 8056 // Notify NSS when relevant events happened. Currently, NSS only cares about 8057 // interface changed to update clat interfaces accounting. 8058 final boolean interfacesChanged = oldLp == null 8059 || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames()); 8060 if (interfacesChanged) { 8061 notifyIfacesChangedForNetworkStats(); 8062 } 8063 networkAgent.networkMonitor().notifyLinkPropertiesChanged( 8064 new LinkProperties(newLp, true /* parcelSensitiveFields */)); 8065 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 8066 } 8067 8068 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 8069 } 8070 8071 private void applyInitialLinkProperties(@NonNull NetworkAgentInfo nai) { 8072 updateLinkProperties(nai, new LinkProperties(nai.linkProperties), null); 8073 } 8074 8075 /** 8076 * @param naData captive portal data from NetworkAgent 8077 * @param apiData captive portal data from capport API 8078 */ 8079 @Nullable 8080 private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData, 8081 CaptivePortalData apiData) { 8082 if (naData == null || apiData == null) { 8083 return naData == null ? apiData : naData; 8084 } 8085 final CaptivePortalData.Builder captivePortalBuilder = 8086 new CaptivePortalData.Builder(naData); 8087 8088 if (apiData.isCaptive()) { 8089 captivePortalBuilder.setCaptive(true); 8090 } 8091 if (apiData.isSessionExtendable()) { 8092 captivePortalBuilder.setSessionExtendable(true); 8093 } 8094 if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) { 8095 // Expiry time, bytes remaining, refresh time all need to come from the same source, 8096 // otherwise data would be inconsistent. Prefer the capport API info if present, 8097 // as it can generally be refreshed more often. 8098 captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis()); 8099 captivePortalBuilder.setBytesRemaining(apiData.getByteLimit()); 8100 captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis()); 8101 } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) { 8102 // No source has time / bytes remaining information: surface the newest refresh time 8103 // for other fields 8104 captivePortalBuilder.setRefreshTime( 8105 Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis())); 8106 } 8107 8108 // Prioritize the user portal URL from the network agent if the source is authenticated. 8109 if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource() 8110 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 8111 captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(), 8112 apiData.getUserPortalUrlSource()); 8113 } 8114 // Prioritize the venue information URL from the network agent if the source is 8115 // authenticated. 8116 if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource() 8117 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) { 8118 captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(), 8119 apiData.getVenueInfoUrlSource()); 8120 } 8121 return captivePortalBuilder.build(); 8122 } 8123 8124 @VisibleForTesting 8125 static String makeNflogPrefix(String iface, long networkHandle) { 8126 // This needs to be kept in sync and backwards compatible with the decoding logic in 8127 // NetdEventListenerService, which is non-mainline code. 8128 return SdkLevel.isAtLeastU() ? (networkHandle + ":" + iface) : ("iface:" + iface); 8129 } 8130 8131 private static boolean isWakeupMarkingSupported(NetworkCapabilities capabilities) { 8132 if (capabilities.hasTransport(TRANSPORT_WIFI)) { 8133 return true; 8134 } 8135 if (SdkLevel.isAtLeastU() && capabilities.hasTransport(TRANSPORT_CELLULAR)) { 8136 return true; 8137 } 8138 return false; 8139 } 8140 8141 private void wakeupModifyInterface(String iface, NetworkAgentInfo nai, boolean add) { 8142 // Marks are only available on WiFi interfaces. Checking for 8143 // marks on unsupported interfaces is harmless. 8144 if (!isWakeupMarkingSupported(nai.networkCapabilities)) { 8145 return; 8146 } 8147 8148 // Mask/mark of zero will not detect anything interesting. 8149 // Don't install rules unless both values are nonzero. 8150 if (mWakeUpMark == 0 || mWakeUpMask == 0) { 8151 return; 8152 } 8153 8154 final String prefix = makeNflogPrefix(iface, nai.network.getNetworkHandle()); 8155 try { 8156 if (add) { 8157 mNetd.wakeupAddInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 8158 } else { 8159 mNetd.wakeupDelInterface(iface, prefix, mWakeUpMark, mWakeUpMask); 8160 } 8161 } catch (Exception e) { 8162 loge("Exception modifying wakeup packet monitoring: " + e); 8163 } 8164 } 8165 8166 private void updateInterfaces(final @NonNull LinkProperties newLp, 8167 final @Nullable LinkProperties oldLp, final int netId, 8168 final @NonNull NetworkAgentInfo nai) { 8169 final CompareResult<String> interfaceDiff = new CompareResult<>( 8170 oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames()); 8171 if (!interfaceDiff.added.isEmpty()) { 8172 for (final String iface : interfaceDiff.added) { 8173 try { 8174 if (DBG) log("Adding iface " + iface + " to network " + netId); 8175 mNetd.networkAddInterface(netId, iface); 8176 wakeupModifyInterface(iface, nai, true); 8177 mDeps.reportNetworkInterfaceForTransports(mContext, iface, 8178 nai.networkCapabilities.getTransportTypes()); 8179 } catch (Exception e) { 8180 logw("Exception adding interface: " + e); 8181 } 8182 } 8183 } 8184 for (final String iface : interfaceDiff.removed) { 8185 try { 8186 if (DBG) log("Removing iface " + iface + " from network " + netId); 8187 wakeupModifyInterface(iface, nai, false); 8188 mNetd.networkRemoveInterface(netId, iface); 8189 } catch (Exception e) { 8190 loge("Exception removing interface: " + e); 8191 } 8192 } 8193 } 8194 8195 // TODO: move to frameworks/libs/net. 8196 private RouteInfoParcel convertRouteInfo(RouteInfo route) { 8197 final String nextHop; 8198 8199 switch (route.getType()) { 8200 case RouteInfo.RTN_UNICAST: 8201 if (route.hasGateway()) { 8202 nextHop = route.getGateway().getHostAddress(); 8203 } else { 8204 nextHop = INetd.NEXTHOP_NONE; 8205 } 8206 break; 8207 case RouteInfo.RTN_UNREACHABLE: 8208 nextHop = INetd.NEXTHOP_UNREACHABLE; 8209 break; 8210 case RouteInfo.RTN_THROW: 8211 nextHop = INetd.NEXTHOP_THROW; 8212 break; 8213 default: 8214 nextHop = INetd.NEXTHOP_NONE; 8215 break; 8216 } 8217 8218 final RouteInfoParcel rip = new RouteInfoParcel(); 8219 rip.ifName = route.getInterface(); 8220 rip.destination = route.getDestination().toString(); 8221 rip.nextHop = nextHop; 8222 rip.mtu = route.getMtu(); 8223 8224 return rip; 8225 } 8226 8227 /** 8228 * Have netd update routes from oldLp to newLp. 8229 * @return true if routes changed between oldLp and newLp 8230 */ 8231 private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 8232 int netId) { 8233 // compare the route diff to determine which routes have been updated 8234 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff = 8235 new CompareOrUpdateResult<>( 8236 oldLp != null ? oldLp.getAllRoutes() : null, 8237 newLp.getAllRoutes(), 8238 (r) -> r.getRouteKey()); 8239 8240 // add routes before removing old in case it helps with continuous connectivity 8241 8242 // do this twice, adding non-next-hop routes first, then routes they are dependent on 8243 for (RouteInfo route : routeDiff.added) { 8244 if (route.hasGateway()) continue; 8245 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 8246 try { 8247 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); 8248 } catch (Exception e) { 8249 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 8250 loge("Exception in networkAddRouteParcel for non-gateway: " + e); 8251 } 8252 } 8253 } 8254 for (RouteInfo route : routeDiff.added) { 8255 if (!route.hasGateway()) continue; 8256 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); 8257 try { 8258 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); 8259 } catch (Exception e) { 8260 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 8261 loge("Exception in networkAddRouteParcel for gateway: " + e); 8262 } 8263 } 8264 } 8265 8266 for (RouteInfo route : routeDiff.removed) { 8267 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); 8268 try { 8269 mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route)); 8270 } catch (Exception e) { 8271 loge("Exception in networkRemoveRouteParcel: " + e); 8272 } 8273 } 8274 8275 for (RouteInfo route : routeDiff.updated) { 8276 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId); 8277 try { 8278 mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route)); 8279 } catch (Exception e) { 8280 loge("Exception in networkUpdateRouteParcel: " + e); 8281 } 8282 } 8283 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty() 8284 || !routeDiff.updated.isEmpty(); 8285 } 8286 8287 private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 8288 int netId) { 8289 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 8290 return; // no updating necessary 8291 } 8292 8293 if (DBG) { 8294 final Collection<InetAddress> dnses = newLp.getDnsServers(); 8295 log("Setting DNS servers for network " + netId + " to " + dnses); 8296 } 8297 try { 8298 mDnsManager.noteDnsServersForNetwork(netId, newLp); 8299 mDnsManager.flushVmDnsCache(); 8300 } catch (Exception e) { 8301 loge("Exception in setDnsConfigurationForNetwork: " + e); 8302 } 8303 } 8304 8305 private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp, 8306 @NonNull NetworkAgentInfo nai) { 8307 final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp); 8308 final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp); 8309 final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface); 8310 final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface); 8311 8312 if (!wasFiltering && !needsFiltering) { 8313 // Nothing to do. 8314 return; 8315 } 8316 8317 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) { 8318 // Nothing changed. 8319 return; 8320 } 8321 8322 final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges(); 8323 if (ranges == null || ranges.isEmpty()) { 8324 return; 8325 } 8326 8327 final int vpnAppUid = nai.networkCapabilities.getOwnerUid(); 8328 // TODO: this create a window of opportunity for apps to receive traffic between the time 8329 // when the old rules are removed and the time when new rules are added. To fix this, 8330 // make eBPF support two allowlisted interfaces so here new rules can be added before the 8331 // old rules are being removed. 8332 if (wasFiltering) { 8333 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid); 8334 } 8335 if (needsFiltering) { 8336 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid); 8337 } 8338 } 8339 8340 private void updateWakeOnLan(@NonNull LinkProperties lp) { 8341 if (mWolSupportedInterfaces == null) { 8342 mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray( 8343 R.array.config_wakeonlan_supported_interfaces)); 8344 } 8345 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName())); 8346 } 8347 8348 private int getNetworkPermission(NetworkCapabilities nc) { 8349 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 8350 return INetd.PERMISSION_SYSTEM; 8351 } 8352 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 8353 return INetd.PERMISSION_NETWORK; 8354 } 8355 return INetd.PERMISSION_NONE; 8356 } 8357 8358 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai, 8359 @NonNull final NetworkCapabilities newNc) { 8360 final int oldPermission = getNetworkPermission(nai.networkCapabilities); 8361 final int newPermission = getNetworkPermission(newNc); 8362 if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) { 8363 try { 8364 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission); 8365 } catch (RemoteException | ServiceSpecificException e) { 8366 loge("Exception in networkSetPermissionForNetwork: " + e); 8367 } 8368 } 8369 } 8370 8371 /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */ 8372 @VisibleForTesting 8373 void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, 8374 @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { 8375 underlyingNetworks = underlyingNetworksOrDefault( 8376 agentCaps.getOwnerUid(), underlyingNetworks); 8377 long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes()); 8378 int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 8379 int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 8380 // metered if any underlying is metered, or originally declared metered by the agent. 8381 boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 8382 boolean roaming = false; // roaming if any underlying is roaming 8383 boolean congested = false; // congested if any underlying is congested 8384 boolean suspended = true; // suspended if all underlying are suspended 8385 8386 boolean hadUnderlyingNetworks = false; 8387 ArrayList<Network> newUnderlyingNetworks = null; 8388 if (null != underlyingNetworks) { 8389 newUnderlyingNetworks = new ArrayList<>(); 8390 for (Network underlyingNetwork : underlyingNetworks) { 8391 final NetworkAgentInfo underlying = 8392 getNetworkAgentInfoForNetwork(underlyingNetwork); 8393 if (underlying == null) continue; 8394 8395 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; 8396 hadUnderlyingNetworks = true; 8397 for (int underlyingType : underlyingCaps.getTransportTypes()) { 8398 transportTypes |= 1L << underlyingType; 8399 } 8400 8401 // Merge capabilities of this underlying network. For bandwidth, assume the 8402 // worst case. 8403 downKbps = NetworkCapabilities.minBandwidth(downKbps, 8404 underlyingCaps.getLinkDownstreamBandwidthKbps()); 8405 upKbps = NetworkCapabilities.minBandwidth(upKbps, 8406 underlyingCaps.getLinkUpstreamBandwidthKbps()); 8407 // If this underlying network is metered, the VPN is metered (it may cost money 8408 // to send packets on this network). 8409 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); 8410 // If this underlying network is roaming, the VPN is roaming (the billing structure 8411 // is different than the usual, local one). 8412 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); 8413 // If this underlying network is congested, the VPN is congested (the current 8414 // condition of the network affects the performance of this network). 8415 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 8416 // If this network is not suspended, the VPN is not suspended (the VPN 8417 // is able to transfer some data). 8418 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 8419 newUnderlyingNetworks.add(underlyingNetwork); 8420 } 8421 } 8422 if (!hadUnderlyingNetworks) { 8423 // No idea what the underlying networks are; assume reasonable defaults 8424 metered = true; 8425 roaming = false; 8426 congested = false; 8427 suspended = false; 8428 } 8429 8430 newNc.setTransportTypes(BitUtils.unpackBits(transportTypes)); 8431 newNc.setLinkDownstreamBandwidthKbps(downKbps); 8432 newNc.setLinkUpstreamBandwidthKbps(upKbps); 8433 newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered); 8434 newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); 8435 newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); 8436 newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); 8437 newNc.setUnderlyingNetworks(newUnderlyingNetworks); 8438 } 8439 8440 /** 8441 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 8442 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 8443 * and foreground status). 8444 */ 8445 @NonNull 8446 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 8447 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 8448 // Don't complain for VPNs since they're not driven by requests and there is no risk of 8449 // causing a connect/teardown loop. 8450 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to 8451 // avoid connect/teardown loops. 8452 if (nai.everConnected() 8453 && !nai.isVPN() 8454 && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 8455 // TODO: consider not complaining when a network agent degrades its capabilities if this 8456 // does not cause any request (that is not a listen) currently matching that agent to 8457 // stop being matched by the updated agent. 8458 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 8459 if (!TextUtils.isEmpty(diff)) { 8460 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 8461 } 8462 } 8463 8464 // Don't modify caller's NetworkCapabilities. 8465 final NetworkCapabilities newNc = new NetworkCapabilities(nc); 8466 if (nai.isValidated()) { 8467 newNc.addCapability(NET_CAPABILITY_VALIDATED); 8468 } else { 8469 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 8470 } 8471 if (nai.captivePortalDetected()) { 8472 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 8473 } else { 8474 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 8475 } 8476 if (nai.isBackgroundNetwork()) { 8477 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 8478 } else { 8479 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 8480 } 8481 if (nai.partialConnectivity()) { 8482 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 8483 } else { 8484 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); 8485 } 8486 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken()); 8487 8488 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING 8489 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) { 8490 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8491 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING); 8492 } 8493 8494 if (nai.propagateUnderlyingCapabilities()) { 8495 applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, 8496 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator), 8497 newNc); 8498 } 8499 8500 return newNc; 8501 } 8502 8503 private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai, 8504 NetworkCapabilities prevNc, NetworkCapabilities newNc) { 8505 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 8506 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 8507 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 8508 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 8509 if (prevSuspended != suspended) { 8510 // TODO (b/73132094) : remove this call once the few users of onSuspended and 8511 // onResumed have been removed. 8512 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED 8513 : ConnectivityManager.CALLBACK_RESUMED); 8514 } 8515 if (prevSuspended != suspended || prevRoaming != roaming) { 8516 // updateNetworkInfo will mix in the suspended info from the capabilities and 8517 // take appropriate action for the network having possibly changed state. 8518 updateNetworkInfo(nai, nai.networkInfo); 8519 } 8520 } 8521 8522 /** 8523 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 8524 * 8525 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 8526 * capabilities we manage and store in {@code nai}, such as validated status and captive 8527 * portal status) 8528 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 8529 * potentially triggers rematches. 8530 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 8531 * change.) 8532 * 8533 * @param oldScore score of the network before any of the changes that prompted us 8534 * to call this function. 8535 * @param nai the network having its capabilities updated. 8536 * @param nc the new network capabilities. 8537 */ 8538 private void updateCapabilities(final FullScore oldScore, @NonNull final NetworkAgentInfo nai, 8539 @NonNull final NetworkCapabilities nc) { 8540 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 8541 if (Objects.equals(nai.networkCapabilities, newNc)) return; 8542 final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities); 8543 if (null != differences) { 8544 Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences); 8545 } 8546 updateNetworkPermissions(nai, newNc); 8547 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc); 8548 8549 updateVpnUids(nai, prevNc, newNc); 8550 updateAllowedUids(nai, prevNc, newNc); 8551 nai.updateScoreForNetworkAgentUpdate(); 8552 8553 if (nai.getScore().equals(oldScore) && newNc.equalRequestableCapabilities(prevNc)) { 8554 // If the requestable capabilities haven't changed, and the score hasn't changed, then 8555 // the change we're processing can't affect any requests, it can only affect the listens 8556 // on this network. We might have been called by rematchNetworkAndRequests when a 8557 // network changed foreground state. 8558 processListenRequests(nai); 8559 } else { 8560 // If the requestable capabilities have changed or the score changed, we can't have been 8561 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 8562 rematchAllNetworksAndRequests(); 8563 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 8564 } 8565 updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc); 8566 8567 final boolean oldMetered = prevNc.isMetered(); 8568 final boolean newMetered = newNc.isMetered(); 8569 final boolean meteredChanged = oldMetered != newMetered; 8570 8571 if (meteredChanged) { 8572 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, 8573 mVpnBlockedUidRanges, mVpnBlockedUidRanges); 8574 } 8575 8576 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) 8577 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 8578 8579 // Report changes that are interesting for network statistics tracking. 8580 if (meteredChanged || roamingChanged) { 8581 notifyIfacesChangedForNetworkStats(); 8582 } 8583 8584 // This network might have been underlying another network. Propagate its capabilities. 8585 propagateUnderlyingNetworkCapabilities(nai.network); 8586 8587 if (!newNc.equalsTransportTypes(prevNc)) { 8588 mDnsManager.updateTransportsForNetwork( 8589 nai.network.getNetId(), newNc.getTransportTypes()); 8590 } 8591 8592 maybeSendProxyBroadcast(nai, prevNc, newNc); 8593 } 8594 8595 /** Convenience method to update the capabilities for a given network. */ 8596 private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) { 8597 updateCapabilities(nai.getScore(), nai, nai.networkCapabilities); 8598 } 8599 8600 /** 8601 * Returns the interface which requires VPN isolation (ingress interface filtering). 8602 * 8603 * Ingress interface filtering enforces that all apps under the given network can only receive 8604 * packets from the network's interface (and loopback). This is important for VPNs because 8605 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any 8606 * non-VPN interfaces. 8607 * 8608 * As a result, this method should return Non-null interface iff 8609 * 1. the network is an app VPN (not legacy VPN) 8610 * 2. the VPN does not allow bypass 8611 * 3. the VPN is fully-routed 8612 * 4. the VPN interface is non-null 8613 * 8614 * @see INetd#firewallAddUidInterfaceRules 8615 * @see INetd#firewallRemoveUidInterfaceRules 8616 */ 8617 @Nullable 8618 private String getVpnIsolationInterface(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc, 8619 LinkProperties lp) { 8620 if (nc == null || lp == null) return null; 8621 if (nai.isVPN() 8622 && !nai.networkAgentConfig.allowBypass 8623 && nc.getOwnerUid() != Process.SYSTEM_UID 8624 && lp.getInterfaceName() != null 8625 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute()) 8626 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()) 8627 && !lp.hasExcludeRoute()) { 8628 return lp.getInterfaceName(); 8629 } 8630 return null; 8631 } 8632 8633 /** 8634 * Returns whether we need to set interface filtering rule or not 8635 */ 8636 private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp, 8637 String isolationIface) { 8638 // Allow rules are always needed if VPN isolation is enabled. 8639 if (isolationIface != null) return true; 8640 8641 // On T and above, allow rules are needed for all VPNs. Allow rule with null iface is a 8642 // wildcard to allow apps to receive packets on all interfaces. This is required to accept 8643 // incoming traffic in Lockdown mode by overriding the Lockdown blocking rule. 8644 return mDeps.isAtLeastT() && nai.isVPN() && lp != null && lp.getInterfaceName() != null; 8645 } 8646 8647 private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 8648 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; 8649 int index = 0; 8650 for (UidRange range : ranges) { 8651 stableRanges[index] = new UidRangeParcel(range.start, range.stop); 8652 index++; 8653 } 8654 return stableRanges; 8655 } 8656 8657 private static UidRangeParcel[] intsToUidRangeStableParcels( 8658 final @NonNull ArraySet<Integer> uids) { 8659 final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()]; 8660 int index = 0; 8661 for (int uid : uids) { 8662 stableRanges[index] = new UidRangeParcel(uid, uid); 8663 index++; 8664 } 8665 return stableRanges; 8666 } 8667 8668 private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) { 8669 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 8670 for (int i = 0; i < ranges.length; i++) { 8671 stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop); 8672 } 8673 return stableRanges; 8674 } 8675 8676 private void maybeCloseSockets(NetworkAgentInfo nai, Set<UidRange> ranges, 8677 UidRangeParcel[] uidRangeParcels, int[] exemptUids) { 8678 if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) { 8679 try { 8680 if (mDeps.isAtLeastU()) { 8681 final Set<Integer> exemptUidSet = new ArraySet<>(); 8682 for (final int uid: exemptUids) { 8683 exemptUidSet.add(uid); 8684 } 8685 mDeps.destroyLiveTcpSockets(UidRange.toIntRanges(ranges), exemptUidSet); 8686 } else { 8687 mNetd.socketDestroy(uidRangeParcels, exemptUids); 8688 } 8689 } catch (Exception e) { 8690 loge("Exception in socket destroy: ", e); 8691 } 8692 } 8693 } 8694 8695 private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) { 8696 int[] exemptUids = new int[2]; 8697 // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used 8698 // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when 8699 // starting a legacy VPN, and remove VPN_UID here. (b/176542831) 8700 exemptUids[0] = VPN_UID; 8701 exemptUids[1] = nai.networkCapabilities.getOwnerUid(); 8702 UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges); 8703 8704 // Close sockets before modifying uid ranges so that RST packets can reach to the server. 8705 maybeCloseSockets(nai, uidRanges, ranges, exemptUids); 8706 try { 8707 if (add) { 8708 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 8709 nai.network.netId, ranges, PREFERENCE_ORDER_VPN)); 8710 } else { 8711 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 8712 nai.network.netId, ranges, PREFERENCE_ORDER_VPN)); 8713 } 8714 } catch (Exception e) { 8715 loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges + 8716 " on netId " + nai.network.netId + ". " + e); 8717 } 8718 // Close sockets that established connection while requesting netd. 8719 maybeCloseSockets(nai, uidRanges, ranges, exemptUids); 8720 } 8721 8722 private boolean isProxySetOnAnyDefaultNetwork() { 8723 ensureRunningOnConnectivityServiceThread(); 8724 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 8725 final NetworkAgentInfo nai = nri.getSatisfier(); 8726 if (nai != null && nai.linkProperties.getHttpProxy() != null) { 8727 return true; 8728 } 8729 } 8730 return false; 8731 } 8732 8733 private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc, 8734 NetworkCapabilities newNc) { 8735 // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that 8736 // the proxy might be changed since the default network satisfied by the apps might also 8737 // changed. 8738 // TODO: Try to track the default network that apps use and only send a proxy broadcast when 8739 // that happens to prevent false alarms. 8740 final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges(); 8741 final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges(); 8742 if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids) 8743 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) { 8744 mProxyTracker.sendProxyBroadcast(); 8745 } 8746 } 8747 8748 private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc, 8749 @Nullable NetworkCapabilities newNc) { 8750 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges(); 8751 Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges(); 8752 if (null == prevRanges) prevRanges = new ArraySet<>(); 8753 if (null == newRanges) newRanges = new ArraySet<>(); 8754 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 8755 8756 prevRanges.removeAll(newRanges); 8757 newRanges.removeAll(prevRangesCopy); 8758 8759 try { 8760 // When updating the VPN uid routing rules, add the new range first then remove the old 8761 // range. If old range were removed first, there would be a window between the old 8762 // range being removed and the new range being added, during which UIDs contained 8763 // in both ranges are not subject to any VPN routing rules. Adding new range before 8764 // removing old range works because, unlike the filtering rules below, it's possible to 8765 // add duplicate UID routing rules. 8766 // TODO: calculate the intersection of add & remove. Imagining that we are trying to 8767 // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is: 8768 // [1-5] & [1-2],[4-5] == [3] 8769 // Then we can do: 8770 // maybeCloseSockets([3]) 8771 // mNetd.networkAddUidRanges([1-2],[4-5]) 8772 // mNetd.networkRemoveUidRanges([1-5]) 8773 // maybeCloseSockets([3]) 8774 // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the 8775 // number of binder calls from 6 to 4. 8776 if (!newRanges.isEmpty()) { 8777 updateVpnUidRanges(true, nai, newRanges); 8778 } 8779 if (!prevRanges.isEmpty()) { 8780 updateVpnUidRanges(false, nai, prevRanges); 8781 } 8782 final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties); 8783 final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties); 8784 final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface); 8785 final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface); 8786 // For VPN uid interface filtering, old ranges need to be removed before new ranges can 8787 // be added, due to the range being expanded and stored as individual UIDs. For example 8788 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means 8789 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges 8790 // were added first and then newRanges got removed later, there would be only one uid 8791 // 10013 left. A consequence of removing old ranges before adding new ranges is that 8792 // there is now a window of opportunity when the UIDs are not subject to any filtering. 8793 // Note that this is in contrast with the (more robust) update of VPN routing rules 8794 // above, where the addition of new ranges happens before the removal of old ranges. 8795 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range 8796 // to be removed will never overlap with the new range to be added. 8797 if (wasFiltering && !prevRanges.isEmpty()) { 8798 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges, 8799 prevNc.getOwnerUid()); 8800 } 8801 if (shouldFilter && !newRanges.isEmpty()) { 8802 mPermissionMonitor.onVpnUidRangesAdded(newIface, newRanges, newNc.getOwnerUid()); 8803 } 8804 } catch (Exception e) { 8805 // Never crash! 8806 loge("Exception in updateVpnUids: ", e); 8807 } 8808 } 8809 8810 private void updateAllowedUids(@NonNull NetworkAgentInfo nai, 8811 @Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) { 8812 // In almost all cases both NC code for empty access UIDs. return as fast as possible. 8813 final boolean prevEmpty = null == prevNc || prevNc.getAllowedUidsNoCopy().isEmpty(); 8814 final boolean newEmpty = null == newNc || newNc.getAllowedUidsNoCopy().isEmpty(); 8815 if (prevEmpty && newEmpty) return; 8816 8817 final ArraySet<Integer> prevUids = 8818 null == prevNc ? new ArraySet<>() : prevNc.getAllowedUidsNoCopy(); 8819 final ArraySet<Integer> newUids = 8820 null == newNc ? new ArraySet<>() : newNc.getAllowedUidsNoCopy(); 8821 8822 if (prevUids.equals(newUids)) return; 8823 8824 // This implementation is very simple and vastly faster for sets of Integers than 8825 // CompareOrUpdateResult, which is tuned for sets that need to be compared based on 8826 // a key computed from the value and has storage for that. 8827 final ArraySet<Integer> toRemove = new ArraySet<>(prevUids); 8828 final ArraySet<Integer> toAdd = new ArraySet<>(newUids); 8829 toRemove.removeAll(newUids); 8830 toAdd.removeAll(prevUids); 8831 8832 try { 8833 if (!toAdd.isEmpty()) { 8834 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 8835 nai.network.netId, 8836 intsToUidRangeStableParcels(toAdd), 8837 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT)); 8838 } 8839 if (!toRemove.isEmpty()) { 8840 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 8841 nai.network.netId, 8842 intsToUidRangeStableParcels(toRemove), 8843 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT)); 8844 } 8845 } catch (ServiceSpecificException e) { 8846 // Has the interface disappeared since the network was built ? 8847 Log.i(TAG, "Can't set access UIDs for network " + nai.network, e); 8848 } catch (RemoteException e) { 8849 // Netd died. This usually causes a runtime restart anyway. 8850 } 8851 } 8852 8853 public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai, 8854 @NonNull LinkProperties newLp) { 8855 ensureRunningOnConnectivityServiceThread(); 8856 8857 if (!mNetworkAgentInfos.contains(nai)) { 8858 // Ignore updates for disconnected networks 8859 return; 8860 } 8861 if (VDBG || DDBG) { 8862 log("Update of LinkProperties for " + nai.toShortString() 8863 + "; created=" + nai.getCreatedTime() 8864 + "; firstConnected=" + nai.getConnectedTime()); 8865 } 8866 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not 8867 // modify its oldLp parameter. 8868 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties)); 8869 } 8870 8871 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 8872 int notificationType) { 8873 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 8874 Intent intent = new Intent(); 8875 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 8876 // If apps could file multi-layer requests with PendingIntents, they'd need to know 8877 // which of the layer is satisfied alongside with some ID for the request. Hence, if 8878 // such an API is ever implemented, there is no doubt the right request to send in 8879 // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would 8880 // need to be sent as a separate extra. 8881 final NetworkRequest req = nri.isMultilayerRequest() 8882 ? nri.getActiveRequest() 8883 // Non-multilayer listen requests do not have an active request 8884 : nri.mRequests.get(0); 8885 if (req == null) { 8886 Log.wtf(TAG, "No request in NRI " + nri); 8887 } 8888 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req); 8889 nri.mPendingIntentSent = true; 8890 sendIntent(nri.mPendingIntent, intent); 8891 } 8892 // else not handled 8893 } 8894 8895 // TODO(b/193460475): Remove when tooling supports SystemApi to public API. 8896 @SuppressLint("NewApi") 8897 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 8898 mPendingIntentWakeLock.acquire(); 8899 try { 8900 if (DBG) log("Sending " + pendingIntent); 8901 final BroadcastOptions options = BroadcastOptions.makeBasic(); 8902 if (mDeps.isAtLeastT()) { 8903 // Explicitly disallow the receiver from starting activities, to prevent apps from 8904 // utilizing the PendingIntent as a backdoor to do this. 8905 options.setPendingIntentBackgroundActivityLaunchAllowed(false); 8906 } 8907 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */, 8908 null /* requiredPermission */, 8909 mDeps.isAtLeastT() ? options.toBundle() : null); 8910 } catch (PendingIntent.CanceledException e) { 8911 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 8912 mPendingIntentWakeLock.release(); 8913 releasePendingNetworkRequest(pendingIntent); 8914 } 8915 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 8916 } 8917 8918 @Override 8919 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 8920 String resultData, Bundle resultExtras) { 8921 if (DBG) log("Finished sending " + pendingIntent); 8922 mPendingIntentWakeLock.release(); 8923 // Release with a delay so the receiving client has an opportunity to put in its 8924 // own request. 8925 releasePendingNetworkRequestWithDelay(pendingIntent); 8926 } 8927 8928 // networkAgent is only allowed to be null if notificationType is 8929 // CALLBACK_UNAVAIL. This is because UNAVAIL is about no network being 8930 // available, while all other cases are about some particular network. 8931 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, 8932 @Nullable final NetworkAgentInfo networkAgent, final int notificationType, 8933 final int arg1) { 8934 if (nri.mMessenger == null) { 8935 // Default request has no msgr. Also prevents callbacks from being invoked for 8936 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks 8937 // are Type.LISTEN, but should not have NetworkCallbacks invoked. 8938 return; 8939 } 8940 Bundle bundle = new Bundle(); 8941 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. 8942 // TODO: check if defensive copies of data is needed. 8943 final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); 8944 putParcelable(bundle, nrForCallback); 8945 Message msg = Message.obtain(); 8946 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) { 8947 putParcelable(bundle, networkAgent.network); 8948 } 8949 final boolean includeLocationSensitiveInfo = 8950 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0; 8951 switch (notificationType) { 8952 case ConnectivityManager.CALLBACK_AVAILABLE: { 8953 final NetworkCapabilities nc = 8954 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 8955 networkCapabilitiesRestrictedForCallerPermissions( 8956 networkAgent.networkCapabilities, nri.mPid, nri.mUid), 8957 includeLocationSensitiveInfo, nri.mPid, nri.mUid, 8958 nrForCallback.getRequestorPackageName(), 8959 nri.mCallingAttributionTag); 8960 putParcelable(bundle, nc); 8961 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 8962 networkAgent.linkProperties, nri.mPid, nri.mUid)); 8963 // For this notification, arg1 contains the blocked status. 8964 msg.arg1 = arg1; 8965 break; 8966 } 8967 case ConnectivityManager.CALLBACK_LOSING: { 8968 msg.arg1 = arg1; 8969 break; 8970 } 8971 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 8972 // networkAgent can't be null as it has been accessed a few lines above. 8973 final NetworkCapabilities netCap = 8974 networkCapabilitiesRestrictedForCallerPermissions( 8975 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 8976 putParcelable( 8977 bundle, 8978 createWithLocationInfoSanitizedIfNecessaryWhenParceled( 8979 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid, 8980 nrForCallback.getRequestorPackageName(), 8981 nri.mCallingAttributionTag)); 8982 break; 8983 } 8984 case ConnectivityManager.CALLBACK_IP_CHANGED: { 8985 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions( 8986 networkAgent.linkProperties, nri.mPid, nri.mUid)); 8987 break; 8988 } 8989 case ConnectivityManager.CALLBACK_BLK_CHANGED: { 8990 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1); 8991 msg.arg1 = arg1; 8992 break; 8993 } 8994 } 8995 msg.what = notificationType; 8996 msg.setData(bundle); 8997 try { 8998 if (VDBG) { 8999 String notification = ConnectivityManager.getCallbackName(notificationType); 9000 log("sending notification " + notification + " for " + nrForCallback); 9001 } 9002 nri.mMessenger.send(msg); 9003 } catch (RemoteException e) { 9004 // may occur naturally in the race of binder death. 9005 loge("RemoteException caught trying to send a callback msg for " + nrForCallback); 9006 } 9007 } 9008 9009 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 9010 bundle.putParcelable(t.getClass().getSimpleName(), t); 9011 } 9012 9013 /** 9014 * Returns whether reassigning a request from an NAI to another can be done gracefully. 9015 * 9016 * When a request should be assigned to a new network, it is normally lingered to give 9017 * time for apps to gracefully migrate their connections. When both networks are on the same 9018 * radio, but that radio can't do time-sharing efficiently, this may end up being 9019 * counter-productive because any traffic on the old network may drastically reduce the 9020 * performance of the new network. 9021 * The stack supports a configuration to let modem vendors state that their radio can't 9022 * do time-sharing efficiently. If this configuration is set, the stack assumes moving 9023 * from one cell network to another can't be done gracefully. 9024 * 9025 * @param oldNai the old network serving the request 9026 * @param newNai the new network serving the request 9027 * @return whether the switch can be graceful 9028 */ 9029 private boolean canSupportGracefulNetworkSwitch(@NonNull final NetworkAgentInfo oldSatisfier, 9030 @NonNull final NetworkAgentInfo newSatisfier) { 9031 if (mCellularRadioTimesharingCapable) return true; 9032 return !oldSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 9033 || !newSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR) 9034 || !newSatisfier.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY); 9035 } 9036 9037 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 9038 if (nai.numRequestNetworkRequests() != 0) { 9039 for (int i = 0; i < nai.numNetworkRequests(); i++) { 9040 NetworkRequest nr = nai.requestAt(i); 9041 // Ignore listening and track default requests. 9042 if (!nr.isRequest()) continue; 9043 loge("Dead network still had at least " + nr); 9044 break; 9045 } 9046 } 9047 nai.disconnect(); 9048 } 9049 9050 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 9051 if (oldNetwork == null) { 9052 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 9053 return; 9054 } 9055 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString()); 9056 9057 // If we get here it means that the last linger timeout for this network expired. So there 9058 // must be no other active linger timers, and we must stop lingering. 9059 oldNetwork.clearInactivityState(); 9060 9061 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 9062 // Tear the network down. 9063 teardownUnneededNetwork(oldNetwork); 9064 } else { 9065 // Put the network in the background if it doesn't satisfy any foreground request. 9066 updateCapabilitiesForNetwork(oldNetwork); 9067 } 9068 } 9069 9070 private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) { 9071 boolean isDefaultChanged = false; 9072 for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) { 9073 final NetworkReassignment.RequestReassignment reassignment = 9074 changes.getReassignment(defaultRequestInfo); 9075 if (null == reassignment) { 9076 continue; 9077 } 9078 // reassignment only contains those instances where the satisfying network changed. 9079 isDefaultChanged = true; 9080 // Notify system services of the new default. 9081 makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork); 9082 } 9083 9084 if (isDefaultChanged) { 9085 // Hold a wakelock for a short time to help apps in migrating to a new default. 9086 scheduleReleaseNetworkTransitionWakelock(); 9087 } 9088 } 9089 9090 private void resetHttpProxyForNonDefaultNetwork(NetworkAgentInfo oldDefaultNetwork) { 9091 if (null == oldDefaultNetwork) return; 9092 // The network stopped being the default. If it was using a PAC proxy, then the 9093 // proxy needs to be reset, otherwise HTTP requests on this network may be sent 9094 // to the local proxy server, which would forward them over the newly default network. 9095 final ProxyInfo proxyInfo = oldDefaultNetwork.linkProperties.getHttpProxy(); 9096 if (null == proxyInfo || !proxyInfo.isPacProxy()) return; 9097 oldDefaultNetwork.linkProperties.setHttpProxy(new ProxyInfo(proxyInfo.getPacFileUrl())); 9098 notifyNetworkCallbacks(oldDefaultNetwork, CALLBACK_IP_CHANGED); 9099 } 9100 9101 private void makeDefault(@NonNull final NetworkRequestInfo nri, 9102 @Nullable final NetworkAgentInfo oldDefaultNetwork, 9103 @Nullable final NetworkAgentInfo newDefaultNetwork) { 9104 if (DBG) { 9105 log("Switching to new default network for: " + nri + " using " + newDefaultNetwork); 9106 } 9107 9108 // Fix up the NetworkCapabilities of any networks that have this network as underlying. 9109 if (newDefaultNetwork != null) { 9110 propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network); 9111 } 9112 9113 // Set an app level managed default and return since further processing only applies to the 9114 // default network. 9115 if (mDefaultRequest != nri) { 9116 makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork); 9117 return; 9118 } 9119 9120 makeDefaultNetwork(newDefaultNetwork); 9121 9122 if (oldDefaultNetwork != null) { 9123 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork); 9124 } 9125 mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork); 9126 mProxyTracker.setDefaultProxy(null != newDefaultNetwork 9127 ? newDefaultNetwork.linkProperties.getHttpProxy() : null); 9128 resetHttpProxyForNonDefaultNetwork(oldDefaultNetwork); 9129 updateTcpBufferSizes(null != newDefaultNetwork 9130 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null); 9131 notifyIfacesChangedForNetworkStats(); 9132 } 9133 9134 private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri, 9135 @Nullable final NetworkAgentInfo oldDefaultNetwork, 9136 @Nullable final NetworkAgentInfo newDefaultNetwork) { 9137 try { 9138 if (VDBG) { 9139 log("Setting default network for " + nri 9140 + " using UIDs " + nri.getUids() 9141 + " with old network " + (oldDefaultNetwork != null 9142 ? oldDefaultNetwork.network().getNetId() : "null") 9143 + " and new network " + (newDefaultNetwork != null 9144 ? newDefaultNetwork.network().getNetId() : "null")); 9145 } 9146 if (nri.getUids().isEmpty()) { 9147 throw new IllegalStateException("makeDefaultForApps called without specifying" 9148 + " any applications to set as the default." + nri); 9149 } 9150 if (null != newDefaultNetwork) { 9151 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig( 9152 newDefaultNetwork.network.getNetId(), 9153 toUidRangeStableParcels(nri.getUids()), 9154 nri.getPreferenceOrderForNetd())); 9155 } 9156 if (null != oldDefaultNetwork) { 9157 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig( 9158 oldDefaultNetwork.network.getNetId(), 9159 toUidRangeStableParcels(nri.getUids()), 9160 nri.getPreferenceOrderForNetd())); 9161 } 9162 } catch (RemoteException | ServiceSpecificException e) { 9163 loge("Exception setting app default network", e); 9164 } 9165 } 9166 9167 /** 9168 * Collect restricted uid ranges for the given network and UserHandle, these uids 9169 * are not restricted for matched enterprise networks but being restricted for non-matched 9170 * enterprise networks and non-enterprise networks. 9171 */ 9172 @NonNull 9173 private ArraySet<UidRange> getRestrictedUidRangesForEnterpriseBlocking( 9174 @NonNull NetworkAgentInfo nai, @NonNull UserHandle user) { 9175 final ArraySet<UidRange> restrictedUidRanges = new ArraySet<>(); 9176 for (final ProfileNetworkPreferenceInfo pref : mProfileNetworkPreferences) { 9177 if (!pref.user.equals(user) || !pref.blockingNonEnterprise) continue; 9178 9179 if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_ENTERPRISE)) { 9180 // The NC is built from a `ProfileNetworkPreference` which has only one 9181 // enterprise ID, so it's guaranteed to have exactly one. 9182 final int prefId = pref.capabilities.getEnterpriseIds()[0]; 9183 if (nai.networkCapabilities.hasEnterpriseId(prefId)) { 9184 continue; 9185 } 9186 } 9187 9188 if (UidRangeUtils.doesRangeSetOverlap(restrictedUidRanges, 9189 pref.capabilities.getUidRanges())) { 9190 throw new IllegalArgumentException( 9191 "Overlapping uid range in preference: " + pref); 9192 } 9193 restrictedUidRanges.addAll(pref.capabilities.getUidRanges()); 9194 } 9195 return restrictedUidRanges; 9196 } 9197 9198 private void updateProfileAllowedNetworks() { 9199 // Netd command is not implemented before U. 9200 if (!mDeps.isAtLeastU()) return; 9201 9202 ensureRunningOnConnectivityServiceThread(); 9203 final ArrayList<NativeUidRangeConfig> configs = new ArrayList<>(); 9204 final List<UserHandle> users = mContext.getSystemService(UserManager.class) 9205 .getUserHandles(true /* excludeDying */); 9206 if (users.isEmpty()) { 9207 throw new IllegalStateException("No user is available"); 9208 } 9209 9210 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 9211 ArraySet<UidRange> allowedUidRanges = new ArraySet<>(); 9212 for (final UserHandle user : users) { 9213 final ArraySet<UidRange> restrictedUidRanges = 9214 getRestrictedUidRangesForEnterpriseBlocking(nai, user); 9215 allowedUidRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 9216 UidRange.createForUser(user), restrictedUidRanges)); 9217 } 9218 9219 final UidRangeParcel[] rangesParcel = toUidRangeStableParcels(allowedUidRanges); 9220 configs.add(new NativeUidRangeConfig( 9221 nai.network.netId, rangesParcel, 0 /* subPriority */)); 9222 } 9223 9224 // The netd API replaces the previous configs with the current configs. 9225 // Thus, for network disconnection or preference removal, no need to 9226 // unset previous config. Instead, collecting all currently needed 9227 // configs and issue to netd. 9228 try { 9229 mNetd.setNetworkAllowlist(configs.toArray(new NativeUidRangeConfig[0])); 9230 } catch (ServiceSpecificException e) { 9231 // Has the interface disappeared since the network was built? 9232 Log.wtf(TAG, "Unexpected ServiceSpecificException", e); 9233 } catch (RemoteException e) { 9234 // Netd died. This will cause a runtime restart anyway. 9235 Log.wtf(TAG, "Unexpected RemoteException", e); 9236 } 9237 } 9238 9239 private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) { 9240 try { 9241 if (null != newDefaultNetwork) { 9242 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId()); 9243 } else { 9244 mNetd.networkClearDefault(); 9245 } 9246 } catch (RemoteException | ServiceSpecificException e) { 9247 loge("Exception setting default network :" + e); 9248 } 9249 } 9250 9251 private void processListenRequests(@NonNull final NetworkAgentInfo nai) { 9252 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 9253 processNewlyLostListenRequests(nai); 9254 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 9255 processNewlySatisfiedListenRequests(nai); 9256 } 9257 9258 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) { 9259 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 9260 if (nri.isMultilayerRequest()) { 9261 continue; 9262 } 9263 final NetworkRequest nr = nri.mRequests.get(0); 9264 if (!nr.isListen()) continue; 9265 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 9266 nai.removeRequest(nr.requestId); 9267 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0); 9268 } 9269 } 9270 } 9271 9272 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) { 9273 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 9274 if (nri.isMultilayerRequest()) { 9275 continue; 9276 } 9277 final NetworkRequest nr = nri.mRequests.get(0); 9278 if (!nr.isListen()) continue; 9279 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 9280 nai.addRequest(nr); 9281 notifyNetworkAvailable(nai, nri); 9282 } 9283 } 9284 } 9285 9286 // An accumulator class to gather the list of changes that result from a rematch. 9287 private static class NetworkReassignment { 9288 static class RequestReassignment { 9289 @NonNull public final NetworkRequestInfo mNetworkRequestInfo; 9290 @Nullable public final NetworkRequest mOldNetworkRequest; 9291 @Nullable public final NetworkRequest mNewNetworkRequest; 9292 @Nullable public final NetworkAgentInfo mOldNetwork; 9293 @Nullable public final NetworkAgentInfo mNewNetwork; 9294 RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo, 9295 @Nullable final NetworkRequest oldNetworkRequest, 9296 @Nullable final NetworkRequest newNetworkRequest, 9297 @Nullable final NetworkAgentInfo oldNetwork, 9298 @Nullable final NetworkAgentInfo newNetwork) { 9299 mNetworkRequestInfo = networkRequestInfo; 9300 mOldNetworkRequest = oldNetworkRequest; 9301 mNewNetworkRequest = newNetworkRequest; 9302 mOldNetwork = oldNetwork; 9303 mNewNetwork = newNetwork; 9304 } 9305 9306 public String toString() { 9307 final NetworkRequest requestToShow = null != mNewNetworkRequest 9308 ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0); 9309 return requestToShow.requestId + " : " 9310 + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null") 9311 + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null"); 9312 } 9313 } 9314 9315 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>(); 9316 9317 @NonNull Iterable<RequestReassignment> getRequestReassignments() { 9318 return mReassignments; 9319 } 9320 9321 void addRequestReassignment(@NonNull final RequestReassignment reassignment) { 9322 if (Build.isDebuggable()) { 9323 // The code is never supposed to add two reassignments of the same request. Make 9324 // sure this stays true, but without imposing this expensive check on all 9325 // reassignments on all user devices. 9326 for (final RequestReassignment existing : mReassignments) { 9327 if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) { 9328 throw new IllegalStateException("Trying to reassign [" 9329 + reassignment + "] but already have [" 9330 + existing + "]"); 9331 } 9332 } 9333 } 9334 mReassignments.add(reassignment); 9335 } 9336 9337 // Will return null if this reassignment does not change the network assigned to 9338 // the passed request. 9339 @Nullable 9340 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) { 9341 for (final RequestReassignment event : getRequestReassignments()) { 9342 if (nri == event.mNetworkRequestInfo) return event; 9343 } 9344 return null; 9345 } 9346 9347 public String toString() { 9348 final StringJoiner sj = new StringJoiner(", " /* delimiter */, 9349 "NetReassign [" /* prefix */, "]" /* suffix */); 9350 if (mReassignments.isEmpty()) return sj.add("no changes").toString(); 9351 for (final RequestReassignment rr : getRequestReassignments()) { 9352 sj.add(rr.toString()); 9353 } 9354 return sj.toString(); 9355 } 9356 9357 public String debugString() { 9358 final StringBuilder sb = new StringBuilder(); 9359 sb.append("NetworkReassignment :"); 9360 if (mReassignments.isEmpty()) return sb.append(" no changes").toString(); 9361 for (final RequestReassignment rr : getRequestReassignments()) { 9362 sb.append("\n ").append(rr); 9363 } 9364 return sb.append("\n").toString(); 9365 } 9366 } 9367 9368 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri, 9369 @Nullable final NetworkRequest previousRequest, 9370 @Nullable final NetworkRequest newRequest, 9371 @Nullable final NetworkAgentInfo previousSatisfier, 9372 @Nullable final NetworkAgentInfo newSatisfier, 9373 final long now) { 9374 if (null != newSatisfier && mNoServiceNetwork != newSatisfier) { 9375 if (VDBG) log("rematch for " + newSatisfier.toShortString()); 9376 if (null != previousRequest && null != previousSatisfier) { 9377 if (VDBG || DDBG) { 9378 log(" accepting network in place of " + previousSatisfier.toShortString()); 9379 } 9380 previousSatisfier.removeRequest(previousRequest.requestId); 9381 if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier) 9382 && !previousSatisfier.isDestroyed()) { 9383 // If this network switch can't be supported gracefully, the request is not 9384 // lingered. This allows letting go of the network sooner to reclaim some 9385 // performance on the new network, since the radio can't do both at the same 9386 // time while preserving good performance. 9387 // 9388 // Also don't linger the request if the old network has been destroyed. 9389 // A destroyed network does not provide actual network connectivity, so 9390 // lingering it is not useful. In particular this ensures that a destroyed 9391 // network is outscored by its replacement, 9392 // then it is torn down immediately instead of being lingered, and any apps that 9393 // were using it immediately get onLost and can connect using the new network. 9394 previousSatisfier.lingerRequest(previousRequest.requestId, now); 9395 } 9396 } else { 9397 if (VDBG || DDBG) log(" accepting network in place of null"); 9398 } 9399 9400 // To prevent constantly CPU wake up for nascent timer, if a network comes up 9401 // and immediately satisfies a request then remove the timer. This will happen for 9402 // all networks except in the case of an underlying network for a VCN. 9403 if (newSatisfier.isNascent()) { 9404 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE); 9405 newSatisfier.unsetInactive(); 9406 } 9407 9408 // if newSatisfier is not null, then newRequest may not be null. 9409 newSatisfier.unlingerRequest(newRequest.requestId); 9410 if (!newSatisfier.addRequest(newRequest)) { 9411 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has " 9412 + newRequest); 9413 } 9414 } else if (null != previousRequest && null != previousSatisfier) { 9415 if (DBG) { 9416 log("Network " + previousSatisfier.toShortString() + " stopped satisfying" 9417 + " request " + previousRequest.requestId); 9418 } 9419 previousSatisfier.removeRequest(previousRequest.requestId); 9420 } 9421 nri.setSatisfier(newSatisfier, newRequest); 9422 } 9423 9424 /** 9425 * This function is triggered when something can affect what network should satisfy what 9426 * request, and it computes the network reassignment from the passed collection of requests to 9427 * network match to the one that the system should now have. That data is encoded in an 9428 * object that is a list of changes, each of them having an NRI, and old satisfier, and a new 9429 * satisfier. 9430 * 9431 * After the reassignment is computed, it is applied to the state objects. 9432 * 9433 * @param networkRequests the nri objects to evaluate for possible network reassignment 9434 * @return NetworkReassignment listing of proposed network assignment changes 9435 */ 9436 @NonNull 9437 private NetworkReassignment computeNetworkReassignment( 9438 @NonNull final Collection<NetworkRequestInfo> networkRequests) { 9439 final NetworkReassignment changes = new NetworkReassignment(); 9440 9441 // Gather the list of all relevant agents. 9442 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>(); 9443 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 9444 nais.add(nai); 9445 } 9446 9447 for (final NetworkRequestInfo nri : networkRequests) { 9448 // Non-multilayer listen requests can be ignored. 9449 if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) { 9450 continue; 9451 } 9452 NetworkAgentInfo bestNetwork = null; 9453 NetworkRequest bestRequest = null; 9454 for (final NetworkRequest req : nri.mRequests) { 9455 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier()); 9456 // Stop evaluating as the highest possible priority request is satisfied. 9457 if (null != bestNetwork) { 9458 bestRequest = req; 9459 break; 9460 } 9461 } 9462 if (null == bestNetwork && isDefaultBlocked(nri)) { 9463 // Remove default networking if disallowed for managed default requests. 9464 bestNetwork = mNoServiceNetwork; 9465 } 9466 if (nri.getSatisfier() != bestNetwork) { 9467 // bestNetwork may be null if no network can satisfy this request. 9468 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment( 9469 nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork)); 9470 } 9471 } 9472 return changes; 9473 } 9474 9475 private Set<NetworkRequestInfo> getNrisFromGlobalRequests() { 9476 return new HashSet<>(mNetworkRequests.values()); 9477 } 9478 9479 /** 9480 * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks 9481 * being disconnected. 9482 */ 9483 private void rematchAllNetworksAndRequests() { 9484 rematchNetworksAndRequests(getNrisFromGlobalRequests()); 9485 } 9486 9487 /** 9488 * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks 9489 * being disconnected. 9490 */ 9491 private void rematchNetworksAndRequests( 9492 @NonNull final Set<NetworkRequestInfo> networkRequests) { 9493 ensureRunningOnConnectivityServiceThread(); 9494 // TODO: This may be slow, and should be optimized. 9495 final long start = SystemClock.elapsedRealtime(); 9496 final NetworkReassignment changes = computeNetworkReassignment(networkRequests); 9497 final long computed = SystemClock.elapsedRealtime(); 9498 applyNetworkReassignment(changes, start); 9499 final long applied = SystemClock.elapsedRealtime(); 9500 issueNetworkNeeds(); 9501 final long end = SystemClock.elapsedRealtime(); 9502 if (VDBG || DDBG) { 9503 log(String.format("Rematched networks [computed %dms] [applied %dms] [issued %d]", 9504 computed - start, applied - computed, end - applied)); 9505 log(changes.debugString()); 9506 } else if (DBG) { 9507 // Shorter form, only one line of log 9508 log(String.format("%s [c %d] [a %d] [i %d]", changes.toString(), 9509 computed - start, applied - computed, end - applied)); 9510 } 9511 } 9512 9513 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes, 9514 final long now) { 9515 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos; 9516 9517 // Since most of the time there are only 0 or 1 background networks, it would probably 9518 // be more efficient to just use an ArrayList here. TODO : measure performance 9519 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>(); 9520 for (final NetworkAgentInfo nai : nais) { 9521 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai); 9522 } 9523 9524 // First, update the lists of satisfied requests in the network agents. This is necessary 9525 // because some code later depends on this state to be correct, most prominently computing 9526 // the linger status. 9527 for (final NetworkReassignment.RequestReassignment event : 9528 changes.getRequestReassignments()) { 9529 updateSatisfiersForRematchRequest(event.mNetworkRequestInfo, 9530 event.mOldNetworkRequest, event.mNewNetworkRequest, 9531 event.mOldNetwork, event.mNewNetwork, 9532 now); 9533 } 9534 9535 // Process default network changes if applicable. 9536 processDefaultNetworkChanges(changes); 9537 9538 // Notify requested networks are available after the default net is switched, but 9539 // before LegacyTypeTracker sends legacy broadcasts 9540 for (final NetworkReassignment.RequestReassignment event : 9541 changes.getRequestReassignments()) { 9542 if (null != event.mNewNetwork) { 9543 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo); 9544 } else { 9545 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork, 9546 ConnectivityManager.CALLBACK_LOST, 0); 9547 } 9548 } 9549 9550 // Update the inactivity state before processing listen callbacks, because the background 9551 // computation depends on whether the network is inactive. Don't send the LOSING callbacks 9552 // just yet though, because they have to be sent after the listens are processed to keep 9553 // backward compatibility. 9554 final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>(); 9555 for (final NetworkAgentInfo nai : nais) { 9556 // Rematching may have altered the inactivity state of some networks, so update all 9557 // inactivity timers. updateInactivityState reads the state from the network agent 9558 // and does nothing if the state has not changed : the source of truth is controlled 9559 // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which 9560 // have been called while rematching the individual networks above. 9561 if (updateInactivityState(nai, now)) { 9562 inactiveNetworks.add(nai); 9563 } 9564 } 9565 9566 for (final NetworkAgentInfo nai : nais) { 9567 final boolean oldBackground = oldBgNetworks.contains(nai); 9568 // Process listen requests and update capabilities if the background state has 9569 // changed for this network. For consistency with previous behavior, send onLost 9570 // callbacks before onAvailable. 9571 processNewlyLostListenRequests(nai); 9572 if (oldBackground != nai.isBackgroundNetwork()) { 9573 applyBackgroundChangeForRematch(nai); 9574 } 9575 processNewlySatisfiedListenRequests(nai); 9576 } 9577 9578 for (final NetworkAgentInfo nai : inactiveNetworks) { 9579 // For nascent networks, if connecting with no foreground request, skip broadcasting 9580 // LOSING for backward compatibility. This is typical when mobile data connected while 9581 // wifi connected with mobile data always-on enabled. 9582 if (nai.isNascent()) continue; 9583 notifyNetworkLosing(nai, now); 9584 } 9585 9586 updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais); 9587 9588 // Tear down all unneeded networks. 9589 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 9590 if (unneeded(nai, UnneededFor.TEARDOWN)) { 9591 if (nai.getInactivityExpiry() > 0) { 9592 // This network has active linger timers and no requests, but is not 9593 // lingering. Linger it. 9594 // 9595 // One way (the only way?) this can happen if this network is unvalidated 9596 // and became unneeded due to another network improving its score to the 9597 // point where this network will no longer be able to satisfy any requests 9598 // even if it validates. 9599 if (updateInactivityState(nai, now)) { 9600 notifyNetworkLosing(nai, now); 9601 } 9602 } else { 9603 if (DBG) log("Reaping " + nai.toShortString()); 9604 teardownUnneededNetwork(nai); 9605 } 9606 } 9607 } 9608 } 9609 9610 /** 9611 * Apply a change in background state resulting from rematching networks with requests. 9612 * 9613 * During rematch, a network may change background states by starting to satisfy or stopping 9614 * to satisfy a foreground request. Listens don't count for this. When a network changes 9615 * background states, its capabilities need to be updated and callbacks fired for the 9616 * capability change. 9617 * 9618 * @param nai The network that changed background states 9619 */ 9620 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) { 9621 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities); 9622 if (Objects.equals(nai.networkCapabilities, newNc)) return; 9623 updateNetworkPermissions(nai, newNc); 9624 nai.getAndSetNetworkCapabilities(newNc); 9625 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 9626 } 9627 9628 private void updateLegacyTypeTrackerAndVpnLockdownForRematch( 9629 @NonNull final NetworkReassignment changes, 9630 @NonNull final Collection<NetworkAgentInfo> nais) { 9631 final NetworkReassignment.RequestReassignment reassignmentOfDefault = 9632 changes.getReassignment(mDefaultRequest); 9633 final NetworkAgentInfo oldDefaultNetwork = 9634 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null; 9635 final NetworkAgentInfo newDefaultNetwork = 9636 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null; 9637 9638 if (oldDefaultNetwork != newDefaultNetwork) { 9639 // Maintain the illusion : since the legacy API only understands one network at a time, 9640 // if the default network changed, apps should see a disconnected broadcast for the 9641 // old default network before they see a connected broadcast for the new one. 9642 if (oldDefaultNetwork != null) { 9643 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 9644 oldDefaultNetwork, true); 9645 } 9646 if (newDefaultNetwork != null) { 9647 // The new default network can be newly null if and only if the old default 9648 // network doesn't satisfy the default request any more because it lost a 9649 // capability. 9650 mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0; 9651 mLegacyTypeTracker.add( 9652 newDefaultNetwork.networkInfo.getType(), newDefaultNetwork); 9653 } 9654 } 9655 9656 // Now that all the callbacks have been sent, send the legacy network broadcasts 9657 // as needed. This is necessary so that legacy requests correctly bind dns 9658 // requests to this network. The legacy users are listening for this broadcast 9659 // and will generally do a dns request so they can ensureRouteToHost and if 9660 // they do that before the callbacks happen they'll use the default network. 9661 // 9662 // TODO: Is there still a race here? The legacy broadcast will be sent after sending 9663 // callbacks, but if apps can receive the broadcast before the callback, they still might 9664 // have an inconsistent view of networking. 9665 // 9666 // This *does* introduce a race where if the user uses the new api 9667 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 9668 // they may get old info. Reverse this after the old startUsing api is removed. 9669 // This is on top of the multiple intent sequencing referenced in the todo above. 9670 for (NetworkAgentInfo nai : nais) { 9671 if (nai.everConnected()) { 9672 addNetworkToLegacyTypeTracker(nai); 9673 } 9674 } 9675 } 9676 9677 private void issueNetworkNeeds() { 9678 ensureRunningOnConnectivityServiceThread(); 9679 for (final NetworkOfferInfo noi : mNetworkOffers) { 9680 issueNetworkNeeds(noi); 9681 } 9682 } 9683 9684 private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) { 9685 ensureRunningOnConnectivityServiceThread(); 9686 for (final NetworkRequestInfo nri : mNetworkRequests.values()) { 9687 informOffer(nri, noi.offer, mNetworkRanker); 9688 } 9689 } 9690 9691 /** 9692 * Inform a NetworkOffer about any new situation of a request. 9693 * 9694 * This function handles updates to offers. A number of events may happen that require 9695 * updating the registrant for this offer about the situation : 9696 * • The offer itself was updated. This may lead the offer to no longer being able 9697 * to satisfy a request or beat a satisfier (and therefore be no longer needed), 9698 * or conversely being strengthened enough to beat the satisfier (and therefore 9699 * start being needed) 9700 * • The network satisfying a request changed (including cases where the request 9701 * starts or stops being satisfied). The new network may be a stronger or weaker 9702 * match than the old one, possibly affecting whether the offer is needed. 9703 * • The network satisfying a request updated their score. This may lead the offer 9704 * to no longer be able to beat it if the current satisfier got better, or 9705 * conversely start being a good choice if the current satisfier got weaker. 9706 * 9707 * @param nri The request 9708 * @param offer The offer. This may be an updated offer. 9709 */ 9710 private static void informOffer(@NonNull NetworkRequestInfo nri, 9711 @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) { 9712 final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null; 9713 final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null; 9714 9715 // Multi-layer requests have a currently active request, the one being satisfied. 9716 // Since the system will try to bring up a better network than is currently satisfying 9717 // the request, NetworkProviders need to be told the offers matching the requests *above* 9718 // the currently satisfied one are needed, that the ones *below* the satisfied one are 9719 // not needed, and the offer is needed for the active request iff the offer can beat 9720 // the satisfier. 9721 // For non-multilayer requests, the logic above gracefully degenerates to only the 9722 // last case. 9723 // To achieve this, the loop below will proceed in three steps. In a first phase, inform 9724 // providers that the offer is needed for this request, until the active request is found. 9725 // In a second phase, deal with the currently active request. In a third phase, inform 9726 // the providers that offer is unneeded for the remaining requests. 9727 9728 // First phase : inform providers of all requests above the active request. 9729 int i; 9730 for (i = 0; nri.mRequests.size() > i; ++i) { 9731 final NetworkRequest request = nri.mRequests.get(i); 9732 if (activeRequest == request) break; // Found the active request : go to phase 2 9733 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 9734 // Since this request is higher-priority than the one currently satisfied, if the 9735 // offer can satisfy it, the provider should try and bring up the network for sure ; 9736 // no need to even ask the ranker – an offer that can satisfy is always better than 9737 // no network. Hence tell the provider so unless it already knew. 9738 if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) { 9739 offer.onNetworkNeeded(request); 9740 } 9741 } 9742 9743 // Second phase : deal with the active request (if any) 9744 if (null != activeRequest && activeRequest.isRequest()) { 9745 final boolean oldNeeded = offer.neededFor(activeRequest); 9746 // If an offer can satisfy the request, it is considered needed if it is currently 9747 // served by this provider or if this offer can beat the current satisfier. 9748 final boolean currentlyServing = satisfier != null 9749 && satisfier.factorySerialNumber == offer.providerId 9750 && activeRequest.canBeSatisfiedBy(offer.caps); 9751 final boolean newNeeded = currentlyServing 9752 || networkRanker.mightBeat(activeRequest, satisfier, offer); 9753 if (newNeeded != oldNeeded) { 9754 if (newNeeded) { 9755 offer.onNetworkNeeded(activeRequest); 9756 } else { 9757 // The offer used to be able to beat the satisfier. Now it can't. 9758 offer.onNetworkUnneeded(activeRequest); 9759 } 9760 } 9761 } 9762 9763 // Third phase : inform the providers that the offer isn't needed for any request 9764 // below the active one. 9765 for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) { 9766 final NetworkRequest request = nri.mRequests.get(i); 9767 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers 9768 // Since this request is lower-priority than the one currently satisfied, if the 9769 // offer can satisfy it, the provider should not try and bring up the network. 9770 // Hence tell the provider so unless it already knew. 9771 if (offer.neededFor(request)) { 9772 offer.onNetworkUnneeded(request); 9773 } 9774 } 9775 } 9776 9777 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) { 9778 for (int i = 0; i < nai.numNetworkRequests(); i++) { 9779 NetworkRequest nr = nai.requestAt(i); 9780 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 9781 // legacy type tracker filters out repeat adds 9782 mLegacyTypeTracker.add(nr.legacyType, nai); 9783 } 9784 } 9785 9786 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 9787 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 9788 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 9789 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 9790 if (nai.isVPN()) { 9791 mLegacyTypeTracker.add(TYPE_VPN, nai); 9792 } 9793 } 9794 9795 private void updateInetCondition(NetworkAgentInfo nai) { 9796 // Don't bother updating until we've graduated to validated at least once. 9797 if (!nai.everValidated()) return; 9798 // For now only update icons for the default connection. 9799 // TODO: Update WiFi and cellular icons separately. b/17237507 9800 if (!isDefaultNetwork(nai)) return; 9801 9802 int newInetCondition = nai.isValidated() ? 100 : 0; 9803 // Don't repeat publish. 9804 if (newInetCondition == mDefaultInetConditionPublished) return; 9805 9806 mDefaultInetConditionPublished = newInetCondition; 9807 sendInetConditionBroadcast(nai.networkInfo); 9808 } 9809 9810 @NonNull 9811 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) { 9812 final NetworkInfo newInfo = new NetworkInfo(info); 9813 // The suspended and roaming bits are managed in NetworkCapabilities. 9814 final boolean suspended = 9815 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); 9816 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) { 9817 // Only override the state with SUSPENDED if the network is currently in CONNECTED 9818 // state. This is because the network could have been suspended before connecting, 9819 // or it could be disconnecting while being suspended, and in both these cases 9820 // the state should not be overridden. Note that the only detailed state that 9821 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to 9822 // worry about multiple different substates of CONNECTED. 9823 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(), 9824 info.getExtraInfo()); 9825 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) { 9826 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the 9827 // network agent is created, then goes to suspended, then goes out of suspended without 9828 // ever setting connected. Check if network agent is ever connected to update the state. 9829 newInfo.setDetailedState(nai.everConnected() 9830 ? NetworkInfo.DetailedState.CONNECTED 9831 : NetworkInfo.DetailedState.CONNECTING, 9832 info.getReason(), 9833 info.getExtraInfo()); 9834 } 9835 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 9836 return newInfo; 9837 } 9838 9839 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) { 9840 final NetworkInfo newInfo = mixInInfo(networkAgent, info); 9841 9842 final NetworkInfo.State state = newInfo.getState(); 9843 NetworkInfo oldInfo = null; 9844 synchronized (networkAgent) { 9845 oldInfo = networkAgent.networkInfo; 9846 networkAgent.networkInfo = newInfo; 9847 } 9848 9849 if (DBG) { 9850 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from " 9851 + oldInfo.getState() + " to " + state); 9852 } 9853 9854 if (shouldCreateNativeNetwork(networkAgent, state)) { 9855 // A network that has just connected has zero requests and is thus a foreground network. 9856 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 9857 9858 if (!createNativeNetwork(networkAgent)) return; 9859 9860 networkAgent.setCreated(); 9861 9862 // If the network is created immediately on register, then apply the LinkProperties now. 9863 // Otherwise, this is done further down when the network goes into connected state. 9864 // Applying the LinkProperties means that the network is ready to carry traffic - 9865 // interfaces and routing rules have been added, DNS servers programmed, etc. 9866 // For VPNs, this must be done before the capabilities are updated, because as soon as 9867 // that happens, UIDs are routed to the network. 9868 if (shouldCreateNetworksImmediately()) { 9869 applyInitialLinkProperties(networkAgent); 9870 } 9871 9872 // TODO: should this move earlier? It doesn't seem to have anything to do with whether 9873 // a network is created or not. 9874 if (networkAgent.propagateUnderlyingCapabilities()) { 9875 // Initialize the network's capabilities to their starting values according to the 9876 // underlying networks. This ensures that the capabilities are correct before 9877 // anything happens to the network. 9878 updateCapabilitiesForNetwork(networkAgent); 9879 } 9880 networkAgent.onNetworkCreated(); 9881 updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities); 9882 updateProfileAllowedNetworks(); 9883 } 9884 9885 if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) { 9886 networkAgent.setConnected(); 9887 9888 // NetworkCapabilities need to be set before sending the private DNS config to 9889 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required. 9890 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities); 9891 9892 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 9893 if (!shouldCreateNetworksImmediately()) { 9894 applyInitialLinkProperties(networkAgent); 9895 } else { 9896 // The network was created when the agent registered, and the LinkProperties are 9897 // already up-to-date. However, updateLinkProperties also makes some changes only 9898 // when the network connects. Apply those changes here. On T and below these are 9899 // handled by the applyInitialLinkProperties call just above. 9900 // TODO: stop relying on updateLinkProperties(..., null) to do this. 9901 // If something depends on both LinkProperties and connected state, it should be in 9902 // this method as well. 9903 networkAgent.clatd.update(); 9904 updateProxy(networkAgent.linkProperties, null); 9905 } 9906 9907 // If a rate limit has been configured and is applicable to this network (network 9908 // provides internet connectivity), apply it. The tc police filter cannot be attached 9909 // before the clsact qdisc is added which happens as part of updateLinkProperties -> 9910 // updateInterfaces -> INetd#networkAddInterface. 9911 // Note: in case of a system server crash, the NetworkController constructor in netd 9912 // (called when netd starts up) deletes the clsact qdisc of all interfaces. 9913 if (canNetworkBeRateLimited(networkAgent) && mIngressRateLimit >= 0) { 9914 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 9915 mIngressRateLimit); 9916 } 9917 9918 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect 9919 // command must be sent after updating LinkProperties to maximize chances of 9920 // NetworkMonitor seeing the correct LinkProperties when starting. 9921 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call. 9922 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) { 9923 networkAgent.networkMonitor().setAcceptPartialConnectivity(); 9924 } 9925 final NetworkMonitorParameters params = new NetworkMonitorParameters(); 9926 params.networkAgentConfig = networkAgent.networkAgentConfig; 9927 params.networkCapabilities = networkAgent.networkCapabilities; 9928 params.linkProperties = new LinkProperties(networkAgent.linkProperties, 9929 true /* parcelSensitiveFields */); 9930 // isAtLeastT() is conservative here, as recent versions of NetworkStack support the 9931 // newer callback even before T. However getInterfaceVersion is a synchronized binder 9932 // call that would cause a Log.wtf to be emitted from the system_server process, and 9933 // in the absence of a satisfactory, scalable solution which follows an easy/standard 9934 // process to check the interface version, just use an SDK check. NetworkStack will 9935 // always be new enough when running on T+. 9936 if (mDeps.isAtLeastT()) { 9937 networkAgent.networkMonitor().notifyNetworkConnected(params); 9938 } else { 9939 networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties, 9940 params.networkCapabilities); 9941 } 9942 final long evaluationDelay; 9943 if (!networkAgent.networkCapabilities.hasSingleTransport(TRANSPORT_WIFI)) { 9944 // If the network is anything other than pure wifi, use the default timeout. 9945 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 9946 } else if (networkAgent.networkAgentConfig.isExplicitlySelected()) { 9947 // If the network is explicitly selected, use the default timeout because it's 9948 // shorter and the user is likely staring at the screen expecting it to validate 9949 // right away. 9950 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 9951 } else if (avoidBadWifi() || !activelyPreferBadWifi()) { 9952 // If avoiding bad wifi, or if not avoiding but also not preferring bad wifi 9953 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS; 9954 } else { 9955 // It's wifi, automatically connected, and bad wifi is preferred : use the 9956 // longer timeout to avoid the device switching to captive portals with bad 9957 // signal or very slow response. 9958 evaluationDelay = ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS; 9959 } 9960 scheduleEvaluationTimeout(networkAgent.network, evaluationDelay); 9961 9962 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 9963 // be communicated to a particular NetworkAgent depends only on the network's immutable, 9964 // capabilities, so it only needs to be done once on initial connect, not every time the 9965 // network's capabilities change. Note that we do this before rematching the network, 9966 // so we could decide to tear it down immediately afterwards. That's fine though - on 9967 // disconnection NetworkAgents should stop any signal strength monitoring they have been 9968 // doing. 9969 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 9970 9971 // Before first rematching networks, put an inactivity timer without any request, this 9972 // allows {@code updateInactivityState} to update the state accordingly and prevent 9973 // tearing down for any {@code unneeded} evaluation in this period. 9974 // Note that the timer will not be rescheduled since the expiry time is 9975 // fixed after connection regardless of the network satisfying other requests or not. 9976 // But it will be removed as soon as the network satisfies a request for the first time. 9977 networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE, 9978 SystemClock.elapsedRealtime(), mNascentDelayMs); 9979 networkAgent.setInactive(); 9980 9981 // Consider network even though it is not yet validated. 9982 rematchAllNetworksAndRequests(); 9983 9984 // This has to happen after matching the requests, because callbacks are just requests. 9985 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 9986 } else if (state == NetworkInfo.State.DISCONNECTED) { 9987 networkAgent.disconnect(); 9988 if (networkAgent.isVPN()) { 9989 updateVpnUids(networkAgent, networkAgent.networkCapabilities, null); 9990 } 9991 disconnectAndDestroyNetwork(networkAgent); 9992 if (networkAgent.isVPN()) { 9993 // As the active or bound network changes for apps, broadcast the default proxy, as 9994 // apps may need to update their proxy data. This is called after disconnecting from 9995 // VPN to make sure we do not broadcast the old proxy data. 9996 // TODO(b/122649188): send the broadcast only to VPN users. 9997 mProxyTracker.sendProxyBroadcast(); 9998 } 9999 } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED 10000 || state == NetworkInfo.State.SUSPENDED)) { 10001 mLegacyTypeTracker.update(networkAgent); 10002 } 10003 } 10004 10005 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { 10006 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); 10007 nai.setScore(score); 10008 rematchAllNetworksAndRequests(); 10009 } 10010 10011 // Notify only this one new request of the current state. Transfer all the 10012 // current state by calling NetworkCapabilities and LinkProperties callbacks 10013 // so that callers can be guaranteed to have as close to atomicity in state 10014 // transfer as can be supported by this current API. 10015 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 10016 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 10017 if (nri.mPendingIntent != null) { 10018 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE); 10019 // Attempt no subsequent state pushes where intents are involved. 10020 return; 10021 } 10022 10023 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 10024 final boolean metered = nai.networkCapabilities.isMetered(); 10025 final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges); 10026 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 10027 getBlockedState(blockedReasons, metered, vpnBlocked)); 10028 } 10029 10030 // Notify the requests on this NAI that the network is now lingered. 10031 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) { 10032 final int lingerTime = (int) (nai.getInactivityExpiry() - now); 10033 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 10034 } 10035 10036 private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) { 10037 if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK; 10038 return vpnBlocked 10039 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN 10040 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN; 10041 } 10042 10043 private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) { 10044 if (blockedReasons == BLOCKED_REASON_NONE) { 10045 mUidBlockedReasons.delete(uid); 10046 } else { 10047 mUidBlockedReasons.put(uid, blockedReasons); 10048 } 10049 } 10050 10051 /** 10052 * Notify of the blocked state apps with a registered callback matching a given NAI. 10053 * 10054 * Unlike other callbacks, blocked status is different between each individual uid. So for 10055 * any given nai, all requests need to be considered according to the uid who filed it. 10056 * 10057 * @param nai The target NetworkAgentInfo. 10058 * @param oldMetered True if the previous network capabilities were metered. 10059 * @param newMetered True if the current network capabilities are metered. 10060 * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN. 10061 * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN. 10062 */ 10063 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, 10064 boolean newMetered, List<UidRange> oldBlockedUidRanges, 10065 List<UidRange> newBlockedUidRanges) { 10066 10067 for (int i = 0; i < nai.numNetworkRequests(); i++) { 10068 NetworkRequest nr = nai.requestAt(i); 10069 NetworkRequestInfo nri = mNetworkRequests.get(nr); 10070 10071 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); 10072 final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges); 10073 final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges) 10074 ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges) 10075 : oldVpnBlocked; 10076 10077 final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked); 10078 final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked); 10079 if (oldBlockedState != newBlockedState) { 10080 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 10081 newBlockedState); 10082 } 10083 } 10084 } 10085 10086 /** 10087 * Notify apps with a given UID of the new blocked state according to new uid state. 10088 * @param uid The uid for which the rules changed. 10089 * @param blockedReasons The reasons for why an uid is blocked. 10090 */ 10091 private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) { 10092 for (final NetworkAgentInfo nai : mNetworkAgentInfos) { 10093 final boolean metered = nai.networkCapabilities.isMetered(); 10094 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); 10095 10096 final int oldBlockedState = getBlockedState( 10097 mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked); 10098 final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked); 10099 if (oldBlockedState == newBlockedState) { 10100 continue; 10101 } 10102 for (int i = 0; i < nai.numNetworkRequests(); i++) { 10103 NetworkRequest nr = nai.requestAt(i); 10104 NetworkRequestInfo nri = mNetworkRequests.get(nr); 10105 if (nri != null && nri.mAsUid == uid) { 10106 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, 10107 newBlockedState); 10108 } 10109 } 10110 } 10111 } 10112 10113 @VisibleForTesting 10114 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 10115 // The NetworkInfo we actually send out has no bearing on the real 10116 // state of affairs. For example, if the default connection is mobile, 10117 // and a request for HIPRI has just gone away, we need to pretend that 10118 // HIPRI has just disconnected. So we need to set the type to HIPRI and 10119 // the state to DISCONNECTED, even though the network is of type MOBILE 10120 // and is still connected. 10121 NetworkInfo info = new NetworkInfo(nai.networkInfo); 10122 info.setType(type); 10123 filterForLegacyLockdown(info); 10124 if (state != DetailedState.DISCONNECTED) { 10125 info.setDetailedState(state, null, info.getExtraInfo()); 10126 sendConnectedBroadcast(info); 10127 } else { 10128 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 10129 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 10130 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 10131 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 10132 if (info.isFailover()) { 10133 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 10134 nai.networkInfo.setFailover(false); 10135 } 10136 if (info.getReason() != null) { 10137 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 10138 } 10139 if (info.getExtraInfo() != null) { 10140 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 10141 } 10142 NetworkAgentInfo newDefaultAgent = null; 10143 if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { 10144 newDefaultAgent = mDefaultRequest.getSatisfier(); 10145 if (newDefaultAgent != null) { 10146 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 10147 newDefaultAgent.networkInfo); 10148 } else { 10149 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 10150 } 10151 } 10152 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 10153 mDefaultInetConditionPublished); 10154 sendStickyBroadcast(intent); 10155 if (newDefaultAgent != null) { 10156 sendConnectedBroadcast(newDefaultAgent.networkInfo); 10157 } 10158 } 10159 } 10160 10161 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 10162 if (VDBG || DDBG) { 10163 String notification = ConnectivityManager.getCallbackName(notifyType); 10164 log("notifyType " + notification + " for " + networkAgent.toShortString()); 10165 } 10166 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 10167 NetworkRequest nr = networkAgent.requestAt(i); 10168 NetworkRequestInfo nri = mNetworkRequests.get(nr); 10169 if (VDBG) log(" sending notification for " + nr); 10170 if (nri.mPendingIntent == null) { 10171 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 10172 } else { 10173 sendPendingIntentForRequest(nri, networkAgent, notifyType); 10174 } 10175 } 10176 } 10177 10178 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 10179 notifyNetworkCallbacks(networkAgent, notifyType, 0); 10180 } 10181 10182 /** 10183 * Returns the list of all interfaces that could be used by network traffic that does not 10184 * explicitly specify a network. This includes the default network, but also all VPNs that are 10185 * currently connected. 10186 * 10187 * Must be called on the handler thread. 10188 */ 10189 @NonNull 10190 private ArrayList<Network> getDefaultNetworks() { 10191 ensureRunningOnConnectivityServiceThread(); 10192 final ArrayList<Network> defaultNetworks = new ArrayList<>(); 10193 final Set<Integer> activeNetIds = new ArraySet<>(); 10194 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { 10195 if (nri.isBeingSatisfied()) { 10196 activeNetIds.add(nri.getSatisfier().network().netId); 10197 } 10198 } 10199 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 10200 if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) { 10201 defaultNetworks.add(nai.network); 10202 } 10203 } 10204 return defaultNetworks; 10205 } 10206 10207 /** 10208 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 10209 * active iface's tracked properties has changed. 10210 */ 10211 private void notifyIfacesChangedForNetworkStats() { 10212 ensureRunningOnConnectivityServiceThread(); 10213 String activeIface = null; 10214 LinkProperties activeLinkProperties = getActiveLinkProperties(); 10215 if (activeLinkProperties != null) { 10216 activeIface = activeLinkProperties.getInterfaceName(); 10217 } 10218 10219 final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo(); 10220 try { 10221 final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>(); 10222 snapshots.addAll(getAllNetworkStateSnapshots()); 10223 mStatsManager.notifyNetworkStatus(getDefaultNetworks(), 10224 snapshots, activeIface, Arrays.asList(underlyingNetworkInfos)); 10225 } catch (Exception ignored) { 10226 } 10227 } 10228 10229 @Override 10230 public String getCaptivePortalServerUrl() { 10231 enforceNetworkStackOrSettingsPermission(); 10232 String settingUrl = mResources.get().getString( 10233 R.string.config_networkCaptivePortalServerUrl); 10234 10235 if (!TextUtils.isEmpty(settingUrl)) { 10236 return settingUrl; 10237 } 10238 10239 settingUrl = Settings.Global.getString(mContext.getContentResolver(), 10240 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL); 10241 if (!TextUtils.isEmpty(settingUrl)) { 10242 return settingUrl; 10243 } 10244 10245 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL; 10246 } 10247 10248 @Override 10249 public void startNattKeepalive(Network network, int intervalSeconds, 10250 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { 10251 enforceKeepalivePermission(); 10252 mKeepaliveTracker.startNattKeepalive( 10253 getNetworkAgentInfoForNetwork(network), null /* fd */, 10254 intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT, 10255 // Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to 10256 // false and set the underpinned network to null because there is no way and no 10257 // plan to configure automaticOnOffKeepalives or underpinnedNetwork in this 10258 // deprecated method. 10259 false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */); 10260 } 10261 10262 @Override 10263 public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId, 10264 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, 10265 String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) { 10266 try { 10267 final FileDescriptor fd = pfd.getFileDescriptor(); 10268 mKeepaliveTracker.startNattKeepalive( 10269 getNetworkAgentInfoForNetwork(network), fd, resourceId, 10270 intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT, 10271 automaticOnOffKeepalives, underpinnedNetwork); 10272 } finally { 10273 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 10274 // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately. 10275 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 10276 IoUtils.closeQuietly(pfd); 10277 } 10278 } 10279 } 10280 10281 @Override 10282 public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds, 10283 ISocketKeepaliveCallback cb) { 10284 try { 10285 enforceKeepalivePermission(); 10286 final FileDescriptor fd = pfd.getFileDescriptor(); 10287 mKeepaliveTracker.startTcpKeepalive( 10288 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); 10289 } finally { 10290 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. 10291 // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately. 10292 if (pfd != null && Binder.getCallingPid() != Process.myPid()) { 10293 IoUtils.closeQuietly(pfd); 10294 } 10295 } 10296 } 10297 10298 @Override 10299 public void stopKeepalive(@NonNull final ISocketKeepaliveCallback cb) { 10300 mHandler.sendMessage(mHandler.obtainMessage( 10301 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, 0, SocketKeepalive.SUCCESS, 10302 Objects.requireNonNull(cb).asBinder())); 10303 } 10304 10305 @Override 10306 public int[] getSupportedKeepalives() { 10307 enforceAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS, 10308 // Backwards compatibility with CTS 13 10309 android.Manifest.permission.QUERY_ALL_PACKAGES); 10310 10311 return BinderUtils.withCleanCallingIdentity(() -> 10312 KeepaliveResourceUtil.getSupportedKeepalives(mContext)); 10313 } 10314 10315 @Override 10316 public void factoryReset() { 10317 enforceSettingsPermission(); 10318 10319 final int uid = mDeps.getCallingUid(); 10320 final long token = Binder.clearCallingIdentity(); 10321 try { 10322 if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET, 10323 UserHandle.getUserHandleForUid(uid))) { 10324 return; 10325 } 10326 10327 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext); 10328 ipMemoryStore.factoryReset(); 10329 10330 // Turn airplane mode off 10331 setAirplaneMode(false); 10332 10333 // restore private DNS settings to default mode (opportunistic) 10334 if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, 10335 UserHandle.getUserHandleForUid(uid))) { 10336 ConnectivitySettingsManager.setPrivateDnsMode(mContext, 10337 PRIVATE_DNS_MODE_OPPORTUNISTIC); 10338 } 10339 10340 Settings.Global.putString(mContext.getContentResolver(), 10341 ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 10342 } finally { 10343 Binder.restoreCallingIdentity(token); 10344 } 10345 } 10346 10347 @Override 10348 public byte[] getNetworkWatchlistConfigHash() { 10349 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 10350 if (nwm == null) { 10351 loge("Unable to get NetworkWatchlistManager"); 10352 return null; 10353 } 10354 // Redirect it to network watchlist service to access watchlist file and calculate hash. 10355 return nwm.getWatchlistConfigHash(); 10356 } 10357 10358 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 10359 int[] transports = nai.networkCapabilities.getTransportTypes(); 10360 mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype)); 10361 } 10362 10363 private static boolean toBool(int encodedBoolean) { 10364 return encodedBoolean != 0; // Only 0 means false. 10365 } 10366 10367 private static int encodeBool(boolean b) { 10368 return b ? 1 : 0; 10369 } 10370 10371 @Override 10372 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 10373 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 10374 @NonNull String[] args) { 10375 return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 10376 err.getFileDescriptor(), args); 10377 } 10378 10379 private class ShellCmd extends BasicShellCommandHandler { 10380 @Override 10381 public int onCommand(String cmd) { 10382 if (cmd == null) { 10383 return handleDefaultCommands(cmd); 10384 } 10385 final PrintWriter pw = getOutPrintWriter(); 10386 try { 10387 switch (cmd) { 10388 case "airplane-mode": 10389 // Usage : adb shell cmd connectivity airplane-mode [enable|disable] 10390 // If no argument, get and display the current status 10391 final String action = getNextArg(); 10392 if ("enable".equals(action)) { 10393 setAirplaneMode(true); 10394 return 0; 10395 } else if ("disable".equals(action)) { 10396 setAirplaneMode(false); 10397 return 0; 10398 } else if (action == null) { 10399 final ContentResolver cr = mContext.getContentResolver(); 10400 final int enabled = Settings.Global.getInt(cr, 10401 Settings.Global.AIRPLANE_MODE_ON); 10402 pw.println(enabled == 0 ? "disabled" : "enabled"); 10403 return 0; 10404 } else { 10405 onHelp(); 10406 return -1; 10407 } 10408 case "reevaluate": 10409 // Usage : adb shell cmd connectivity reevaluate <netId> 10410 // If netId is omitted, then reevaluate the default network 10411 final String netId = getNextArg(); 10412 final NetworkAgentInfo nai; 10413 if (null == netId) { 10414 // Note that the command is running on the wrong thread to call this, 10415 // so this could in principle return stale data. But it can't crash. 10416 nai = getDefaultNetwork(); 10417 } else { 10418 // If netId can't be parsed, this throws NumberFormatException, which 10419 // is passed back to adb who prints it. 10420 nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId)); 10421 } 10422 if (null == nai) { 10423 pw.println("Unknown network (net ID not found or no default network)"); 10424 return 0; 10425 } 10426 Log.d(TAG, "Reevaluating network " + nai.network); 10427 reportNetworkConnectivity(nai.network, !nai.isValidated()); 10428 return 0; 10429 default: 10430 return handleDefaultCommands(cmd); 10431 } 10432 } catch (Exception e) { 10433 pw.println(e); 10434 } 10435 return -1; 10436 } 10437 10438 @Override 10439 public void onHelp() { 10440 PrintWriter pw = getOutPrintWriter(); 10441 pw.println("Connectivity service commands:"); 10442 pw.println(" help"); 10443 pw.println(" Print this help text."); 10444 pw.println(" airplane-mode [enable|disable]"); 10445 pw.println(" Turn airplane mode on or off."); 10446 pw.println(" airplane-mode"); 10447 pw.println(" Get airplane mode."); 10448 } 10449 } 10450 10451 private int getVpnType(@Nullable NetworkAgentInfo vpn) { 10452 if (vpn == null) return VpnManager.TYPE_VPN_NONE; 10453 final TransportInfo ti = vpn.networkCapabilities.getTransportInfo(); 10454 if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE; 10455 return ((VpnTransportInfo) ti).getType(); 10456 } 10457 10458 private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai, 10459 @NonNull NetworkCapabilities nc) { 10460 final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo(); 10461 final TransportInfo newInfo = nc.getTransportInfo(); 10462 if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) { 10463 return; 10464 } 10465 if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) { 10466 nai.lastRoamTime = SystemClock.elapsedRealtime(); 10467 } 10468 } 10469 10470 /** 10471 * @param connectionInfo the connection to resolve. 10472 * @return {@code uid} if the connection is found and the app has permission to observe it 10473 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the 10474 * connection is not found. 10475 */ 10476 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { 10477 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { 10478 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); 10479 } 10480 10481 final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol, 10482 connectionInfo.local, connectionInfo.remote); 10483 10484 if (uid == INVALID_UID) return uid; // Not found. 10485 10486 // Connection owner UIDs are visible only to the network stack and to the VpnService-based 10487 // VPN, if any, that applies to the UID that owns the connection. 10488 if (checkNetworkStackPermission()) return uid; 10489 10490 final NetworkAgentInfo vpn = getVpnForUid(uid); 10491 if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE 10492 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) { 10493 return INVALID_UID; 10494 } 10495 10496 return uid; 10497 } 10498 10499 /** 10500 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. 10501 * 10502 * <p>The TestNetworkService must be run in the system server due to TUN creation. 10503 */ 10504 @Override 10505 public IBinder startOrGetTestNetworkService() { 10506 synchronized (mTNSLock) { 10507 TestNetworkService.enforceTestNetworkPermissions(mContext); 10508 10509 if (mTNS == null) { 10510 mTNS = new TestNetworkService(mContext); 10511 } 10512 10513 return mTNS; 10514 } 10515 } 10516 10517 /** 10518 * Handler used for managing all Connectivity Diagnostics related functions. 10519 * 10520 * @see android.net.ConnectivityDiagnosticsManager 10521 * 10522 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file 10523 */ 10524 @VisibleForTesting 10525 class ConnectivityDiagnosticsHandler extends Handler { 10526 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName(); 10527 10528 /** 10529 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link 10530 * android.net.ConnectivityDiagnosticsManager}. 10531 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and 10532 * NetworkRequestInfo to be registered 10533 */ 10534 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1; 10535 10536 /** 10537 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link 10538 * android.net.ConnectivityDiagnosticsManager}. 10539 * obj = the IConnectivityDiagnosticsCallback to be unregistered 10540 * arg1 = the uid of the caller 10541 */ 10542 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2; 10543 10544 /** 10545 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks 10546 * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events. 10547 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from 10548 * NetworkMonitor. 10549 * data = PersistableBundle of extras passed from NetworkMonitor. 10550 */ 10551 private static final int CMD_SEND_CONNECTIVITY_REPORT = 3; 10552 10553 /** 10554 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has 10555 * been detected on the network. 10556 * obj = Long the timestamp (in millis) for when the suspected data stall was detected. 10557 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method. 10558 * arg2 = NetID. 10559 * data = PersistableBundle of extras passed from NetworkMonitor. 10560 */ 10561 private static final int EVENT_DATA_STALL_SUSPECTED = 4; 10562 10563 /** 10564 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to 10565 * the platform. This event will invoke {@link 10566 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned 10567 * callbacks. 10568 * obj = ReportedNetworkConnectivityInfo with info on reported Network connectivity. 10569 */ 10570 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5; 10571 10572 private ConnectivityDiagnosticsHandler(Looper looper) { 10573 super(looper); 10574 } 10575 10576 @Override 10577 public void handleMessage(Message msg) { 10578 switch (msg.what) { 10579 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 10580 handleRegisterConnectivityDiagnosticsCallback( 10581 (ConnectivityDiagnosticsCallbackInfo) msg.obj); 10582 break; 10583 } 10584 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: { 10585 handleUnregisterConnectivityDiagnosticsCallback( 10586 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1); 10587 break; 10588 } 10589 case CMD_SEND_CONNECTIVITY_REPORT: { 10590 final ConnectivityReportEvent reportEvent = 10591 (ConnectivityReportEvent) msg.obj; 10592 10593 handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras); 10594 break; 10595 } 10596 case EVENT_DATA_STALL_SUSPECTED: { 10597 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); 10598 final Pair<Long, PersistableBundle> arg = 10599 (Pair<Long, PersistableBundle>) msg.obj; 10600 if (nai == null) break; 10601 10602 handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second); 10603 break; 10604 } 10605 case EVENT_NETWORK_CONNECTIVITY_REPORTED: { 10606 handleNetworkConnectivityReported((ReportedNetworkConnectivityInfo) msg.obj); 10607 break; 10608 } 10609 default: { 10610 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what); 10611 } 10612 } 10613 } 10614 } 10615 10616 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */ 10617 @VisibleForTesting 10618 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient { 10619 @NonNull private final IConnectivityDiagnosticsCallback mCb; 10620 @NonNull private final NetworkRequestInfo mRequestInfo; 10621 @NonNull private final String mCallingPackageName; 10622 10623 @VisibleForTesting 10624 ConnectivityDiagnosticsCallbackInfo( 10625 @NonNull IConnectivityDiagnosticsCallback cb, 10626 @NonNull NetworkRequestInfo nri, 10627 @NonNull String callingPackageName) { 10628 mCb = cb; 10629 mRequestInfo = nri; 10630 mCallingPackageName = callingPackageName; 10631 } 10632 10633 @Override 10634 public void binderDied() { 10635 log("ConnectivityDiagnosticsCallback IBinder died."); 10636 unregisterConnectivityDiagnosticsCallback(mCb); 10637 } 10638 } 10639 10640 /** 10641 * Class used for sending information from {@link 10642 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it. 10643 */ 10644 private static class NetworkTestedResults { 10645 private final int mNetId; 10646 private final int mTestResult; 10647 @Nullable private final String mRedirectUrl; 10648 10649 private NetworkTestedResults( 10650 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) { 10651 mNetId = netId; 10652 mTestResult = testResult; 10653 mRedirectUrl = redirectUrl; 10654 } 10655 } 10656 10657 /** 10658 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link 10659 * ConnectivityDiagnosticsHandler}. 10660 */ 10661 private static class ConnectivityReportEvent { 10662 private final long mTimestampMillis; 10663 @NonNull private final NetworkAgentInfo mNai; 10664 private final PersistableBundle mExtras; 10665 10666 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai, 10667 PersistableBundle p) { 10668 mTimestampMillis = timestampMillis; 10669 mNai = nai; 10670 mExtras = p; 10671 } 10672 } 10673 10674 /** 10675 * Class used for sending info for a call to {@link #reportNetworkConnectivity()} to {@link 10676 * ConnectivityDiagnosticsHandler}. 10677 */ 10678 private static class ReportedNetworkConnectivityInfo { 10679 public final boolean hasConnectivity; 10680 public final boolean isNetworkRevalidating; 10681 public final int reporterUid; 10682 @NonNull public final NetworkAgentInfo nai; 10683 10684 private ReportedNetworkConnectivityInfo( 10685 boolean hasConnectivity, 10686 boolean isNetworkRevalidating, 10687 int reporterUid, 10688 @NonNull NetworkAgentInfo nai) { 10689 this.hasConnectivity = hasConnectivity; 10690 this.isNetworkRevalidating = isNetworkRevalidating; 10691 this.reporterUid = reporterUid; 10692 this.nai = nai; 10693 } 10694 } 10695 10696 private void handleRegisterConnectivityDiagnosticsCallback( 10697 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) { 10698 ensureRunningOnConnectivityServiceThread(); 10699 10700 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb; 10701 final IBinder iCb = cb.asBinder(); 10702 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 10703 10704 // Connectivity Diagnostics are meant to be used with a single network request. It would be 10705 // confusing for these networks to change when an NRI is satisfied in another layer. 10706 if (nri.isMultilayerRequest()) { 10707 throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer " 10708 + "network requests."); 10709 } 10710 10711 // This means that the client registered the same callback multiple times. Do 10712 // not override the previous entry, and exit silently. 10713 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) { 10714 if (VDBG) log("Diagnostics callback is already registered"); 10715 10716 // Decrement the reference count for this NetworkRequestInfo. The reference count is 10717 // incremented when the NetworkRequestInfo is created as part of 10718 // enforceRequestCountLimit(). 10719 nri.mPerUidCounter.decrementCount(nri.mUid); 10720 return; 10721 } 10722 10723 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo); 10724 10725 try { 10726 iCb.linkToDeath(cbInfo, 0); 10727 } catch (RemoteException e) { 10728 cbInfo.binderDied(); 10729 return; 10730 } 10731 10732 // Once registered, provide ConnectivityReports for matching Networks 10733 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>(); 10734 synchronized (mNetworkForNetId) { 10735 for (int i = 0; i < mNetworkForNetId.size(); i++) { 10736 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i); 10737 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0) 10738 if (nai.satisfies(nri.mRequests.get(0))) { 10739 matchingNetworks.add(nai); 10740 } 10741 } 10742 } 10743 for (final NetworkAgentInfo nai : matchingNetworks) { 10744 final ConnectivityReport report = nai.getConnectivityReport(); 10745 if (report == null) { 10746 continue; 10747 } 10748 if (!checkConnectivityDiagnosticsPermissions( 10749 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 10750 continue; 10751 } 10752 10753 try { 10754 cb.onConnectivityReportAvailable(report); 10755 } catch (RemoteException e) { 10756 // Exception while sending the ConnectivityReport. Move on to the next network. 10757 } 10758 } 10759 } 10760 10761 private void handleUnregisterConnectivityDiagnosticsCallback( 10762 @NonNull IConnectivityDiagnosticsCallback cb, int uid) { 10763 ensureRunningOnConnectivityServiceThread(); 10764 final IBinder iCb = cb.asBinder(); 10765 10766 final ConnectivityDiagnosticsCallbackInfo cbInfo = 10767 mConnectivityDiagnosticsCallbacks.remove(iCb); 10768 if (cbInfo == null) { 10769 if (VDBG) log("Removing diagnostics callback that is not currently registered"); 10770 return; 10771 } 10772 10773 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 10774 10775 // Caller's UID must either be the registrants (if they are unregistering) or the System's 10776 // (if the Binder died) 10777 if (uid != nri.mUid && uid != Process.SYSTEM_UID) { 10778 if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's"); 10779 return; 10780 } 10781 10782 // Decrement the reference count for this NetworkRequestInfo. The reference count is 10783 // incremented when the NetworkRequestInfo is created as part of 10784 // enforceRequestCountLimit(). 10785 nri.mPerUidCounter.decrementCount(nri.mUid); 10786 10787 iCb.unlinkToDeath(cbInfo, 0); 10788 } 10789 10790 private void handleNetworkTestedWithExtras( 10791 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) { 10792 final NetworkAgentInfo nai = reportEvent.mNai; 10793 final NetworkCapabilities networkCapabilities = 10794 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 10795 final ConnectivityReport report = 10796 new ConnectivityReport( 10797 reportEvent.mNai.network, 10798 reportEvent.mTimestampMillis, 10799 nai.linkProperties, 10800 networkCapabilities, 10801 extras); 10802 nai.setConnectivityReport(report); 10803 10804 final List<IConnectivityDiagnosticsCallback> results = 10805 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 10806 for (final IConnectivityDiagnosticsCallback cb : results) { 10807 try { 10808 cb.onConnectivityReportAvailable(report); 10809 } catch (RemoteException ex) { 10810 loge("Error invoking onConnectivityReportAvailable", ex); 10811 } 10812 } 10813 } 10814 10815 private void handleDataStallSuspected( 10816 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, 10817 @NonNull PersistableBundle extras) { 10818 final NetworkCapabilities networkCapabilities = 10819 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities); 10820 final DataStallReport report = 10821 new DataStallReport( 10822 nai.network, 10823 timestampMillis, 10824 detectionMethod, 10825 nai.linkProperties, 10826 networkCapabilities, 10827 extras); 10828 final List<IConnectivityDiagnosticsCallback> results = 10829 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID); 10830 for (final IConnectivityDiagnosticsCallback cb : results) { 10831 try { 10832 cb.onDataStallSuspected(report); 10833 } catch (RemoteException ex) { 10834 loge("Error invoking onDataStallSuspected", ex); 10835 } 10836 } 10837 } 10838 10839 private void handleNetworkConnectivityReported( 10840 @NonNull ReportedNetworkConnectivityInfo reportedNetworkConnectivityInfo) { 10841 final NetworkAgentInfo nai = reportedNetworkConnectivityInfo.nai; 10842 final ConnectivityReport cachedReport = nai.getConnectivityReport(); 10843 10844 // If the Network is being re-validated as a result of this call to 10845 // reportNetworkConnectivity(), notify all permissioned callbacks. Otherwise, only notify 10846 // permissioned callbacks registered by the reporter. 10847 final List<IConnectivityDiagnosticsCallback> results = 10848 getMatchingPermissionedCallbacks( 10849 nai, 10850 reportedNetworkConnectivityInfo.isNetworkRevalidating 10851 ? Process.INVALID_UID 10852 : reportedNetworkConnectivityInfo.reporterUid); 10853 10854 for (final IConnectivityDiagnosticsCallback cb : results) { 10855 try { 10856 cb.onNetworkConnectivityReported( 10857 nai.network, reportedNetworkConnectivityInfo.hasConnectivity); 10858 } catch (RemoteException ex) { 10859 loge("Error invoking onNetworkConnectivityReported", ex); 10860 } 10861 10862 // If the Network isn't re-validating, also provide the cached report. If there is no 10863 // cached report, the Network is still being validated and a report will be sent once 10864 // validation is complete. Note that networks which never undergo validation will still 10865 // have a cached ConnectivityReport with RESULT_SKIPPED. 10866 if (!reportedNetworkConnectivityInfo.isNetworkRevalidating && cachedReport != null) { 10867 try { 10868 cb.onConnectivityReportAvailable(cachedReport); 10869 } catch (RemoteException ex) { 10870 loge("Error invoking onConnectivityReportAvailable", ex); 10871 } 10872 } 10873 } 10874 } 10875 10876 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) { 10877 final NetworkCapabilities sanitized = new NetworkCapabilities(nc, 10878 NetworkCapabilities.REDACT_ALL); 10879 sanitized.setUids(null); 10880 sanitized.setAdministratorUids(new int[0]); 10881 sanitized.setOwnerUid(Process.INVALID_UID); 10882 return sanitized; 10883 } 10884 10885 /** 10886 * Gets a list of ConnectivityDiagnostics callbacks that match the specified Network and uid. 10887 * 10888 * <p>If Process.INVALID_UID is specified, all matching callbacks will be returned. 10889 */ 10890 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks( 10891 @NonNull NetworkAgentInfo nai, int uid) { 10892 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); 10893 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry : 10894 mConnectivityDiagnosticsCallbacks.entrySet()) { 10895 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue(); 10896 final NetworkRequestInfo nri = cbInfo.mRequestInfo; 10897 10898 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0). 10899 if (!nai.satisfies(nri.mRequests.get(0))) { 10900 continue; 10901 } 10902 10903 // UID for this callback must either be: 10904 // - INVALID_UID (which sends callbacks to all UIDs), or 10905 // - The callback's owner (the owner called reportNetworkConnectivity() and is being 10906 // notified as a result) 10907 if (uid != Process.INVALID_UID && uid != nri.mUid) { 10908 continue; 10909 } 10910 10911 if (!checkConnectivityDiagnosticsPermissions( 10912 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) { 10913 continue; 10914 } 10915 10916 results.add(entry.getValue().mCb); 10917 } 10918 return results; 10919 } 10920 10921 private boolean isLocationPermissionRequiredForConnectivityDiagnostics( 10922 @NonNull NetworkAgentInfo nai) { 10923 // TODO(b/188483916): replace with a transport-agnostic location-aware check 10924 return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI); 10925 } 10926 10927 private boolean hasLocationPermission(String packageName, int uid) { 10928 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid 10929 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the 10930 // call in a try-catch. 10931 try { 10932 if (!mLocationPermissionChecker.checkLocationPermission( 10933 packageName, null /* featureId */, uid, null /* message */)) { 10934 return false; 10935 } 10936 } catch (SecurityException e) { 10937 return false; 10938 } 10939 10940 return true; 10941 } 10942 10943 private boolean ownsVpnRunningOverNetwork(int uid, Network network) { 10944 for (NetworkAgentInfo virtual : mNetworkAgentInfos) { 10945 if (virtual.propagateUnderlyingCapabilities() 10946 && virtual.networkCapabilities.getOwnerUid() == uid 10947 && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) { 10948 return true; 10949 } 10950 } 10951 10952 return false; 10953 } 10954 10955 @VisibleForTesting 10956 boolean checkConnectivityDiagnosticsPermissions( 10957 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) { 10958 if (checkNetworkStackPermission(callbackPid, callbackUid)) { 10959 return true; 10960 } 10961 10962 // Administrator UIDs also contains the Owner UID 10963 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); 10964 if (!CollectionUtils.contains(administratorUids, callbackUid) 10965 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) { 10966 return false; 10967 } 10968 10969 return !isLocationPermissionRequiredForConnectivityDiagnostics(nai) 10970 || hasLocationPermission(callbackPackageName, callbackUid); 10971 } 10972 10973 @Override 10974 public void registerConnectivityDiagnosticsCallback( 10975 @NonNull IConnectivityDiagnosticsCallback callback, 10976 @NonNull NetworkRequest request, 10977 @NonNull String callingPackageName) { 10978 Objects.requireNonNull(callback, "callback must not be null"); 10979 Objects.requireNonNull(request, "request must not be null"); 10980 Objects.requireNonNull(callingPackageName, "callingPackageName must not be null"); 10981 10982 if (request.legacyType != TYPE_NONE) { 10983 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." 10984 + " Please use NetworkCapabilities instead."); 10985 } 10986 final int callingUid = mDeps.getCallingUid(); 10987 mAppOpsManager.checkPackage(callingUid, callingPackageName); 10988 10989 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid 10990 // and administrator uids to be safe. 10991 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); 10992 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); 10993 10994 final NetworkRequest requestWithId = 10995 new NetworkRequest( 10996 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); 10997 10998 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit. 10999 // 11000 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in 11001 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the 11002 // callback's binder death. 11003 final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId); 11004 final ConnectivityDiagnosticsCallbackInfo cbInfo = 11005 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName); 11006 11007 mConnectivityDiagnosticsHandler.sendMessage( 11008 mConnectivityDiagnosticsHandler.obtainMessage( 11009 ConnectivityDiagnosticsHandler 11010 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 11011 cbInfo)); 11012 } 11013 11014 @Override 11015 public void unregisterConnectivityDiagnosticsCallback( 11016 @NonNull IConnectivityDiagnosticsCallback callback) { 11017 Objects.requireNonNull(callback, "callback must be non-null"); 11018 mConnectivityDiagnosticsHandler.sendMessage( 11019 mConnectivityDiagnosticsHandler.obtainMessage( 11020 ConnectivityDiagnosticsHandler 11021 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK, 11022 mDeps.getCallingUid(), 11023 0, 11024 callback)); 11025 } 11026 11027 private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) { 11028 final List<Network> underlyingNetworks = nc.getUnderlyingNetworks(); 11029 if (underlyingNetworks == null) return false; 11030 11031 for (Network network : underlyingNetworks) { 11032 if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) { 11033 return true; 11034 } 11035 } 11036 return false; 11037 } 11038 11039 @Override 11040 public void simulateDataStall(int detectionMethod, long timestampMillis, 11041 @NonNull Network network, @NonNull PersistableBundle extras) { 11042 Objects.requireNonNull(network, "network must not be null"); 11043 Objects.requireNonNull(extras, "extras must not be null"); 11044 11045 enforceAnyPermissionOf(mContext, 11046 android.Manifest.permission.MANAGE_TEST_NETWORKS, 11047 android.Manifest.permission.NETWORK_STACK); 11048 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); 11049 if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) { 11050 throw new SecurityException( 11051 "Data Stall simulation is only possible for test networks or networks built on" 11052 + " top of test networks"); 11053 } 11054 11055 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 11056 if (nai == null 11057 || (nai.creatorUid != mDeps.getCallingUid() 11058 && nai.creatorUid != Process.SYSTEM_UID)) { 11059 throw new SecurityException( 11060 "Data Stall simulation is only possible for network " + "creators"); 11061 } 11062 11063 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat 11064 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the 11065 // Data Stall information as a DataStallReportParcelable and passing to 11066 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are 11067 // still passed to ConnectivityDiagnostics (with new detection methods masked). 11068 final DataStallReportParcelable p = new DataStallReportParcelable(); 11069 p.timestampMillis = timestampMillis; 11070 p.detectionMethod = detectionMethod; 11071 11072 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) { 11073 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS); 11074 } 11075 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) { 11076 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE); 11077 p.tcpMetricsCollectionPeriodMillis = extras.getInt( 11078 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS); 11079 } 11080 11081 notifyDataStallSuspected(p, network.getNetId()); 11082 } 11083 11084 private class NetdCallback extends BaseNetdUnsolicitedEventListener { 11085 @Override 11086 public void onInterfaceClassActivityChanged(boolean isActive, int transportType, 11087 long timestampNs, int uid) { 11088 mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs); 11089 } 11090 11091 @Override 11092 public void onInterfaceLinkStateChanged(@NonNull String iface, boolean up) { 11093 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 11094 nai.clatd.interfaceLinkStateChanged(iface, up); 11095 } 11096 } 11097 11098 @Override 11099 public void onInterfaceRemoved(@NonNull String iface) { 11100 for (NetworkAgentInfo nai : mNetworkAgentInfos) { 11101 nai.clatd.interfaceRemoved(iface); 11102 } 11103 } 11104 } 11105 11106 private final LegacyNetworkActivityTracker mNetworkActivityTracker; 11107 11108 /** 11109 * Class used for updating network activity tracking with netd and notify network activity 11110 * changes. 11111 */ 11112 private static final class LegacyNetworkActivityTracker { 11113 private static final int NO_UID = -1; 11114 private final Context mContext; 11115 private final INetd mNetd; 11116 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 11117 new RemoteCallbackList<>(); 11118 // Indicate the current system default network activity is active or not. 11119 @GuardedBy("mActiveIdleTimers") 11120 private boolean mNetworkActive; 11121 @GuardedBy("mActiveIdleTimers") 11122 private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap<>(); 11123 private final Handler mHandler; 11124 11125 private static class IdleTimerParams { 11126 public final int timeout; 11127 public final int transportType; 11128 11129 IdleTimerParams(int timeout, int transport) { 11130 this.timeout = timeout; 11131 this.transportType = transport; 11132 } 11133 } 11134 11135 LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler, 11136 @NonNull INetd netd) { 11137 mContext = context; 11138 mNetd = netd; 11139 mHandler = handler; 11140 } 11141 11142 public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) { 11143 sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos); 11144 synchronized (mActiveIdleTimers) { 11145 mNetworkActive = active; 11146 // If there are no idle timers, it means that system is not monitoring 11147 // activity, so the system default network for those default network 11148 // unspecified apps is always considered active. 11149 // 11150 // TODO: If the mActiveIdleTimers is empty, netd will actually not send 11151 // any network activity change event. Whenever this event is received, 11152 // the mActiveIdleTimers should be always not empty. The legacy behavior 11153 // is no-op. Remove to refer to mNetworkActive only. 11154 if (mNetworkActive || mActiveIdleTimers.isEmpty()) { 11155 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY)); 11156 } 11157 } 11158 } 11159 11160 // The network activity should only be updated from ConnectivityService handler thread 11161 // when mActiveIdleTimers lock is held. 11162 @GuardedBy("mActiveIdleTimers") 11163 private void reportNetworkActive() { 11164 final int length = mNetworkActivityListeners.beginBroadcast(); 11165 if (DDBG) log("reportNetworkActive, notify " + length + " listeners"); 11166 try { 11167 for (int i = 0; i < length; i++) { 11168 try { 11169 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 11170 } catch (RemoteException | RuntimeException e) { 11171 loge("Fail to send network activity to listener " + e); 11172 } 11173 } 11174 } finally { 11175 mNetworkActivityListeners.finishBroadcast(); 11176 } 11177 } 11178 11179 @GuardedBy("mActiveIdleTimers") 11180 public void handleReportNetworkActivity() { 11181 synchronized (mActiveIdleTimers) { 11182 reportNetworkActive(); 11183 } 11184 } 11185 11186 // This is deprecated and only to support legacy use cases. 11187 private int transportTypeToLegacyType(int type) { 11188 switch (type) { 11189 case NetworkCapabilities.TRANSPORT_CELLULAR: 11190 return TYPE_MOBILE; 11191 case NetworkCapabilities.TRANSPORT_WIFI: 11192 return TYPE_WIFI; 11193 case NetworkCapabilities.TRANSPORT_BLUETOOTH: 11194 return TYPE_BLUETOOTH; 11195 case NetworkCapabilities.TRANSPORT_ETHERNET: 11196 return TYPE_ETHERNET; 11197 default: 11198 loge("Unexpected transport in transportTypeToLegacyType: " + type); 11199 } 11200 return ConnectivityManager.TYPE_NONE; 11201 } 11202 11203 public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 11204 final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 11205 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 11206 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 11207 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 11208 final long ident = Binder.clearCallingIdentity(); 11209 try { 11210 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 11211 RECEIVE_DATA_ACTIVITY_CHANGE, 11212 null /* resultReceiver */, 11213 null /* scheduler */, 11214 0 /* initialCode */, 11215 null /* initialData */, 11216 null /* initialExtra */); 11217 } finally { 11218 Binder.restoreCallingIdentity(ident); 11219 } 11220 } 11221 11222 /** 11223 * Setup data activity tracking for the given network. 11224 * 11225 * Every {@code setupDataActivityTracking} should be paired with a 11226 * {@link #removeDataActivityTracking} for cleanup. 11227 */ 11228 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) { 11229 final String iface = networkAgent.linkProperties.getInterfaceName(); 11230 11231 final int timeout; 11232 final int type; 11233 11234 if (networkAgent.networkCapabilities.hasTransport( 11235 NetworkCapabilities.TRANSPORT_CELLULAR)) { 11236 timeout = Settings.Global.getInt(mContext.getContentResolver(), 11237 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE, 11238 10); 11239 type = NetworkCapabilities.TRANSPORT_CELLULAR; 11240 } else if (networkAgent.networkCapabilities.hasTransport( 11241 NetworkCapabilities.TRANSPORT_WIFI)) { 11242 timeout = Settings.Global.getInt(mContext.getContentResolver(), 11243 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI, 11244 15); 11245 type = NetworkCapabilities.TRANSPORT_WIFI; 11246 } else { 11247 return; // do not track any other networks 11248 } 11249 11250 updateRadioPowerState(true /* isActive */, type); 11251 11252 if (timeout > 0 && iface != null) { 11253 try { 11254 synchronized (mActiveIdleTimers) { 11255 // Networks start up. 11256 mNetworkActive = true; 11257 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type)); 11258 mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type)); 11259 reportNetworkActive(); 11260 } 11261 } catch (Exception e) { 11262 // You shall not crash! 11263 loge("Exception in setupDataActivityTracking " + e); 11264 } 11265 } 11266 } 11267 11268 /** 11269 * Remove data activity tracking when network disconnects. 11270 */ 11271 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 11272 final String iface = networkAgent.linkProperties.getInterfaceName(); 11273 final NetworkCapabilities caps = networkAgent.networkCapabilities; 11274 11275 if (iface == null) return; 11276 11277 final int type; 11278 if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { 11279 type = NetworkCapabilities.TRANSPORT_CELLULAR; 11280 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 11281 type = NetworkCapabilities.TRANSPORT_WIFI; 11282 } else { 11283 return; // do not track any other networks 11284 } 11285 11286 try { 11287 updateRadioPowerState(false /* isActive */, type); 11288 synchronized (mActiveIdleTimers) { 11289 final IdleTimerParams params = mActiveIdleTimers.remove(iface); 11290 // The call fails silently if no idle timer setup for this interface 11291 mNetd.idletimerRemoveInterface(iface, params.timeout, 11292 Integer.toString(params.transportType)); 11293 } 11294 } catch (Exception e) { 11295 // You shall not crash! 11296 loge("Exception in removeDataActivityTracking " + e); 11297 } 11298 } 11299 11300 /** 11301 * Update data activity tracking when network state is updated. 11302 */ 11303 public void updateDataActivityTracking(NetworkAgentInfo newNetwork, 11304 NetworkAgentInfo oldNetwork) { 11305 if (newNetwork != null) { 11306 setupDataActivityTracking(newNetwork); 11307 } 11308 if (oldNetwork != null) { 11309 removeDataActivityTracking(oldNetwork); 11310 } 11311 } 11312 11313 private void updateRadioPowerState(boolean isActive, int transportType) { 11314 final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class); 11315 switch (transportType) { 11316 case NetworkCapabilities.TRANSPORT_CELLULAR: 11317 bs.reportMobileRadioPowerState(isActive, NO_UID); 11318 break; 11319 case NetworkCapabilities.TRANSPORT_WIFI: 11320 bs.reportWifiRadioPowerState(isActive, NO_UID); 11321 break; 11322 default: 11323 logw("Untracked transport type:" + transportType); 11324 } 11325 } 11326 11327 public boolean isDefaultNetworkActive() { 11328 synchronized (mActiveIdleTimers) { 11329 // If there are no idle timers, it means that system is not monitoring activity, 11330 // so the default network is always considered active. 11331 // 11332 // TODO : Distinguish between the cases where mActiveIdleTimers is empty because 11333 // tracking is disabled (negative idle timer value configured), or no active default 11334 // network. In the latter case, this reports active but it should report inactive. 11335 return mNetworkActive || mActiveIdleTimers.isEmpty(); 11336 } 11337 } 11338 11339 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) { 11340 mNetworkActivityListeners.register(l); 11341 } 11342 11343 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) { 11344 mNetworkActivityListeners.unregister(l); 11345 } 11346 11347 public void dump(IndentingPrintWriter pw) { 11348 synchronized (mActiveIdleTimers) { 11349 pw.print("mNetworkActive="); pw.println(mNetworkActive); 11350 pw.println("Idle timers:"); 11351 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) { 11352 pw.print(" "); pw.print(ent.getKey()); pw.println(":"); 11353 final IdleTimerParams params = ent.getValue(); 11354 pw.print(" timeout="); pw.print(params.timeout); 11355 pw.print(" type="); pw.println(params.transportType); 11356 } 11357 } 11358 } 11359 } 11360 11361 /** 11362 * Registers {@link QosSocketFilter} with {@link IQosCallback}. 11363 * 11364 * @param socketInfo the socket information 11365 * @param callback the callback to register 11366 */ 11367 @Override 11368 public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo, 11369 @NonNull final IQosCallback callback) { 11370 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork()); 11371 if (nai == null || nai.networkCapabilities == null) { 11372 try { 11373 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); 11374 } catch (final RemoteException ex) { 11375 loge("registerQosCallbackInternal: RemoteException", ex); 11376 } 11377 return; 11378 } 11379 registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai); 11380 } 11381 11382 /** 11383 * Register a {@link IQosCallback} with base {@link QosFilter}. 11384 * 11385 * @param filter the filter to register 11386 * @param callback the callback to register 11387 * @param nai the agent information related to the filter's network 11388 */ 11389 @VisibleForTesting 11390 public void registerQosCallbackInternal(@NonNull final QosFilter filter, 11391 @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) { 11392 Objects.requireNonNull(filter, "filter must be non-null"); 11393 Objects.requireNonNull(callback, "callback must be non-null"); 11394 11395 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 11396 // TODO: Check allowed list here and ensure that either a) any QoS callback registered 11397 // on this network is unregistered when the app loses permission or b) no QoS 11398 // callbacks are sent for restricted networks unless the app currently has permission 11399 // to access restricted networks. 11400 enforceConnectivityRestrictedNetworksPermission(false /* checkUidsAllowedList */); 11401 } 11402 mQosCallbackTracker.registerCallback(callback, filter, nai); 11403 } 11404 11405 /** 11406 * Unregisters the given callback. 11407 * 11408 * @param callback the callback to unregister 11409 */ 11410 @Override 11411 public void unregisterQosCallback(@NonNull final IQosCallback callback) { 11412 Objects.requireNonNull(callback, "callback must be non-null"); 11413 mQosCallbackTracker.unregisterCallback(callback); 11414 } 11415 11416 private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) { 11417 // UserManager.isManagedProfile returns true for all apps in managed user profiles. 11418 // Enterprise device can be fully managed like device owner and such use case 11419 // also should be supported. Calling app check for work profile and fully managed device 11420 // is already done in DevicePolicyManager. 11421 // This check is an extra caution to be sure device is fully managed or not. 11422 final UserManager um = mContext.getSystemService(UserManager.class); 11423 final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); 11424 if (um.isManagedProfile(profile.getIdentifier())) { 11425 return true; 11426 } 11427 if (mDeps.isAtLeastT() && dpm.getDeviceOwner() != null) return true; 11428 return false; 11429 } 11430 11431 /** 11432 * Set a list of default network selection policies for a user profile or device owner. 11433 * 11434 * See the documentation for the individual preferences for a description of the supported 11435 * behaviors. 11436 * 11437 * @param profile If the device owner is set, any profile is allowed. 11438 Otherwise, the given profile can only be managed profile. 11439 * @param preferences the list of profile network preferences for the 11440 * provided profile. 11441 * @param listener an optional listener to listen for completion of the operation. 11442 */ 11443 @Override 11444 public void setProfileNetworkPreferences( 11445 @NonNull final UserHandle profile, 11446 @NonNull List<ProfileNetworkPreference> preferences, 11447 @Nullable final IOnCompleteListener listener) { 11448 Objects.requireNonNull(preferences); 11449 Objects.requireNonNull(profile); 11450 11451 if (preferences.size() == 0) { 11452 final ProfileNetworkPreference pref = new ProfileNetworkPreference.Builder() 11453 .setPreference(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT) 11454 .build(); 11455 preferences.add(pref); 11456 } 11457 11458 enforceNetworkStackPermission(mContext); 11459 if (DBG) { 11460 log("setProfileNetworkPreferences " + profile + " to " + preferences); 11461 } 11462 if (profile.getIdentifier() < 0) { 11463 throw new IllegalArgumentException("Must explicitly specify a user handle (" 11464 + "UserHandle.CURRENT not supported)"); 11465 } 11466 if (!isNetworkPreferenceAllowedForProfile(profile)) { 11467 throw new IllegalArgumentException("Profile must be a managed profile " 11468 + "or the device owner must be set. "); 11469 } 11470 11471 final List<ProfileNetworkPreferenceInfo> preferenceList = new ArrayList<>(); 11472 boolean hasDefaultPreference = false; 11473 for (final ProfileNetworkPreference preference : preferences) { 11474 final NetworkCapabilities nc; 11475 boolean allowFallback = true; 11476 boolean blockingNonEnterprise = false; 11477 switch (preference.getPreference()) { 11478 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT: 11479 nc = null; 11480 hasDefaultPreference = true; 11481 if (preference.getPreferenceEnterpriseId() != 0) { 11482 throw new IllegalArgumentException( 11483 "Invalid enterprise identifier in setProfileNetworkPreferences"); 11484 } 11485 break; 11486 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING: 11487 blockingNonEnterprise = true; 11488 // continue to process the enterprise preference. 11489 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK: 11490 allowFallback = false; 11491 // continue to process the enterprise preference. 11492 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE: 11493 // This code is needed even though there is a check later on, 11494 // because isRangeAlreadyInPreferenceList assumes that every preference 11495 // has a UID list. 11496 if (hasDefaultPreference) { 11497 throw new IllegalArgumentException( 11498 "Default profile preference should not be set along with other " 11499 + "preference"); 11500 } 11501 if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) { 11502 throw new IllegalArgumentException( 11503 "Invalid enterprise identifier in setProfileNetworkPreferences"); 11504 } 11505 final Set<UidRange> uidRangeSet = 11506 getUidListToBeAppliedForNetworkPreference(profile, preference); 11507 if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) { 11508 nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet); 11509 } else { 11510 throw new IllegalArgumentException( 11511 "Overlapping uid range in setProfileNetworkPreferences"); 11512 } 11513 nc.addCapability(NET_CAPABILITY_ENTERPRISE); 11514 nc.addEnterpriseId( 11515 preference.getPreferenceEnterpriseId()); 11516 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 11517 break; 11518 default: 11519 throw new IllegalArgumentException( 11520 "Invalid preference in setProfileNetworkPreferences"); 11521 } 11522 preferenceList.add(new ProfileNetworkPreferenceInfo( 11523 profile, nc, allowFallback, blockingNonEnterprise)); 11524 if (hasDefaultPreference && preferenceList.size() > 1) { 11525 throw new IllegalArgumentException( 11526 "Default profile preference should not be set along with other preference"); 11527 } 11528 } 11529 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE, 11530 new Pair<>(preferenceList, listener))); 11531 } 11532 11533 private Set<UidRange> getUidListToBeAppliedForNetworkPreference( 11534 @NonNull final UserHandle profile, 11535 @NonNull final ProfileNetworkPreference profileNetworkPreference) { 11536 final UidRange profileUids = UidRange.createForUser(profile); 11537 Set<UidRange> uidRangeSet = UidRangeUtils.convertArrayToUidRange( 11538 profileNetworkPreference.getIncludedUids()); 11539 11540 if (uidRangeSet.size() > 0) { 11541 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) { 11542 throw new IllegalArgumentException( 11543 "Allow uid range is outside the uid range of profile."); 11544 } 11545 } else { 11546 ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertArrayToUidRange( 11547 profileNetworkPreference.getExcludedUids()); 11548 if (disallowUidRangeSet.size() > 0) { 11549 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) { 11550 throw new IllegalArgumentException( 11551 "disallow uid range is outside the uid range of profile."); 11552 } 11553 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids, 11554 disallowUidRangeSet); 11555 } else { 11556 uidRangeSet = new ArraySet<>(); 11557 uidRangeSet.add(profileUids); 11558 } 11559 } 11560 return uidRangeSet; 11561 } 11562 11563 private boolean isEnterpriseIdentifierValid( 11564 @NetworkCapabilities.EnterpriseId int identifier) { 11565 if ((identifier >= NET_ENTERPRISE_ID_1) && (identifier <= NET_ENTERPRISE_ID_5)) { 11566 return true; 11567 } 11568 return false; 11569 } 11570 11571 private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences( 11572 @NonNull final NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> prefs) { 11573 final ArraySet<NetworkRequestInfo> result = new ArraySet<>(); 11574 for (final ProfileNetworkPreferenceInfo pref : prefs) { 11575 // The NRI for a user should contain the request for capabilities. 11576 // If fallback to default network is needed then NRI should include 11577 // the request for the default network. Create an image of it to 11578 // have the correct UIDs in it (also a request can only be part of one NRI, because 11579 // of lookups in 1:1 associations like mNetworkRequests). 11580 final ArrayList<NetworkRequest> nrs = new ArrayList<>(); 11581 nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities)); 11582 if (pref.allowFallback) { 11583 nrs.add(createDefaultInternetRequestForTransport( 11584 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 11585 } 11586 if (VDBG) { 11587 loge("pref.capabilities.getUids():" + UidRange.fromIntRanges( 11588 pref.capabilities.getUids())); 11589 } 11590 11591 setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids())); 11592 final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs, 11593 PREFERENCE_ORDER_PROFILE); 11594 result.add(nri); 11595 } 11596 return result; 11597 } 11598 11599 /** 11600 * Compare if the given UID range sets have the same UIDs. 11601 * 11602 */ 11603 private boolean isRangeAlreadyInPreferenceList( 11604 @NonNull List<ProfileNetworkPreferenceInfo> preferenceList, 11605 @NonNull Set<UidRange> uidRangeSet) { 11606 if (uidRangeSet.size() == 0 || preferenceList.size() == 0) { 11607 return false; 11608 } 11609 for (ProfileNetworkPreferenceInfo pref : preferenceList) { 11610 if (UidRangeUtils.doesRangeSetOverlap( 11611 UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) { 11612 return true; 11613 } 11614 } 11615 return false; 11616 } 11617 11618 private void handleSetProfileNetworkPreference( 11619 @NonNull final List<ProfileNetworkPreferenceInfo> preferenceList, 11620 @Nullable final IOnCompleteListener listener) { 11621 /* 11622 * handleSetProfileNetworkPreference is always called for single user. 11623 * preferenceList only contains preferences for different uids within the same user 11624 * (enforced by getUidListToBeAppliedForNetworkPreference). 11625 * Clear all the existing preferences for the user before applying new preferences. 11626 * 11627 */ 11628 mProfileNetworkPreferences = mProfileNetworkPreferences.minus(preferenceList.get(0).user); 11629 for (final ProfileNetworkPreferenceInfo preference : preferenceList) { 11630 mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference); 11631 } 11632 11633 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_PROFILE); 11634 addPerAppDefaultNetworkRequests( 11635 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences)); 11636 updateProfileAllowedNetworks(); 11637 11638 // Finally, rematch. 11639 rematchAllNetworksAndRequests(); 11640 11641 if (null != listener) { 11642 try { 11643 listener.onComplete(); 11644 } catch (RemoteException e) { 11645 loge("Listener for setProfileNetworkPreference has died"); 11646 } 11647 } 11648 } 11649 11650 @VisibleForTesting 11651 @NonNull 11652 ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids( 11653 @NonNull final Set<Integer> uids) { 11654 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 11655 if (uids.size() == 0) { 11656 // Should not create NetworkRequestInfo if no preferences. Without uid range in 11657 // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI. 11658 if (DBG) log("Don't create NetworkRequestInfo because no preferences"); 11659 return nris; 11660 } 11661 11662 final List<NetworkRequest> requests = new ArrayList<>(); 11663 // The NRI should be comprised of two layers: 11664 // - The request for the mobile network preferred. 11665 // - The request for the default network, for fallback. 11666 requests.add(createDefaultInternetRequestForTransport( 11667 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST)); 11668 requests.add(createDefaultInternetRequestForTransport( 11669 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 11670 final Set<UidRange> ranges = new ArraySet<>(); 11671 for (final int uid : uids) { 11672 ranges.add(new UidRange(uid, uid)); 11673 } 11674 setNetworkRequestUids(requests, ranges); 11675 nris.add(new NetworkRequestInfo(Process.myUid(), requests, 11676 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED)); 11677 return nris; 11678 } 11679 11680 private void handleMobileDataPreferredUidsChanged() { 11681 mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext); 11682 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 11683 addPerAppDefaultNetworkRequests( 11684 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids)); 11685 // Finally, rematch. 11686 rematchAllNetworksAndRequests(); 11687 } 11688 11689 private void handleIngressRateLimitChanged() { 11690 final long oldIngressRateLimit = mIngressRateLimit; 11691 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( 11692 mContext); 11693 for (final NetworkAgentInfo networkAgent : mNetworkAgentInfos) { 11694 if (canNetworkBeRateLimited(networkAgent)) { 11695 // If rate limit has previously been enabled, remove the old limit first. 11696 if (oldIngressRateLimit >= 0) { 11697 mDeps.disableIngressRateLimit(networkAgent.linkProperties.getInterfaceName()); 11698 } 11699 if (mIngressRateLimit >= 0) { 11700 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(), 11701 mIngressRateLimit); 11702 } 11703 } 11704 } 11705 } 11706 11707 private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) { 11708 // Rate-limiting cannot run correctly before T because the BPF program is not loaded. 11709 if (!mDeps.isAtLeastT()) return false; 11710 11711 final NetworkCapabilities agentCaps = networkAgent.networkCapabilities; 11712 // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide 11713 // internet connectivity can be rate limited. 11714 if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport( 11715 TRANSPORT_TEST)) { 11716 return false; 11717 } 11718 11719 final String iface = networkAgent.linkProperties.getInterfaceName(); 11720 if (iface == null) { 11721 // This may happen in tests, but if there is no interface then there is nothing that 11722 // can be rate limited. 11723 loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null"); 11724 return false; 11725 } 11726 return true; 11727 } 11728 11729 private void enforceAutomotiveDevice() { 11730 PermissionUtils.enforceSystemFeature(mContext, PackageManager.FEATURE_AUTOMOTIVE, 11731 "setOemNetworkPreference() is only available on automotive devices."); 11732 } 11733 11734 /** 11735 * Used by automotive devices to set the network preferences used to direct traffic at an 11736 * application level as per the given OemNetworkPreferences. An example use-case would be an 11737 * automotive OEM wanting to provide connectivity for applications critical to the usage of a 11738 * vehicle via a particular network. 11739 * 11740 * Calling this will overwrite the existing preference. 11741 * 11742 * @param preference {@link OemNetworkPreferences} The application network preference to be set. 11743 * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used 11744 * to communicate completion of setOemNetworkPreference(); 11745 */ 11746 @Override 11747 public void setOemNetworkPreference( 11748 @NonNull final OemNetworkPreferences preference, 11749 @Nullable final IOnCompleteListener listener) { 11750 11751 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 11752 // Only bypass the permission/device checks if this is a valid test request. 11753 if (isValidTestOemNetworkPreference(preference)) { 11754 enforceManageTestNetworksPermission(); 11755 } else { 11756 enforceAutomotiveDevice(); 11757 enforceOemNetworkPreferencesPermission(); 11758 validateOemNetworkPreferences(preference); 11759 } 11760 11761 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE, 11762 new Pair<>(preference, listener))); 11763 } 11764 11765 /** 11766 * Sets the specified UIDs to get/receive the VPN as the only default network. 11767 * 11768 * Calling this will overwrite the existing network preference for this session, and the 11769 * specified UIDs won't get any default network when no VPN is connected. 11770 * 11771 * @param session The VPN session which manages the passed UIDs. 11772 * @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the 11773 * setting for this session if the array is empty. Null is not allowed, the 11774 * method will use {@link Objects#requireNonNull(Object)} to check this variable. 11775 * @hide 11776 */ 11777 @Override 11778 public void setVpnNetworkPreference(String session, UidRange[] ranges) { 11779 Objects.requireNonNull(ranges); 11780 enforceNetworkStackOrSettingsPermission(); 11781 final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges); 11782 if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) { 11783 throw new IllegalArgumentException( 11784 "setVpnNetworkPreference: Passed UID ranges overlap"); 11785 } 11786 11787 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE, 11788 new VpnNetworkPreferenceInfo(session, 11789 new ArraySet<UidRange>(Arrays.asList(ranges))))); 11790 } 11791 11792 private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) { 11793 Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo); 11794 11795 mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey()); 11796 mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo); 11797 11798 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN); 11799 addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences)); 11800 // Finally, rematch. 11801 rematchAllNetworksAndRequests(); 11802 } 11803 11804 private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference( 11805 @NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) { 11806 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 11807 for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) { 11808 final List<NetworkRequest> requests = new ArrayList<>(); 11809 // Request VPN only, so other networks won't be the fallback options when VPN is not 11810 // connected temporarily. 11811 requests.add(createVpnRequest()); 11812 final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy()); 11813 setNetworkRequestUids(requests, uidRanges); 11814 nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN)); 11815 } 11816 return nris; 11817 } 11818 11819 /** 11820 * Check the validity of an OEM network preference to be used for testing purposes. 11821 * @param preference the preference to validate 11822 * @return true if this is a valid OEM network preference test request. 11823 */ 11824 private boolean isValidTestOemNetworkPreference( 11825 @NonNull final OemNetworkPreferences preference) { 11826 // Allow for clearing of an existing OemNetworkPreference used for testing. 11827 // This isn't called on the handler thread so it is possible that mOemNetworkPreferences 11828 // changes after this check is complete. This is an unlikely scenario as calling of this API 11829 // is controlled by the OEM therefore the added complexity is not worth adding given those 11830 // circumstances. That said, it is an edge case to be aware of hence this comment. 11831 final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0 11832 && isTestOemNetworkPreference(mOemNetworkPreferences); 11833 return isTestOemNetworkPreference(preference) || isValidTestClearPref; 11834 } 11835 11836 private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) { 11837 final Map<String, Integer> prefMap = preference.getNetworkPreferences(); 11838 return prefMap.size() == 1 11839 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST) 11840 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY)); 11841 } 11842 11843 private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) { 11844 for (@OemNetworkPreferences.OemNetworkPreference final int pref 11845 : preference.getNetworkPreferences().values()) { 11846 if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) { 11847 throw new IllegalArgumentException( 11848 OemNetworkPreferences.oemNetworkPreferenceToString(pref) 11849 + " is an invalid value."); 11850 } 11851 } 11852 } 11853 11854 private void handleSetOemNetworkPreference( 11855 @NonNull final OemNetworkPreferences preference, 11856 @Nullable final IOnCompleteListener listener) { 11857 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null"); 11858 if (DBG) { 11859 log("set OEM network preferences :" + preference.toString()); 11860 } 11861 11862 mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference); 11863 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_OEM); 11864 addPerAppDefaultNetworkRequests(new OemNetworkRequestFactory() 11865 .createNrisFromOemNetworkPreferences(preference)); 11866 mOemNetworkPreferences = preference; 11867 11868 if (null != listener) { 11869 try { 11870 listener.onComplete(); 11871 } catch (RemoteException e) { 11872 loge("Can't send onComplete in handleSetOemNetworkPreference", e); 11873 } 11874 } 11875 } 11876 11877 private void removeDefaultNetworkRequestsForPreference(final int preferenceOrder) { 11878 // Skip the requests which are set by other network preference. Because the uid range rules 11879 // should stay in netd. 11880 final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests); 11881 requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder); 11882 handleRemoveNetworkRequests(requests); 11883 } 11884 11885 private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) { 11886 ensureRunningOnConnectivityServiceThread(); 11887 mDefaultNetworkRequests.addAll(nris); 11888 final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate = 11889 getPerAppCallbackRequestsToUpdate(); 11890 final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris); 11891 handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate); 11892 nrisToRegister.addAll( 11893 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate)); 11894 handleRegisterNetworkRequests(nrisToRegister); 11895 } 11896 11897 /** 11898 * All current requests that are tracking the default network need to be assessed as to whether 11899 * or not the current set of per-application default requests will be changing their default 11900 * network. If so, those requests will need to be updated so that they will send callbacks for 11901 * default network changes at the appropriate time. Additionally, those requests tracking the 11902 * default that were previously updated by this flow will need to be reassessed. 11903 * @return the nris which will need to be updated. 11904 */ 11905 private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() { 11906 final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>(); 11907 // Get the distinct nris to check since for multilayer requests, it is possible to have the 11908 // same nri in the map's values for each of its NetworkRequest objects. 11909 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values()); 11910 for (final NetworkRequestInfo nri : nris) { 11911 // Include this nri if it is currently being tracked. 11912 if (isPerAppTrackedNri(nri)) { 11913 defaultCallbackRequests.add(nri); 11914 continue; 11915 } 11916 // We only track callbacks for requests tracking the default. 11917 if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) { 11918 continue; 11919 } 11920 // Include this nri if it will be tracked by the new per-app default requests. 11921 final boolean isNriGoingToBeTracked = 11922 getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest; 11923 if (isNriGoingToBeTracked) { 11924 defaultCallbackRequests.add(nri); 11925 } 11926 } 11927 return defaultCallbackRequests; 11928 } 11929 11930 /** 11931 * Create nris for those network requests that are currently tracking the default network that 11932 * are being controlled by a per-application default. 11933 * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the 11934 * foundation when creating the nri. Important items include the calling uid's original 11935 * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These 11936 * requests are assumed to have already been validated as needing to be updated. 11937 * @return the Set of nris to use when registering network requests. 11938 */ 11939 private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister( 11940 @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) { 11941 final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>(); 11942 for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) { 11943 final NetworkRequestInfo trackingNri = 11944 getDefaultRequestTrackingUid(callbackRequest.mAsUid); 11945 11946 // If this nri is not being tracked, then change it back to an untracked nri. 11947 if (trackingNri == mDefaultRequest) { 11948 callbackRequestsToRegister.add(new NetworkRequestInfo( 11949 callbackRequest, 11950 Collections.singletonList(callbackRequest.getNetworkRequestForCallback()))); 11951 continue; 11952 } 11953 11954 final NetworkRequest request = callbackRequest.mRequests.get(0); 11955 callbackRequestsToRegister.add(new NetworkRequestInfo( 11956 callbackRequest, 11957 copyNetworkRequestsForUid( 11958 trackingNri.mRequests, callbackRequest.mAsUid, 11959 callbackRequest.mUid, request.getRequestorPackageName()))); 11960 } 11961 return callbackRequestsToRegister; 11962 } 11963 11964 private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests, 11965 @NonNull final Set<UidRange> uids) { 11966 for (final NetworkRequest req : requests) { 11967 req.networkCapabilities.setUids(UidRange.toIntRanges(uids)); 11968 } 11969 } 11970 11971 /** 11972 * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}. 11973 */ 11974 @VisibleForTesting 11975 final class OemNetworkRequestFactory { 11976 ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences( 11977 @NonNull final OemNetworkPreferences preference) { 11978 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(); 11979 final SparseArray<Set<Integer>> uids = 11980 createUidsFromOemNetworkPreferences(preference); 11981 for (int i = 0; i < uids.size(); i++) { 11982 final int key = uids.keyAt(i); 11983 final Set<Integer> value = uids.valueAt(i); 11984 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value); 11985 // No need to add an nri without any requests. 11986 if (0 == nri.mRequests.size()) { 11987 continue; 11988 } 11989 nris.add(nri); 11990 } 11991 11992 return nris; 11993 } 11994 11995 private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences( 11996 @NonNull final OemNetworkPreferences preference) { 11997 final SparseArray<Set<Integer>> prefToUids = new SparseArray<>(); 11998 final PackageManager pm = mContext.getPackageManager(); 11999 final List<UserHandle> users = 12000 mContext.getSystemService(UserManager.class).getUserHandles(true); 12001 if (null == users || users.size() == 0) { 12002 if (VDBG || DDBG) { 12003 log("No users currently available for setting the OEM network preference."); 12004 } 12005 return prefToUids; 12006 } 12007 for (final Map.Entry<String, Integer> entry : 12008 preference.getNetworkPreferences().entrySet()) { 12009 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue(); 12010 // Add the rules for all users as this policy is device wide. 12011 for (final UserHandle user : users) { 12012 try { 12013 final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid; 12014 if (!prefToUids.contains(pref)) { 12015 prefToUids.put(pref, new ArraySet<>()); 12016 } 12017 prefToUids.get(pref).add(uid); 12018 } catch (PackageManager.NameNotFoundException e) { 12019 // Although this may seem like an error scenario, it is ok that uninstalled 12020 // packages are sent on a network preference as the system will watch for 12021 // package installations associated with this network preference and update 12022 // accordingly. This is done to minimize race conditions on app install. 12023 continue; 12024 } 12025 } 12026 } 12027 return prefToUids; 12028 } 12029 12030 private NetworkRequestInfo createNriFromOemNetworkPreferences( 12031 @OemNetworkPreferences.OemNetworkPreference final int preference, 12032 @NonNull final Set<Integer> uids) { 12033 final List<NetworkRequest> requests = new ArrayList<>(); 12034 // Requests will ultimately be evaluated by order of insertion therefore it matters. 12035 switch (preference) { 12036 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID: 12037 requests.add(createUnmeteredNetworkRequest()); 12038 requests.add(createOemPaidNetworkRequest()); 12039 requests.add(createDefaultInternetRequestForTransport( 12040 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT)); 12041 break; 12042 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK: 12043 requests.add(createUnmeteredNetworkRequest()); 12044 requests.add(createOemPaidNetworkRequest()); 12045 break; 12046 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY: 12047 requests.add(createOemPaidNetworkRequest()); 12048 break; 12049 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY: 12050 requests.add(createOemPrivateNetworkRequest()); 12051 break; 12052 case OEM_NETWORK_PREFERENCE_TEST: 12053 requests.add(createUnmeteredNetworkRequest()); 12054 requests.add(createTestNetworkRequest()); 12055 requests.add(createDefaultRequest()); 12056 break; 12057 case OEM_NETWORK_PREFERENCE_TEST_ONLY: 12058 requests.add(createTestNetworkRequest()); 12059 break; 12060 default: 12061 // This should never happen. 12062 throw new IllegalArgumentException("createNriFromOemNetworkPreferences()" 12063 + " called with invalid preference of " + preference); 12064 } 12065 12066 final ArraySet<UidRange> ranges = new ArraySet<>(); 12067 for (final int uid : uids) { 12068 ranges.add(new UidRange(uid, uid)); 12069 } 12070 setNetworkRequestUids(requests, ranges); 12071 return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM); 12072 } 12073 12074 private NetworkRequest createUnmeteredNetworkRequest() { 12075 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 12076 .addCapability(NET_CAPABILITY_NOT_METERED) 12077 .addCapability(NET_CAPABILITY_VALIDATED); 12078 return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap); 12079 } 12080 12081 private NetworkRequest createOemPaidNetworkRequest() { 12082 // NET_CAPABILITY_OEM_PAID is a restricted capability. 12083 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 12084 .addCapability(NET_CAPABILITY_OEM_PAID) 12085 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12086 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 12087 } 12088 12089 private NetworkRequest createOemPrivateNetworkRequest() { 12090 // NET_CAPABILITY_OEM_PRIVATE is a restricted capability. 12091 final NetworkCapabilities netcap = createDefaultPerAppNetCap() 12092 .addCapability(NET_CAPABILITY_OEM_PRIVATE) 12093 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12094 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 12095 } 12096 12097 private NetworkCapabilities createDefaultPerAppNetCap() { 12098 final NetworkCapabilities netcap = new NetworkCapabilities(); 12099 netcap.addCapability(NET_CAPABILITY_INTERNET); 12100 netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); 12101 return netcap; 12102 } 12103 12104 private NetworkRequest createTestNetworkRequest() { 12105 final NetworkCapabilities netcap = new NetworkCapabilities(); 12106 netcap.clearAll(); 12107 netcap.addTransportType(TRANSPORT_TEST); 12108 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap); 12109 } 12110 } 12111 12112 @Override 12113 public void updateMeteredNetworkAllowList(final int uid, final boolean add) { 12114 enforceNetworkStackOrSettingsPermission(); 12115 12116 try { 12117 if (add) { 12118 mBpfNetMaps.addNiceApp(uid); 12119 } else { 12120 mBpfNetMaps.removeNiceApp(uid); 12121 } 12122 } catch (ServiceSpecificException e) { 12123 throw new IllegalStateException(e); 12124 } 12125 } 12126 12127 @Override 12128 public void updateMeteredNetworkDenyList(final int uid, final boolean add) { 12129 enforceNetworkStackOrSettingsPermission(); 12130 12131 try { 12132 if (add) { 12133 mBpfNetMaps.addNaughtyApp(uid); 12134 } else { 12135 mBpfNetMaps.removeNaughtyApp(uid); 12136 } 12137 } catch (ServiceSpecificException e) { 12138 throw new IllegalStateException(e); 12139 } 12140 } 12141 12142 @Override 12143 public void setUidFirewallRule(final int chain, final int uid, final int rule) { 12144 enforceNetworkStackOrSettingsPermission(); 12145 12146 // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY 12147 int firewallRule = getFirewallRuleType(chain, rule); 12148 12149 if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) { 12150 throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule); 12151 } 12152 12153 try { 12154 mBpfNetMaps.setUidRule(chain, uid, firewallRule); 12155 } catch (ServiceSpecificException e) { 12156 throw new IllegalStateException(e); 12157 } 12158 } 12159 12160 @Override 12161 public int getUidFirewallRule(final int chain, final int uid) { 12162 enforceNetworkStackOrSettingsPermission(); 12163 return mBpfNetMaps.getUidRule(chain, uid); 12164 } 12165 12166 private int getFirewallRuleType(int chain, int rule) { 12167 final int defaultRule; 12168 switch (chain) { 12169 case ConnectivityManager.FIREWALL_CHAIN_STANDBY: 12170 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1: 12171 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2: 12172 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3: 12173 defaultRule = FIREWALL_RULE_ALLOW; 12174 break; 12175 case ConnectivityManager.FIREWALL_CHAIN_DOZABLE: 12176 case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: 12177 case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: 12178 case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: 12179 defaultRule = FIREWALL_RULE_DENY; 12180 break; 12181 default: 12182 throw new IllegalArgumentException("Unsupported firewall chain: " + chain); 12183 } 12184 if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule; 12185 12186 return rule; 12187 } 12188 12189 private void closeSocketsForFirewallChainLocked(final int chain) 12190 throws ErrnoException, SocketException, InterruptedIOException { 12191 if (mBpfNetMaps.isFirewallAllowList(chain)) { 12192 // Allowlist means the firewall denies all by default, uids must be explicitly allowed 12193 // So, close all non-system socket owned by uids that are not explicitly allowed 12194 Set<Range<Integer>> ranges = new ArraySet<>(); 12195 ranges.add(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE)); 12196 final Set<Integer> exemptUids = mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(chain); 12197 mDeps.destroyLiveTcpSockets(ranges, exemptUids); 12198 } else { 12199 // Denylist means the firewall allows all by default, uids must be explicitly denied 12200 // So, close socket owned by uids that are explicitly denied 12201 final Set<Integer> ownerUids = mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(chain); 12202 mDeps.destroyLiveTcpSocketsByOwnerUids(ownerUids); 12203 } 12204 } 12205 12206 @Override 12207 public void setFirewallChainEnabled(final int chain, final boolean enable) { 12208 enforceNetworkStackOrSettingsPermission(); 12209 12210 try { 12211 mBpfNetMaps.setChildChain(chain, enable); 12212 } catch (ServiceSpecificException e) { 12213 throw new IllegalStateException(e); 12214 } 12215 12216 if (mDeps.isAtLeastU() && enable) { 12217 try { 12218 closeSocketsForFirewallChainLocked(chain); 12219 } catch (ErrnoException | SocketException | InterruptedIOException e) { 12220 Log.e(TAG, "Failed to close sockets after enabling chain (" + chain + "): " + e); 12221 } 12222 } 12223 } 12224 12225 @Override 12226 public boolean getFirewallChainEnabled(final int chain) { 12227 enforceNetworkStackOrSettingsPermission(); 12228 12229 return mBpfNetMaps.isChainEnabled(chain); 12230 } 12231 12232 @Override 12233 public void replaceFirewallChain(final int chain, final int[] uids) { 12234 enforceNetworkStackOrSettingsPermission(); 12235 12236 mBpfNetMaps.replaceUidChain(chain, uids); 12237 } 12238 12239 @Override 12240 public IBinder getCompanionDeviceManagerProxyService() { 12241 enforceNetworkStackPermission(mContext); 12242 return mCdmps; 12243 } 12244 } 12245