1 /* 2 * Copyright (C) 2012 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.ACCESS_NETWORK_STATE; 20 import static android.Manifest.permission.CHANGE_NETWORK_STATE; 21 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; 22 import static android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE; 23 import static android.Manifest.permission.CREATE_USERS; 24 import static android.Manifest.permission.DUMP; 25 import static android.Manifest.permission.GET_INTENT_SENDER_INTENT; 26 import static android.Manifest.permission.LOCAL_MAC_ADDRESS; 27 import static android.Manifest.permission.MANAGE_TEST_NETWORKS; 28 import static android.Manifest.permission.NETWORK_FACTORY; 29 import static android.Manifest.permission.NETWORK_SETTINGS; 30 import static android.Manifest.permission.NETWORK_SETUP_WIZARD; 31 import static android.Manifest.permission.NETWORK_STACK; 32 import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; 33 import static android.Manifest.permission.READ_DEVICE_CONFIG; 34 import static android.Manifest.permission.STATUS_BAR_SERVICE; 35 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; 36 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN; 37 import static android.app.PendingIntent.FLAG_IMMUTABLE; 38 import static android.content.Intent.ACTION_PACKAGE_ADDED; 39 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 40 import static android.content.Intent.ACTION_PACKAGE_REPLACED; 41 import static android.content.Intent.ACTION_USER_ADDED; 42 import static android.content.Intent.ACTION_USER_REMOVED; 43 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 44 import static android.content.pm.PackageManager.FEATURE_ETHERNET; 45 import static android.content.pm.PackageManager.FEATURE_WIFI; 46 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 47 import static android.content.pm.PackageManager.GET_PERMISSIONS; 48 import static android.content.pm.PackageManager.PERMISSION_DENIED; 49 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 50 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 51 import static android.net.ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE; 52 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 53 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 54 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 55 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 56 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; 57 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 58 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 59 import static android.net.ConnectivityManager.EXTRA_DEVICE_TYPE; 60 import static android.net.ConnectivityManager.EXTRA_IS_ACTIVE; 61 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 62 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 63 import static android.net.ConnectivityManager.EXTRA_REALTIME_NS; 64 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; 65 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 66 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 67 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; 68 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; 69 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; 70 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; 71 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2; 72 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3; 73 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 74 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 75 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 76 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 77 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 78 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 79 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; 80 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; 81 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING; 82 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; 83 import static android.net.ConnectivityManager.TYPE_ETHERNET; 84 import static android.net.ConnectivityManager.TYPE_MOBILE; 85 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 86 import static android.net.ConnectivityManager.TYPE_VPN; 87 import static android.net.ConnectivityManager.TYPE_WIFI; 88 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; 89 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 90 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 91 import static android.net.INetd.PERMISSION_INTERNET; 92 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 93 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 94 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 95 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 96 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 97 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 98 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 103 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 104 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 105 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 106 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 107 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 108 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 109 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 110 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 111 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL; 112 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 113 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 114 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 115 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 116 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 117 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 118 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 119 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 120 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 121 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 122 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 123 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 124 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 125 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 126 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 127 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 128 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 129 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 130 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 131 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_2; 132 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_3; 133 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_4; 134 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 135 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 136 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 137 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 138 import static android.net.NetworkCapabilities.REDACT_NONE; 139 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; 140 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 141 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 142 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 143 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 144 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 145 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 146 import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; 147 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 148 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 149 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 150 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 151 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 152 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 153 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; 154 import static android.net.Proxy.PROXY_CHANGE_ACTION; 155 import static android.net.RouteInfo.RTN_UNREACHABLE; 156 import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION; 157 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; 158 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; 159 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; 160 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; 161 import static android.os.Process.INVALID_UID; 162 import static android.system.OsConstants.IPPROTO_TCP; 163 import static android.telephony.DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 164 import static android.telephony.DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 165 166 import static com.android.server.ConnectivityService.ALLOW_SATALLITE_NETWORK_FALLBACK; 167 import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME; 168 import static com.android.server.ConnectivityService.ALLOW_SYSUI_CONNECTIVITY_REPORTS; 169 import static com.android.server.ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION; 170 import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; 171 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED; 172 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_OEM; 173 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_PROFILE; 174 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_VPN; 175 import static com.android.server.ConnectivityService.createDeliveryGroupKeyForConnectivityAction; 176 import static com.android.server.ConnectivityService.makeNflogPrefix; 177 import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; 178 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackRegister; 179 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister; 180 import static com.android.server.connectivity.ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN; 181 import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS; 182 import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING; 183 import static com.android.testutils.Cleanup.testAndCleanup; 184 import static com.android.testutils.ConcurrentUtils.await; 185 import static com.android.testutils.ConcurrentUtils.durationOf; 186 import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 187 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 188 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; 189 import static com.android.testutils.FunctionalUtils.ignoreExceptions; 190 import static com.android.testutils.HandlerUtils.visibleOnHandlerThread; 191 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 192 import static com.android.testutils.MiscAsserts.assertContainsAll; 193 import static com.android.testutils.MiscAsserts.assertContainsExactly; 194 import static com.android.testutils.MiscAsserts.assertEmpty; 195 import static com.android.testutils.MiscAsserts.assertLength; 196 import static com.android.testutils.MiscAsserts.assertRunsInAtMost; 197 import static com.android.testutils.MiscAsserts.assertSameElements; 198 import static com.android.testutils.MiscAsserts.assertThrows; 199 import static com.android.testutils.RecorderCallback.CallbackEntry.AVAILABLE; 200 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS; 201 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS_INT; 202 import static com.android.testutils.RecorderCallback.CallbackEntry.LINK_PROPERTIES_CHANGED; 203 import static com.android.testutils.RecorderCallback.CallbackEntry.LOSING; 204 import static com.android.testutils.RecorderCallback.CallbackEntry.LOST; 205 import static com.android.testutils.RecorderCallback.CallbackEntry.NETWORK_CAPS_UPDATED; 206 import static com.android.testutils.RecorderCallback.CallbackEntry.RESUMED; 207 import static com.android.testutils.RecorderCallback.CallbackEntry.SUSPENDED; 208 import static com.android.testutils.RecorderCallback.CallbackEntry.UNAVAILABLE; 209 import static com.android.testutils.TestPermissionUtil.runAsShell; 210 211 import static org.hamcrest.MatcherAssert.assertThat; 212 import static org.hamcrest.Matchers.containsString; 213 import static org.junit.Assert.assertEquals; 214 import static org.junit.Assert.assertFalse; 215 import static org.junit.Assert.assertNotEquals; 216 import static org.junit.Assert.assertNotNull; 217 import static org.junit.Assert.assertNull; 218 import static org.junit.Assert.assertTrue; 219 import static org.junit.Assert.fail; 220 import static org.junit.Assume.assumeFalse; 221 import static org.junit.Assume.assumeTrue; 222 import static org.mockito.AdditionalMatchers.aryEq; 223 import static org.mockito.ArgumentMatchers.anyBoolean; 224 import static org.mockito.ArgumentMatchers.anyLong; 225 import static org.mockito.ArgumentMatchers.anyString; 226 import static org.mockito.ArgumentMatchers.argThat; 227 import static org.mockito.ArgumentMatchers.eq; 228 import static org.mockito.ArgumentMatchers.isNull; 229 import static org.mockito.Matchers.anyInt; 230 import static org.mockito.Mockito.any; 231 import static org.mockito.Mockito.atLeastOnce; 232 import static org.mockito.Mockito.clearInvocations; 233 import static org.mockito.Mockito.doAnswer; 234 import static org.mockito.Mockito.doNothing; 235 import static org.mockito.Mockito.doReturn; 236 import static org.mockito.Mockito.doThrow; 237 import static org.mockito.Mockito.inOrder; 238 import static org.mockito.Mockito.mock; 239 import static org.mockito.Mockito.never; 240 import static org.mockito.Mockito.reset; 241 import static org.mockito.Mockito.spy; 242 import static org.mockito.Mockito.timeout; 243 import static org.mockito.Mockito.times; 244 import static org.mockito.Mockito.verify; 245 import static org.mockito.Mockito.verifyNoMoreInteractions; 246 247 import static java.util.Arrays.asList; 248 249 import android.Manifest; 250 import android.annotation.NonNull; 251 import android.annotation.Nullable; 252 import android.app.ActivityManager; 253 import android.app.ActivityManager.UidFrozenStateChangedCallback; 254 import android.app.AlarmManager; 255 import android.app.AppOpsManager; 256 import android.app.BroadcastOptions; 257 import android.app.NotificationManager; 258 import android.app.PendingIntent; 259 import android.app.admin.DevicePolicyManager; 260 import android.app.usage.NetworkStatsManager; 261 import android.compat.testing.PlatformCompatChangeRule; 262 import android.content.BroadcastReceiver; 263 import android.content.ComponentName; 264 import android.content.ContentProvider; 265 import android.content.ContentResolver; 266 import android.content.Context; 267 import android.content.Intent; 268 import android.content.IntentFilter; 269 import android.content.pm.ApplicationInfo; 270 import android.content.pm.ModuleInfo; 271 import android.content.pm.PackageInfo; 272 import android.content.pm.PackageManager; 273 import android.content.pm.ResolveInfo; 274 import android.content.pm.ServiceInfo; 275 import android.content.pm.UserInfo; 276 import android.content.res.Resources; 277 import android.location.LocationManager; 278 import android.net.CaptivePortal; 279 import android.net.CaptivePortalData; 280 import android.net.ConnectionInfo; 281 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 282 import android.net.ConnectivityManager; 283 import android.net.ConnectivityManager.NetworkCallback; 284 import android.net.ConnectivityManager.PacketKeepalive; 285 import android.net.ConnectivityManager.PacketKeepaliveCallback; 286 import android.net.ConnectivityManager.TooManyRequestsException; 287 import android.net.ConnectivitySettingsManager; 288 import android.net.ConnectivityThread; 289 import android.net.DataStallReportParcelable; 290 import android.net.EthernetManager; 291 import android.net.EthernetNetworkSpecifier; 292 import android.net.IConnectivityDiagnosticsCallback; 293 import android.net.IDnsResolver; 294 import android.net.INetd; 295 import android.net.INetworkMonitor; 296 import android.net.INetworkMonitorCallbacks; 297 import android.net.IOnCompleteListener; 298 import android.net.IQosCallback; 299 import android.net.InetAddresses; 300 import android.net.InterfaceConfigurationParcel; 301 import android.net.IpPrefix; 302 import android.net.IpSecManager; 303 import android.net.IpSecManager.UdpEncapsulationSocket; 304 import android.net.LinkAddress; 305 import android.net.LinkProperties; 306 import android.net.MatchAllNetworkSpecifier; 307 import android.net.NativeNetworkConfig; 308 import android.net.NativeNetworkType; 309 import android.net.Network; 310 import android.net.NetworkAgent; 311 import android.net.NetworkAgentConfig; 312 import android.net.NetworkCapabilities; 313 import android.net.NetworkFactory; 314 import android.net.NetworkInfo; 315 import android.net.NetworkInfo.DetailedState; 316 import android.net.NetworkPolicyManager; 317 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 318 import android.net.NetworkProvider; 319 import android.net.NetworkRequest; 320 import android.net.NetworkScore; 321 import android.net.NetworkSpecifier; 322 import android.net.NetworkStack; 323 import android.net.NetworkStateSnapshot; 324 import android.net.NetworkTestResultParcelable; 325 import android.net.OemNetworkPreferences; 326 import android.net.PacProxyManager; 327 import android.net.ProfileNetworkPreference; 328 import android.net.Proxy; 329 import android.net.ProxyInfo; 330 import android.net.QosCallbackException; 331 import android.net.QosFilter; 332 import android.net.QosSession; 333 import android.net.ResolverParamsParcel; 334 import android.net.RouteInfo; 335 import android.net.RouteInfoParcel; 336 import android.net.SocketKeepalive; 337 import android.net.TelephonyNetworkSpecifier; 338 import android.net.TetheringManager; 339 import android.net.TransportInfo; 340 import android.net.UidRange; 341 import android.net.UidRangeParcel; 342 import android.net.UnderlyingNetworkInfo; 343 import android.net.Uri; 344 import android.net.VpnManager; 345 import android.net.VpnTransportInfo; 346 import android.net.connectivity.ConnectivityCompatChanges; 347 import android.net.metrics.IpConnectivityLog; 348 import android.net.netd.aidl.NativeUidRangeConfig; 349 import android.net.networkstack.NetworkStackClientBase; 350 import android.net.resolv.aidl.Nat64PrefixEventParcel; 351 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 352 import android.net.shared.PrivateDnsConfig; 353 import android.net.wifi.WifiInfo; 354 import android.os.BadParcelableException; 355 import android.os.BatteryStatsManager; 356 import android.os.Binder; 357 import android.os.Build; 358 import android.os.Bundle; 359 import android.os.ConditionVariable; 360 import android.os.Handler; 361 import android.os.HandlerThread; 362 import android.os.IBinder; 363 import android.os.INetworkManagementService; 364 import android.os.Looper; 365 import android.os.Messenger; 366 import android.os.Parcel; 367 import android.os.ParcelFileDescriptor; 368 import android.os.Parcelable; 369 import android.os.PersistableBundle; 370 import android.os.Process; 371 import android.os.RemoteException; 372 import android.os.ServiceSpecificException; 373 import android.os.SystemClock; 374 import android.os.SystemConfigManager; 375 import android.os.UserHandle; 376 import android.os.UserManager; 377 import android.provider.Settings; 378 import android.system.Os; 379 import android.telephony.SubscriptionManager; 380 import android.telephony.TelephonyManager; 381 import android.telephony.data.EpsBearerQosSessionAttributes; 382 import android.telephony.data.NrQosSessionAttributes; 383 import android.test.mock.MockContentResolver; 384 import android.text.TextUtils; 385 import android.util.ArraySet; 386 import android.util.Log; 387 import android.util.Pair; 388 import android.util.Range; 389 import android.util.SparseArray; 390 391 import androidx.test.InstrumentationRegistry; 392 import androidx.test.filters.SmallTest; 393 394 import com.android.connectivity.resources.R; 395 import com.android.internal.annotations.GuardedBy; 396 import com.android.internal.app.IBatteryStats; 397 import com.android.internal.net.VpnConfig; 398 import com.android.internal.util.WakeupMessage; 399 import com.android.internal.util.test.BroadcastInterceptingContext; 400 import com.android.internal.util.test.FakeSettingsProvider; 401 import com.android.modules.utils.build.SdkLevel; 402 import com.android.net.module.util.ArrayTrackRecord; 403 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 404 import com.android.net.module.util.CollectionUtils; 405 import com.android.net.module.util.LocationPermissionChecker; 406 import com.android.net.module.util.NetworkMonitorUtils; 407 import com.android.networkstack.apishim.ConstantsShim; 408 import com.android.networkstack.apishim.NetworkAgentConfigShimImpl; 409 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 410 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 411 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 412 import com.android.server.ConnectivityService.NetworkRequestInfo; 413 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.DestroySocketsWrapper; 414 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces; 415 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 416 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 417 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 418 import com.android.server.connectivity.ClatCoordinator; 419 import com.android.server.connectivity.ConnectivityFlags; 420 import com.android.server.connectivity.ConnectivityResources; 421 import com.android.server.connectivity.KeepaliveTracker; 422 import com.android.server.connectivity.MultinetworkPolicyTracker; 423 import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies; 424 import com.android.server.connectivity.Nat464Xlat; 425 import com.android.server.connectivity.NetworkAgentInfo; 426 import com.android.server.connectivity.NetworkNotificationManager; 427 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 428 import com.android.server.connectivity.ProxyTracker; 429 import com.android.server.connectivity.QosCallbackTracker; 430 import com.android.server.connectivity.SatelliteAccessController; 431 import com.android.server.connectivity.TcpKeepaliveController; 432 import com.android.server.connectivity.UidRangeUtils; 433 import com.android.server.net.NetworkPinner; 434 import com.android.testutils.DevSdkIgnoreRule; 435 import com.android.testutils.DevSdkIgnoreRunner; 436 import com.android.testutils.FunctionalUtils.Function3; 437 import com.android.testutils.FunctionalUtils.ThrowingConsumer; 438 import com.android.testutils.FunctionalUtils.ThrowingRunnable; 439 import com.android.testutils.HandlerUtils; 440 import com.android.testutils.RecorderCallback.CallbackEntry; 441 import com.android.testutils.TestableNetworkCallback; 442 import com.android.testutils.TestableNetworkOfferCallback; 443 444 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; 445 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; 446 447 import org.junit.After; 448 import org.junit.Assert; 449 import org.junit.Before; 450 import org.junit.Ignore; 451 import org.junit.Rule; 452 import org.junit.Test; 453 import org.junit.runner.RunWith; 454 import org.mockito.AdditionalAnswers; 455 import org.mockito.ArgumentCaptor; 456 import org.mockito.InOrder; 457 import org.mockito.Mock; 458 import org.mockito.MockitoAnnotations; 459 import org.mockito.Spy; 460 import org.mockito.stubbing.Answer; 461 462 import java.io.FileDescriptor; 463 import java.io.IOException; 464 import java.io.PrintWriter; 465 import java.io.StringWriter; 466 import java.lang.reflect.Method; 467 import java.net.DatagramSocket; 468 import java.net.Inet4Address; 469 import java.net.Inet6Address; 470 import java.net.InetAddress; 471 import java.net.InetSocketAddress; 472 import java.net.Socket; 473 import java.util.ArrayList; 474 import java.util.Arrays; 475 import java.util.Collection; 476 import java.util.Collections; 477 import java.util.Comparator; 478 import java.util.HashMap; 479 import java.util.HashSet; 480 import java.util.List; 481 import java.util.Map; 482 import java.util.Objects; 483 import java.util.Set; 484 import java.util.UUID; 485 import java.util.concurrent.CompletableFuture; 486 import java.util.concurrent.CountDownLatch; 487 import java.util.concurrent.Executor; 488 import java.util.concurrent.ExecutorService; 489 import java.util.concurrent.Executors; 490 import java.util.concurrent.LinkedBlockingQueue; 491 import java.util.concurrent.TimeUnit; 492 import java.util.concurrent.TimeoutException; 493 import java.util.concurrent.atomic.AtomicBoolean; 494 import java.util.concurrent.atomic.AtomicReference; 495 import java.util.function.BiConsumer; 496 import java.util.function.Consumer; 497 import java.util.function.Predicate; 498 import java.util.function.Supplier; 499 import java.util.regex.Matcher; 500 import java.util.regex.Pattern; 501 import java.util.stream.Collectors; 502 503 /** 504 * Tests for {@link ConnectivityService}. 505 * 506 * Build, install and run with: 507 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 508 */ 509 // TODO : move methods from this test to smaller tests in the 'connectivityservice' directory 510 // to enable faster testing of smaller groups of functionality. 511 @RunWith(DevSdkIgnoreRunner.class) 512 @SmallTest 513 @DevSdkIgnoreRunner.MonitorThreadLeak 514 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 515 public class ConnectivityServiceTest { 516 private static final String TAG = "ConnectivityServiceTest"; 517 518 @Rule 519 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 520 521 @Rule 522 public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule(); 523 524 private static final int TIMEOUT_MS = 2_000; 525 // Broadcasts can take a long time to be delivered. The test will not wait for that long unless 526 // there is a failure, so use a long timeout. 527 private static final int BROADCAST_TIMEOUT_MS = 30_000; 528 private static final int TEST_LINGER_DELAY_MS = 400; 529 private static final int TEST_NASCENT_DELAY_MS = 300; 530 // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish 531 // between a LOST callback that arrives immediately and a LOST callback that arrives after 532 // the linger/nascent timeout. For this, our assertions should run fast enough to leave 533 // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 534 // supposedly fired, and the time we call expectCapChanged. 535 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 536 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 537 // complete before callbacks are verified. 538 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 539 540 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 2_000; 541 542 private static final long TIMESTAMP = 1234L; 543 544 private static final int NET_ID = 110; 545 private static final int OEM_PREF_ANY_NET_ID = -1; 546 // Set a non-zero value to verify the flow to set tcp init rwnd value. 547 private static final int TEST_TCP_INIT_RWND = 60; 548 549 // Used for testing the per-work-profile default network. 550 private static final int TEST_APP_ID = 103; 551 private static final int TEST_WORK_PROFILE_USER_ID = 2; 552 private static final int TEST_WORK_PROFILE_APP_UID = 553 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); 554 private static final int TEST_APP_ID_2 = 104; 555 private static final int TEST_WORK_PROFILE_APP_UID_2 = 556 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID_2); 557 private static final int TEST_APP_ID_3 = 105; 558 private static final int TEST_APP_ID_4 = 106; 559 private static final int TEST_APP_ID_5 = 107; 560 561 private static final String CLAT_PREFIX = "v4-"; 562 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 563 private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME; 564 private static final String WIFI_IFNAME = "test_wlan0"; 565 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 566 private static final String VPN_IFNAME = "tun10042"; 567 private static final String ETHERNET_IFNAME = "eth0"; 568 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 569 private static final int TEST_PACKAGE_UID = 123; 570 private static final int TEST_PACKAGE_UID2 = 321; 571 private static final int TEST_PACKAGE_UID3 = 456; 572 private static final int NETWORK_ACTIVITY_NO_UID = -1; 573 private static final int TEST_SUBSCRIPTION_ID = 1; 574 575 private static final int PACKET_WAKEUP_MARK_MASK = 0x80000000; 576 577 private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; 578 579 private static final String INTERFACE_NAME = "interface"; 580 581 private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; 582 private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; 583 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = 584 "https://android.com/terms/"; 585 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = 586 "https://example.com/terms/"; 587 private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; 588 private static final String TEST_USER_PORTAL_API_URL_CAPPORT = 589 "https://android.com/user/api/capport/"; 590 private static final String TEST_FRIENDLY_NAME = "Network friendly name"; 591 private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; 592 593 private MockContext mServiceContext; 594 private HandlerThread mCsHandlerThread; 595 private ConnectivityServiceDependencies mDeps; 596 private AutomaticOnOffKeepaliveTrackerDependencies mAutoOnOffKeepaliveDependencies; 597 private ConnectivityService mService; 598 private WrappedConnectivityManager mCm; 599 private TestNetworkAgentWrapper mWiFiAgent; 600 private TestNetworkAgentWrapper mCellAgent; 601 private TestNetworkAgentWrapper mEthernetAgent; 602 private final List<TestNetworkAgentWrapper> mCreatedAgents = new ArrayList<>(); 603 private MockVpn mMockVpn; 604 private Context mContext; 605 private NetworkPolicyCallback mPolicyCallback; 606 private WrappedMultinetworkPolicyTracker mPolicyTracker; 607 private ProxyTracker mProxyTracker; 608 private HandlerThread mAlarmManagerThread; 609 private TestNetIdManager mNetIdManager; 610 private QosCallbackMockHelper mQosCallbackMockHelper; 611 private QosCallbackTracker mQosCallbackTracker; 612 private TestNetworkCallback mDefaultNetworkCallback; 613 private TestNetworkCallback mSystemDefaultNetworkCallback; 614 private TestNetworkCallback mProfileDefaultNetworkCallback; 615 private TestNetworkCallback mTestPackageDefaultNetworkCallback; 616 private TestNetworkCallback mProfileDefaultNetworkCallbackAsAppUid2; 617 private TestNetworkCallback mTestPackageDefaultNetworkCallback2; 618 619 // State variables required to emulate NetworkPolicyManagerService behaviour. 620 private int mBlockedReasons = BLOCKED_REASON_NONE; 621 622 @Mock DeviceIdleInternal mDeviceIdleInternal; 623 @Mock INetworkManagementService mNetworkManagementService; 624 @Mock NetworkStatsManager mStatsManager; 625 @Mock IDnsResolver mMockDnsResolver; 626 @Mock INetd mMockNetd; 627 @Mock NetworkStackClientBase mNetworkStack; 628 @Mock PackageManager mPackageManager; 629 @Mock UserManager mUserManager; 630 @Mock NotificationManager mNotificationManager; 631 @Mock AlarmManager mAlarmManager; 632 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 633 @Mock IBinder mIBinder; 634 @Mock LocationManager mLocationManager; 635 @Mock AppOpsManager mAppOpsManager; 636 @Mock TelephonyManager mTelephonyManager; 637 @Mock EthernetManager mEthernetManager; 638 @Mock NetworkPolicyManager mNetworkPolicyManager; 639 @Mock SystemConfigManager mSystemConfigManager; 640 @Mock DevicePolicyManager mDevicePolicyManager; 641 @Mock Resources mResources; 642 @Mock ClatCoordinator mClatCoordinator; 643 @Mock PacProxyManager mPacProxyManager; 644 @Mock BpfNetMaps mBpfNetMaps; 645 @Mock CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 646 @Mock TetheringManager mTetheringManager; 647 @Mock BroadcastOptionsShim mBroadcastOptionsShim; 648 @Mock ActivityManager mActivityManager; 649 @Mock DestroySocketsWrapper mDestroySocketsWrapper; 650 @Mock SubscriptionManager mSubscriptionManager; 651 @Mock KeepaliveTracker.Dependencies mMockKeepaliveTrackerDependencies; 652 @Mock SatelliteAccessController mSatelliteAccessController; 653 654 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 655 // underlying binder calls. 656 final IBatteryStats mIBatteryStats = mock(IBatteryStats.class); 657 final BatteryStatsManager mBatteryStatsManager = new BatteryStatsManager(mIBatteryStats); 658 659 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 660 ArgumentCaptor.forClass(ResolverParamsParcel.class); 661 662 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 663 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 664 // reflect the state of our test ConnectivityService. 665 private class WrappedConnectivityManager extends ConnectivityManager { 666 private Network mFakeBoundNetwork; 667 bindProcessToNetwork(Network network)668 public synchronized boolean bindProcessToNetwork(Network network) { 669 mFakeBoundNetwork = network; 670 return true; 671 } 672 getBoundNetworkForProcess()673 public synchronized Network getBoundNetworkForProcess() { 674 return mFakeBoundNetwork; 675 } 676 WrappedConnectivityManager(Context context, ConnectivityService service)677 public WrappedConnectivityManager(Context context, ConnectivityService service) { 678 super(context, service); 679 } 680 } 681 682 private class MockContext extends BroadcastInterceptingContext { 683 private final MockContentResolver mContentResolver; 684 685 @Spy private Resources mInternalResources; 686 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 687 688 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 689 // For permissions granted across the board, the key is only the permission name. 690 // For permissions only granted to a combination of uid/pid, the key 691 // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones. 692 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 693 mockStringResource(int resId)694 private void mockStringResource(int resId) { 695 doAnswer((inv) -> { 696 return "Mock string resource ID=" + inv.getArgument(0); 697 }).when(mInternalResources).getString(resId); 698 } 699 MockContext(Context base, ContentProvider settingsProvider)700 MockContext(Context base, ContentProvider settingsProvider) { 701 super(base); 702 703 mInternalResources = spy(base.getResources()); 704 doReturn(new String[] { 705 "wifi,1,1,1,-1,true", 706 "mobile,0,0,0,-1,true", 707 "mobile_mms,2,0,2,60000,true", 708 "mobile_supl,3,0,2,60000,true", 709 }).when(mInternalResources) 710 .getStringArray(com.android.internal.R.array.networkAttributes); 711 712 final int[] stringResourcesToMock = new int[] { 713 com.android.internal.R.string.config_customVpnAlwaysOnDisconnectedDialogComponent, 714 com.android.internal.R.string.vpn_lockdown_config, 715 com.android.internal.R.string.vpn_lockdown_connected, 716 com.android.internal.R.string.vpn_lockdown_connecting, 717 com.android.internal.R.string.vpn_lockdown_disconnected, 718 com.android.internal.R.string.vpn_lockdown_error, 719 }; 720 for (int resId : stringResourcesToMock) { 721 mockStringResource(resId); 722 } 723 724 mContentResolver = new MockContentResolver(); 725 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 726 } 727 728 @Override startActivityAsUser(Intent intent, UserHandle handle)729 public void startActivityAsUser(Intent intent, UserHandle handle) { 730 mStartedActivities.offer(intent); 731 } 732 expectStartActivityIntent(int timeoutMs)733 public Intent expectStartActivityIntent(int timeoutMs) { 734 Intent intent = null; 735 try { 736 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 737 } catch (InterruptedException e) {} 738 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 739 return intent; 740 } 741 expectNoStartActivityIntent(int timeoutMs)742 public void expectNoStartActivityIntent(int timeoutMs) { 743 try { 744 assertNull("Received unexpected Intent to start activity", 745 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 746 } catch (InterruptedException e) {} 747 } 748 749 @Override startService(Intent service)750 public ComponentName startService(Intent service) { 751 final String action = service.getAction(); 752 if (!VpnConfig.SERVICE_INTERFACE.equals(action) 753 && !ConstantsShim.ACTION_VPN_MANAGER_EVENT.equals(action)) { 754 fail("Attempt to start unknown service, action=" + action); 755 } 756 return new ComponentName(service.getPackage(), "com.android.test.Service"); 757 } 758 759 @Override getSystemService(String name)760 public Object getSystemService(String name) { 761 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 762 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 763 if (Context.USER_SERVICE.equals(name)) return mUserManager; 764 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 765 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 766 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 767 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 768 if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; 769 if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; 770 if (Context.DEVICE_POLICY_SERVICE.equals(name)) return mDevicePolicyManager; 771 if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; 772 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 773 if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; 774 if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager; 775 if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager; 776 if (Context.ACTIVITY_SERVICE.equals(name)) return mActivityManager; 777 if (Context.TELEPHONY_SUBSCRIPTION_SERVICE.equals(name)) return mSubscriptionManager; 778 // StatsManager is final and can't be mocked, and uses static methods for mostly 779 // everything. The simplest fix is to return null and not have metrics in tests. 780 if (Context.STATS_MANAGER.equals(name)) return null; 781 return super.getSystemService(name); 782 } 783 784 final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); 785 @Override createContextAsUser(UserHandle user, int flags)786 public Context createContextAsUser(UserHandle user, int flags) { 787 final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); 788 doReturn(user).when(asUser).getUser(); 789 doAnswer((inv) -> { 790 final UserManager um = mUserManagers.computeIfAbsent(user, 791 u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); 792 return um; 793 }).when(asUser).getSystemService(Context.USER_SERVICE); 794 return asUser; 795 } 796 setWorkProfile(@onNull final UserHandle userHandle, boolean value)797 public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { 798 // This relies on all contexts for a given user returning the same UM mock 799 final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) 800 .getSystemService(UserManager.class); 801 doReturn(value).when(umMock).isManagedProfile(); 802 doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); 803 } 804 setDeviceOwner(@onNull final UserHandle userHandle, String value)805 public void setDeviceOwner(@NonNull final UserHandle userHandle, String value) { 806 // This relies on all contexts for a given user returning the same UM mock 807 final DevicePolicyManager dpmMock = createContextAsUser(userHandle, 0 /* flags */) 808 .getSystemService(DevicePolicyManager.class); 809 ComponentName componentName = value == null 810 ? null : new ComponentName(value, "deviceOwnerClass"); 811 doReturn(componentName).when(dpmMock).getDeviceOwnerComponentOnAnyUser(); 812 doReturn(componentName).when(mDevicePolicyManager).getDeviceOwnerComponentOnAnyUser(); 813 } 814 815 @Override getContentResolver()816 public ContentResolver getContentResolver() { 817 return mContentResolver; 818 } 819 820 @Override getResources()821 public Resources getResources() { 822 return mInternalResources; 823 } 824 825 @Override getPackageManager()826 public PackageManager getPackageManager() { 827 return mPackageManager; 828 } 829 checkMockedPermission(String permission, int pid, int uid, Function3<String, Integer, Integer, Integer> ifAbsent )830 private int checkMockedPermission(String permission, int pid, int uid, 831 Function3<String, Integer, Integer, Integer> ifAbsent /* perm, uid, pid -> int */) { 832 final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid); 833 if (null != granted) { 834 return granted; 835 } 836 final Integer allGranted = mMockedPermissions.get(permission); 837 if (null != allGranted) { 838 return allGranted; 839 } 840 return ifAbsent.apply(permission, pid, uid); 841 } 842 843 @Override checkPermission(String permission, int pid, int uid)844 public int checkPermission(String permission, int pid, int uid) { 845 return checkMockedPermission(permission, pid, uid, 846 (perm, p, u) -> super.checkPermission(perm, p, u)); 847 } 848 849 @Override checkCallingOrSelfPermission(String permission)850 public int checkCallingOrSelfPermission(String permission) { 851 return checkMockedPermission(permission, Process.myPid(), Process.myUid(), 852 (perm, p, u) -> super.checkCallingOrSelfPermission(perm)); 853 } 854 855 @Override enforceCallingOrSelfPermission(String permission, String message)856 public void enforceCallingOrSelfPermission(String permission, String message) { 857 final Integer granted = checkMockedPermission(permission, 858 Process.myPid(), Process.myUid(), 859 (perm, p, u) -> { 860 super.enforceCallingOrSelfPermission(perm, message); 861 // enforce will crash if the permission is not granted 862 return PERMISSION_GRANTED; 863 }); 864 865 if (!granted.equals(PERMISSION_GRANTED)) { 866 throw new SecurityException("[Test] permission denied: " + permission); 867 } 868 } 869 870 /** 871 * Mock checks for the specified permission, and have them behave as per {@code granted}. 872 * 873 * This will apply to all calls no matter what the checked UID and PID are. 874 * 875 * <p>Passing null reverts to default behavior, which does a real permission check on the 876 * test package. 877 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 878 * {@link PackageManager#PERMISSION_DENIED}. 879 */ setPermission(String permission, Integer granted)880 public void setPermission(String permission, Integer granted) { 881 mMockedPermissions.put(permission, granted); 882 } 883 884 /** 885 * Mock checks for the specified permission, and have them behave as per {@code granted}. 886 * 887 * This will only apply to the passed UID and PID. 888 * 889 * <p>Passing null reverts to default behavior, which does a real permission check on the 890 * test package. 891 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 892 * {@link PackageManager#PERMISSION_DENIED}. 893 */ setPermission(String permission, int pid, int uid, Integer granted)894 public void setPermission(String permission, int pid, int uid, Integer granted) { 895 final String key = permission + "," + pid + "," + uid; 896 mMockedPermissions.put(key, granted); 897 } 898 899 @Override registerReceiverForAllUsers(@ullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler)900 public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver, 901 @NonNull IntentFilter filter, @Nullable String broadcastPermission, 902 @Nullable Handler scheduler) { 903 // TODO: ensure MultinetworkPolicyTracker's BroadcastReceiver is tested; just returning 904 // null should not pass the test 905 return null; 906 } 907 908 @Override sendStickyBroadcast(Intent intent, Bundle options)909 public void sendStickyBroadcast(Intent intent, Bundle options) { 910 // Verify that delivery group policy APIs were used on U. 911 if (mDeps.isAtLeastU() && CONNECTIVITY_ACTION.equals(intent.getAction())) { 912 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO, 913 NetworkInfo.class); 914 try { 915 verify(mBroadcastOptionsShim).setDeliveryGroupPolicy( 916 eq(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT)); 917 verify(mBroadcastOptionsShim).setDeliveryGroupMatchingKey( 918 eq(CONNECTIVITY_ACTION), 919 eq(createDeliveryGroupKeyForConnectivityAction(ni))); 920 verify(mBroadcastOptionsShim).setDeferralPolicy( 921 eq(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE)); 922 } catch (UnsupportedApiLevelException e) { 923 throw new RuntimeException(e); 924 } 925 } 926 super.sendStickyBroadcast(intent, options); 927 } 928 929 private final ArrayTrackRecord<Intent>.ReadHead mOrderedBroadcastAsUserHistory = 930 new ArrayTrackRecord<Intent>().newReadHead(); 931 expectDataActivityBroadcast(int deviceType, boolean isActive, long tsNanos)932 public void expectDataActivityBroadcast(int deviceType, boolean isActive, long tsNanos) { 933 assertNotNull(mOrderedBroadcastAsUserHistory.poll(BROADCAST_TIMEOUT_MS, 934 intent -> intent.getAction().equals(ACTION_DATA_ACTIVITY_CHANGE) 935 && intent.getIntExtra(EXTRA_DEVICE_TYPE, -1) == deviceType 936 && intent.getBooleanExtra(EXTRA_IS_ACTIVE, !isActive) == isActive 937 && intent.getLongExtra(EXTRA_REALTIME_NS, -1) == tsNanos 938 )); 939 } 940 941 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)942 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 943 String receiverPermission, BroadcastReceiver resultReceiver, 944 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 945 mOrderedBroadcastAsUserHistory.add(intent); 946 } 947 } 948 949 // This was only added in the T SDK, but this test needs to build against the R+S SDKs, too. toSdkSandboxUid(int appUid)950 private static int toSdkSandboxUid(int appUid) { 951 final int firstSdkSandboxUid = 20000; 952 return appUid + (firstSdkSandboxUid - Process.FIRST_APPLICATION_UID); 953 } 954 955 // Create the list of ranges for the primary user (User 0), excluding excludedUids. intRangesPrimaryExcludingUids(List<Integer> excludedUids)956 private static List<Range<Integer>> intRangesPrimaryExcludingUids(List<Integer> excludedUids) { 957 final List<Integer> excludedUidsList = new ArrayList<>(excludedUids); 958 // Uid 0 is always excluded 959 if (!excludedUidsList.contains(0)) { 960 excludedUidsList.add(0); 961 } 962 return intRangesExcludingUids(PRIMARY_USER, excludedUidsList); 963 } 964 intRangesExcludingUids(int userId, List<Integer> excludedAppIds)965 private static List<Range<Integer>> intRangesExcludingUids(int userId, 966 List<Integer> excludedAppIds) { 967 final List<Integer> excludedUids = CollectionUtils.map(excludedAppIds, 968 appId -> UserHandle.getUid(userId, appId)); 969 final int userBase = userId * UserHandle.PER_USER_RANGE; 970 final int maxUid = userBase + UserHandle.PER_USER_RANGE - 1; 971 972 int start = userBase; 973 Collections.sort(excludedUids); 974 final List<Range<Integer>> ranges = new ArrayList<>(); 975 for (int excludedUid : excludedUids) { 976 if (excludedUid == start) { 977 start++; 978 } else { 979 ranges.add(new Range<>(start, excludedUid - 1)); 980 start = excludedUid + 1; 981 } 982 } 983 if (start <= maxUid) { 984 ranges.add(new Range<>(start, maxUid)); 985 } 986 987 return ranges; 988 } 989 waitForIdle()990 private void waitForIdle() { 991 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 992 waitForIdle(mCellAgent, TIMEOUT_MS); 993 waitForIdle(mWiFiAgent, TIMEOUT_MS); 994 waitForIdle(mEthernetAgent, TIMEOUT_MS); 995 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 996 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 997 } 998 waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs)999 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 1000 if (agent == null) { 1001 return; 1002 } 1003 agent.waitForIdle(timeoutMs); 1004 } 1005 1006 @Test testWaitForIdle()1007 public void testWaitForIdle() throws Exception { 1008 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 1009 1010 // Tests that waitForIdle returns immediately if the service is already idle. 1011 for (int i = 0; i < attempts; i++) { 1012 waitForIdle(); 1013 } 1014 1015 // Bring up a network that we can use to send messages to ConnectivityService. 1016 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 1017 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1018 mWiFiAgent.connect(false); 1019 b.expectBroadcast(); 1020 Network n = mWiFiAgent.getNetwork(); 1021 assertNotNull(n); 1022 1023 // Tests that calling waitForIdle waits for messages to be processed. 1024 for (int i = 0; i < attempts; i++) { 1025 mWiFiAgent.setSignalStrength(i); 1026 waitForIdle(); 1027 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 1028 } 1029 } 1030 1031 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 1032 // or presubmit tests. It is kept for manual runs and documentation purposes. 1033 @Ignore verifyThatNotWaitingForIdleCausesRaceConditions()1034 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 1035 // Bring up a network that we can use to send messages to ConnectivityService. 1036 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 1037 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1038 mWiFiAgent.connect(false); 1039 b.expectBroadcast(); 1040 Network n = mWiFiAgent.getNetwork(); 1041 assertNotNull(n); 1042 1043 // Ensure that not calling waitForIdle causes a race condition. 1044 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 1045 for (int i = 0; i < attempts; i++) { 1046 mWiFiAgent.setSignalStrength(i); 1047 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 1048 // We hit a race condition, as expected. Pass the test. 1049 return; 1050 } 1051 } 1052 1053 // No race? There is a bug in this test. 1054 fail("expected race condition at least once in " + attempts + " attempts"); 1055 } 1056 1057 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 1058 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1059 // please add it in CSAgentWrapper and use subclasses of CSTest instead of adding more 1060 // tools in ConnectivityServiceTest. 1061 private static final int VALIDATION_RESULT_INVALID = 0; 1062 1063 private static final long DATA_STALL_TIMESTAMP = 10L; 1064 private static final int DATA_STALL_DETECTION_METHOD = 1; 1065 1066 private INetworkMonitor mNetworkMonitor; 1067 private INetworkMonitorCallbacks mNmCallbacks; 1068 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 1069 private int mProbesCompleted; 1070 private int mProbesSucceeded; 1071 private String mNmValidationRedirectUrl = null; 1072 private boolean mNmProvNotificationRequested = false; 1073 1074 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 1075 // Contains the redirectUrl from networkStatus(). Before reading, wait for 1076 // mNetworkStatusReceived. 1077 private String mRedirectUrl; 1078 TestNetworkAgentWrapper(int transport)1079 TestNetworkAgentWrapper(int transport) throws Exception { 1080 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, null); 1081 } 1082 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)1083 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 1084 throws Exception { 1085 this(transport, linkProperties, null /* ncTemplate */, null /* provider */, null); 1086 } 1087 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate)1088 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1089 NetworkCapabilities ncTemplate) throws Exception { 1090 this(transport, linkProperties, ncTemplate, null /* provider */, null); 1091 } 1092 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider)1093 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1094 NetworkCapabilities ncTemplate, NetworkProvider provider) throws Exception { 1095 this(transport, linkProperties, ncTemplate, provider /* provider */, null); 1096 } 1097 TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks)1098 private TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks) 1099 throws Exception { 1100 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, 1101 callbacks); 1102 } 1103 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider, NetworkAgentWrapper.Callbacks callbacks)1104 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1105 NetworkCapabilities ncTemplate, NetworkProvider provider, 1106 NetworkAgentWrapper.Callbacks callbacks) throws Exception { 1107 super(transport, linkProperties, ncTemplate, provider, callbacks, mServiceContext); 1108 mCreatedAgents.add(this); 1109 1110 // Waits for the NetworkAgent to be registered, which includes the creation of the 1111 // NetworkMonitor. 1112 waitForIdle(TIMEOUT_MS); 1113 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 1114 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 1115 } 1116 1117 class TestInstrumentedNetworkAgent extends InstrumentedNetworkAgent { TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, NetworkAgentConfig nac, NetworkProvider provider)1118 TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, 1119 NetworkAgentConfig nac, NetworkProvider provider) { 1120 super(wrapper, lp, nac, provider); 1121 } 1122 1123 @Override networkStatus(int status, String redirectUrl)1124 public void networkStatus(int status, String redirectUrl) { 1125 mRedirectUrl = redirectUrl; 1126 mNetworkStatusReceived.open(); 1127 } 1128 1129 } 1130 1131 @Override makeNetworkAgent(LinkProperties linkProperties, NetworkAgentConfig nac, NetworkProvider provider)1132 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, 1133 NetworkAgentConfig nac, NetworkProvider provider) throws Exception { 1134 mNetworkMonitor = mock(INetworkMonitor.class); 1135 1136 final Answer validateAnswer = inv -> { 1137 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 1138 return null; 1139 }; 1140 1141 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1142 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1143 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 1144 1145 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 1146 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 1147 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 1148 doNothing().when(mNetworkStack).makeNetworkMonitor( 1149 nmNetworkCaptor.capture(), 1150 any() /* name */, 1151 nmCbCaptor.capture()); 1152 1153 final InstrumentedNetworkAgent na = 1154 new TestInstrumentedNetworkAgent(this, linkProperties, nac, provider); 1155 1156 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 1157 mNmCallbacks = nmCbCaptor.getValue(); 1158 1159 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 1160 1161 return na; 1162 } 1163 onValidationRequested()1164 private void onValidationRequested() throws Exception { 1165 if (mDeps.isAtLeastT()) { 1166 verify(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1167 } else { 1168 verify(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1169 } 1170 if (mNmProvNotificationRequested 1171 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 1172 mNmCallbacks.hideProvisioningNotification(); 1173 mNmProvNotificationRequested = false; 1174 } 1175 1176 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 1177 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 1178 p.result = mNmValidationResult; 1179 p.probesAttempted = mProbesCompleted; 1180 p.probesSucceeded = mProbesSucceeded; 1181 p.redirectUrl = mNmValidationRedirectUrl; 1182 p.timestampMillis = TIMESTAMP; 1183 mNmCallbacks.notifyNetworkTestedWithExtras(p); 1184 1185 if (mNmValidationRedirectUrl != null) { 1186 mNmCallbacks.showProvisioningNotification( 1187 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 1188 mNmProvNotificationRequested = true; 1189 } 1190 } 1191 1192 /** 1193 * Connect without adding any internet capability. 1194 */ connectWithoutInternet()1195 public void connectWithoutInternet() { 1196 super.connect(); 1197 } 1198 1199 /** 1200 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 1201 * @param validated Indicate if network should pretend to be validated. 1202 */ connect(boolean validated)1203 public void connect(boolean validated) { 1204 connect(validated, true, false /* privateDnsProbeSent */); 1205 } 1206 1207 /** 1208 * Transition this NetworkAgent to CONNECTED state. 1209 * 1210 * @param validated Indicate if network should pretend to be validated. 1211 * Note that if this is true, this method will mock the NetworkMonitor 1212 * probes to pretend the network is invalid after it validated once, 1213 * so that subsequent attempts (with mNetworkMonitor.forceReevaluation) 1214 * will fail unless setNetworkValid is called again manually. 1215 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 1216 * @param privateDnsProbeSent whether the private DNS probe should be considered to have 1217 * been sent, assuming |validated| is true. 1218 * If |validated| is false, |privateDnsProbeSent| is not used. 1219 * If |validated| is true and |privateDnsProbeSent| is false, 1220 * the probe has not been sent. 1221 * If |validated| is true and |privateDnsProbeSent| is true, 1222 * the probe has been sent and has succeeded. When the NM probes 1223 * are mocked to be invalid, private DNS is the reason this 1224 * network is invalid ; see @param |validated|. 1225 */ connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1226 public void connect(boolean validated, boolean hasInternet, 1227 boolean privateDnsProbeSent) { 1228 final ConditionVariable validatedCv = new ConditionVariable(); 1229 final ConditionVariable capsChangedCv = new ConditionVariable(); 1230 final NetworkRequest request = new NetworkRequest.Builder() 1231 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 1232 .clearCapabilities() 1233 .build(); 1234 if (validated) { 1235 setNetworkValid(privateDnsProbeSent); 1236 } 1237 final NetworkCallback callback = new NetworkCallback() { 1238 public void onCapabilitiesChanged(Network network, 1239 NetworkCapabilities networkCapabilities) { 1240 if (network.equals(getNetwork())) { 1241 capsChangedCv.open(); 1242 if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 1243 validatedCv.open(); 1244 } 1245 } 1246 } 1247 }; 1248 mCm.registerNetworkCallback(request, callback); 1249 1250 if (hasInternet) { 1251 addCapability(NET_CAPABILITY_INTERNET); 1252 } 1253 1254 connectWithoutInternet(); 1255 waitFor(capsChangedCv); 1256 1257 if (validated) { 1258 // Wait for network to validate. 1259 waitFor(validatedCv); 1260 setNetworkInvalid(privateDnsProbeSent); 1261 } 1262 mCm.unregisterNetworkCallback(callback); 1263 } 1264 connectWithCaptivePortal(String redirectUrl, boolean privateDnsProbeSent)1265 public void connectWithCaptivePortal(String redirectUrl, 1266 boolean privateDnsProbeSent) { 1267 setNetworkPortal(redirectUrl, privateDnsProbeSent); 1268 connect(false, true /* hasInternet */, privateDnsProbeSent); 1269 } 1270 connectWithPartialConnectivity()1271 public void connectWithPartialConnectivity() { 1272 setNetworkPartial(); 1273 connect(false); 1274 } 1275 connectWithPartialValidConnectivity(boolean privateDnsProbeSent)1276 public void connectWithPartialValidConnectivity(boolean privateDnsProbeSent) { 1277 setNetworkPartialValid(privateDnsProbeSent); 1278 connect(false, true /* hasInternet */, privateDnsProbeSent); 1279 } 1280 setNetworkValid(boolean privateDnsProbeSent)1281 void setNetworkValid(boolean privateDnsProbeSent) { 1282 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 1283 mNmValidationRedirectUrl = null; 1284 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 1285 if (privateDnsProbeSent) { 1286 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1287 } 1288 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 1289 // the same value into two different parameter of the method. 1290 setProbesStatus(probesSucceeded, probesSucceeded); 1291 } 1292 setNetworkInvalid(boolean invalidBecauseOfPrivateDns)1293 void setNetworkInvalid(boolean invalidBecauseOfPrivateDns) { 1294 mNmValidationResult = VALIDATION_RESULT_INVALID; 1295 mNmValidationRedirectUrl = null; 1296 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1297 | NETWORK_VALIDATION_PROBE_HTTP; 1298 int probesSucceeded = 0; 1299 // If |invalidBecauseOfPrivateDns| is true, it means the network is invalid because 1300 // NetworkMonitor tried to validate the private DNS but failed. Therefore it 1301 // didn't get a chance to try the HTTP probe. 1302 if (invalidBecauseOfPrivateDns) { 1303 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 1304 probesSucceeded = probesCompleted; 1305 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1306 } 1307 setProbesStatus(probesCompleted, probesSucceeded); 1308 } 1309 setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent)1310 void setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent) { 1311 setNetworkInvalid(privateDnsProbeSent); 1312 mNmValidationRedirectUrl = redirectUrl; 1313 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 1314 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 1315 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1316 int probesSucceeded = VALIDATION_RESULT_INVALID; 1317 if (privateDnsProbeSent) { 1318 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1319 } 1320 setProbesStatus(probesCompleted, probesSucceeded); 1321 } 1322 setNetworkPartial()1323 void setNetworkPartial() { 1324 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 1325 mNmValidationRedirectUrl = null; 1326 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1327 | NETWORK_VALIDATION_PROBE_FALLBACK; 1328 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 1329 setProbesStatus(probesCompleted, probesSucceeded); 1330 } 1331 setNetworkPartialValid(boolean privateDnsProbeSent)1332 void setNetworkPartialValid(boolean privateDnsProbeSent) { 1333 setNetworkPartial(); 1334 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 1335 mNmValidationRedirectUrl = null; 1336 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1337 | NETWORK_VALIDATION_PROBE_HTTP; 1338 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1339 // Assume the partial network cannot pass the private DNS validation as well, so only 1340 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 1341 if (privateDnsProbeSent) { 1342 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1343 } 1344 setProbesStatus(probesCompleted, probesSucceeded); 1345 } 1346 setProbesStatus(int probesCompleted, int probesSucceeded)1347 void setProbesStatus(int probesCompleted, int probesSucceeded) { 1348 mProbesCompleted = probesCompleted; 1349 mProbesSucceeded = probesSucceeded; 1350 } 1351 notifyCapportApiDataChanged(CaptivePortalData data)1352 void notifyCapportApiDataChanged(CaptivePortalData data) { 1353 try { 1354 mNmCallbacks.notifyCaptivePortalDataChanged(data); 1355 } catch (RemoteException e) { 1356 throw new AssertionError("This cannot happen", e); 1357 } 1358 } 1359 waitForRedirectUrl()1360 public String waitForRedirectUrl() { 1361 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 1362 return mRedirectUrl; 1363 } 1364 expectDisconnected()1365 public void expectDisconnected() { 1366 expectDisconnected(TIMEOUT_MS); 1367 } 1368 expectPreventReconnectReceived()1369 public void expectPreventReconnectReceived() { 1370 expectPreventReconnectReceived(TIMEOUT_MS); 1371 } 1372 notifyDataStallSuspected()1373 void notifyDataStallSuspected() throws Exception { 1374 final DataStallReportParcelable p = new DataStallReportParcelable(); 1375 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 1376 p.timestampMillis = DATA_STALL_TIMESTAMP; 1377 mNmCallbacks.notifyDataStallSuspected(p); 1378 } 1379 } 1380 1381 /** 1382 * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove 1383 * operations have been processed and test for them. 1384 */ 1385 private static class MockNetworkFactory extends NetworkFactory { 1386 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1387 // please add it in CSTest and use subclasses of CSTest instead of adding more 1388 // tools in ConnectivityServiceTest. 1389 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 1390 1391 static class RequestEntry { 1392 @NonNull 1393 public final NetworkRequest request; 1394 RequestEntry(@onNull final NetworkRequest request)1395 RequestEntry(@NonNull final NetworkRequest request) { 1396 this.request = request; 1397 } 1398 1399 static final class Add extends RequestEntry { Add(@onNull final NetworkRequest request)1400 Add(@NonNull final NetworkRequest request) { 1401 super(request); 1402 } 1403 } 1404 1405 static final class Remove extends RequestEntry { Remove(@onNull final NetworkRequest request)1406 Remove(@NonNull final NetworkRequest request) { 1407 super(request); 1408 } 1409 } 1410 1411 @Override toString()1412 public String toString() { 1413 return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; 1414 } 1415 } 1416 1417 // History of received requests adds and removes. 1418 private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = 1419 new ArrayTrackRecord<RequestEntry>().newReadHead(); 1420 failIfNull(@ullable final T obj, @Nullable final String message)1421 private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { 1422 if (null == obj) fail(null != message ? message : "Must not be null"); 1423 return obj; 1424 } 1425 expectRequestAdd()1426 public RequestEntry.Add expectRequestAdd() { 1427 return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, 1428 it -> it instanceof RequestEntry.Add), "Expected request add"); 1429 } 1430 expectRequestAdds(final int count)1431 public void expectRequestAdds(final int count) { 1432 for (int i = count; i > 0; --i) { 1433 expectRequestAdd(); 1434 } 1435 } 1436 expectRequestRemove()1437 public RequestEntry.Remove expectRequestRemove() { 1438 return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, 1439 it -> it instanceof RequestEntry.Remove), "Expected request remove"); 1440 } 1441 expectRequestRemoves(final int count)1442 public void expectRequestRemoves(final int count) { 1443 for (int i = count; i > 0; --i) { 1444 expectRequestRemove(); 1445 } 1446 } 1447 1448 // Used to collect the networks requests managed by this factory. This is a duplicate of 1449 // the internal information stored in the NetworkFactory (which is private). 1450 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 1451 private final HandlerThread mHandlerSendingRequests; 1452 MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter, HandlerThread threadSendingRequests)1453 public MockNetworkFactory(Looper looper, Context context, String logTag, 1454 NetworkCapabilities filter, HandlerThread threadSendingRequests) { 1455 super(looper, context, logTag, filter); 1456 mHandlerSendingRequests = threadSendingRequests; 1457 } 1458 getMyRequestCount()1459 public int getMyRequestCount() { 1460 return getRequestCount(); 1461 } 1462 startNetwork()1463 protected void startNetwork() { 1464 mNetworkStarted.set(true); 1465 } 1466 stopNetwork()1467 protected void stopNetwork() { 1468 mNetworkStarted.set(false); 1469 } 1470 getMyStartRequested()1471 public boolean getMyStartRequested() { 1472 return mNetworkStarted.get(); 1473 } 1474 1475 1476 @Override needNetworkFor(NetworkRequest request)1477 protected void needNetworkFor(NetworkRequest request) { 1478 mNetworkRequests.put(request.requestId, request); 1479 super.needNetworkFor(request); 1480 mRequestHistory.add(new RequestEntry.Add(request)); 1481 } 1482 1483 @Override releaseNetworkFor(NetworkRequest request)1484 protected void releaseNetworkFor(NetworkRequest request) { 1485 mNetworkRequests.remove(request.requestId); 1486 super.releaseNetworkFor(request); 1487 mRequestHistory.add(new RequestEntry.Remove(request)); 1488 } 1489 assertRequestCountEquals(final int count)1490 public void assertRequestCountEquals(final int count) { 1491 assertEquals(count, getMyRequestCount()); 1492 } 1493 1494 // Trigger releasing the request as unfulfillable triggerUnfulfillable(NetworkRequest r)1495 public void triggerUnfulfillable(NetworkRequest r) { 1496 super.releaseRequestAsUnfulfillableByAnyFactory(r); 1497 } 1498 assertNoRequestChanged()1499 public void assertNoRequestChanged() { 1500 // Make sure there are no remaining requests unaccounted for. 1501 HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); 1502 assertNull(mRequestHistory.poll(0, r -> true)); 1503 } 1504 } 1505 uidRangesForUids(int... uids)1506 private Set<UidRange> uidRangesForUids(int... uids) { 1507 final ArraySet<UidRange> ranges = new ArraySet<>(); 1508 for (final int uid : uids) { 1509 ranges.add(new UidRange(uid, uid)); 1510 } 1511 return ranges; 1512 } 1513 uidRangesForUids(Collection<Integer> uids)1514 private Set<UidRange> uidRangesForUids(Collection<Integer> uids) { 1515 return uidRangesForUids(CollectionUtils.toIntArray(uids)); 1516 } 1517 1518 // Helper class to mock vpn interaction. 1519 private class MockVpn implements TestableNetworkCallback.HasNetwork { 1520 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1521 // please add it in CSTest and use subclasses of CSTest instead of adding more 1522 // tools in ConnectivityServiceTest. 1523 1524 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1525 // not inherit from NetworkAgent. 1526 private TestNetworkAgentWrapper mMockNetworkAgent; 1527 // Initialize a stored NetworkCapabilities following the defaults of VPN. The TransportInfo 1528 // should at least be updated to a valid VPN type before usage, see registerAgent(...). 1529 private NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities.Builder() 1530 .addTransportType(NetworkCapabilities.TRANSPORT_VPN) 1531 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) 1532 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) 1533 .setTransportInfo(new VpnTransportInfo( 1534 VpnManager.TYPE_VPN_NONE, 1535 null /* sessionId */, 1536 false /* bypassable */, 1537 false /* longLivedTcpConnectionsExpensive */)) 1538 .build(); 1539 private boolean mAgentRegistered = false; 1540 1541 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1542 private String mSessionKey; 1543 setUids(Set<UidRange> uids)1544 public void setUids(Set<UidRange> uids) { 1545 mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); 1546 if (mAgentRegistered) { 1547 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); 1548 } 1549 } 1550 setVpnType(int vpnType)1551 public void setVpnType(int vpnType) { 1552 mVpnType = vpnType; 1553 } 1554 getNetwork()1555 public Network getNetwork() { 1556 return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); 1557 } 1558 getNetworkAgentConfig()1559 public NetworkAgentConfig getNetworkAgentConfig() { 1560 return null == mMockNetworkAgent ? null : mMockNetworkAgent.getNetworkAgentConfig(); 1561 } 1562 getActiveVpnType()1563 public int getActiveVpnType() { 1564 return mVpnType; 1565 } 1566 makeLinkProperties()1567 private LinkProperties makeLinkProperties() { 1568 final LinkProperties lp = new LinkProperties(); 1569 lp.setInterfaceName(VPN_IFNAME); 1570 return lp; 1571 } 1572 registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)1573 private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) 1574 throws Exception { 1575 if (mAgentRegistered) throw new IllegalStateException("already registered"); 1576 final String session = "MySession12345"; 1577 setUids(uids); 1578 if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 1579 mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), 1580 session)); 1581 mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, 1582 mNetworkCapabilities); 1583 mMockNetworkAgent.waitForIdle(TIMEOUT_MS); 1584 1585 verify(mMockNetd, times(1)).networkAddUidRangesParcel( 1586 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 1587 toUidRangeStableParcels(uids), PREFERENCE_ORDER_VPN)); 1588 verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config -> 1589 mMockVpn.getNetwork().getNetId() == config.netId 1590 && PREFERENCE_ORDER_VPN == config.subPriority)); 1591 mAgentRegistered = true; 1592 verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, 1593 !mMockNetworkAgent.isBypassableVpn(), mVpnType)); 1594 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1595 } 1596 registerAgent(Set<UidRange> uids)1597 private void registerAgent(Set<UidRange> uids) throws Exception { 1598 registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); 1599 } 1600 connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1601 private void connect(boolean validated, boolean hasInternet, 1602 boolean privateDnsProbeSent) { 1603 mMockNetworkAgent.connect(validated, hasInternet, privateDnsProbeSent); 1604 } 1605 connect(boolean validated)1606 private void connect(boolean validated) { 1607 mMockNetworkAgent.connect(validated); 1608 } 1609 getAgent()1610 private TestNetworkAgentWrapper getAgent() { 1611 return mMockNetworkAgent; 1612 } 1613 setOwnerAndAdminUid(int uid)1614 private void setOwnerAndAdminUid(int uid) throws Exception { 1615 mNetworkCapabilities.setOwnerUid(uid); 1616 mNetworkCapabilities.setAdministratorUids(new int[]{uid}); 1617 } 1618 establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1619 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, 1620 boolean hasInternet, boolean privateDnsProbeSent) throws Exception { 1621 setOwnerAndAdminUid(uid); 1622 registerAgent(false, ranges, lp); 1623 connect(validated, hasInternet, privateDnsProbeSent); 1624 waitForIdle(); 1625 } 1626 establish(LinkProperties lp, int uid, Set<UidRange> ranges)1627 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { 1628 establish(lp, uid, ranges, true, true, false); 1629 } 1630 establishForMyUid(LinkProperties lp)1631 public void establishForMyUid(LinkProperties lp) throws Exception { 1632 final int uid = Process.myUid(); 1633 establish(lp, uid, uidRangesForUids(uid), true, true, false); 1634 } 1635 establishForMyUid(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1636 public void establishForMyUid(boolean validated, boolean hasInternet, 1637 boolean privateDnsProbeSent) throws Exception { 1638 final int uid = Process.myUid(); 1639 establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, 1640 privateDnsProbeSent); 1641 } 1642 establishForMyUid()1643 public void establishForMyUid() throws Exception { 1644 establishForMyUid(makeLinkProperties()); 1645 } 1646 sendLinkProperties(LinkProperties lp)1647 public void sendLinkProperties(LinkProperties lp) { 1648 mMockNetworkAgent.sendLinkProperties(lp); 1649 } 1650 disconnect()1651 public void disconnect() { 1652 if (mMockNetworkAgent != null) { 1653 mMockNetworkAgent.disconnect(); 1654 } 1655 mAgentRegistered = false; 1656 setUids(null); 1657 // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. 1658 mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); 1659 } 1660 startLegacyVpn()1661 private void startLegacyVpn() { 1662 // Do nothing. 1663 } 1664 1665 // Mock the interaction of IkeV2VpnRunner start. In the context of ConnectivityService, 1666 // setVpnDefaultForUids() is the main interaction and a sessionKey is stored. startPlatformVpn()1667 private void startPlatformVpn() { 1668 mSessionKey = UUID.randomUUID().toString(); 1669 // Assuming no disallowed applications 1670 final Set<Range<Integer>> ranges = UidRange.toIntRanges(Set.of(PRIMARY_UIDRANGE)); 1671 mCm.setVpnDefaultForUids(mSessionKey, ranges); 1672 // Wait for vpn network preference updates. 1673 waitForIdle(); 1674 } 1675 startLegacyVpnPrivileged(boolean isIkev2Vpn)1676 public void startLegacyVpnPrivileged(boolean isIkev2Vpn) { 1677 if (isIkev2Vpn) { 1678 startPlatformVpn(); 1679 } else { 1680 startLegacyVpn(); 1681 } 1682 } 1683 stopVpnRunnerPrivileged()1684 public void stopVpnRunnerPrivileged() { 1685 if (mSessionKey != null) { 1686 // Clear vpn network preference. 1687 mCm.setVpnDefaultForUids(mSessionKey, Collections.EMPTY_LIST); 1688 mSessionKey = null; 1689 } 1690 disconnect(); 1691 } 1692 setUnderlyingNetworks(@ullable Network[] networks)1693 public boolean setUnderlyingNetworks(@Nullable Network[] networks) { 1694 if (!mAgentRegistered) return false; 1695 mMockNetworkAgent.setUnderlyingNetworks( 1696 (networks == null) ? null : Arrays.asList(networks)); 1697 return true; 1698 } 1699 } 1700 toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)1701 private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 1702 return ranges.stream().map( 1703 r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); 1704 } 1705 intToUidRangeStableParcels(final @NonNull Set<Integer> ranges)1706 private UidRangeParcel[] intToUidRangeStableParcels(final @NonNull Set<Integer> ranges) { 1707 return ranges.stream().map(r -> new UidRangeParcel(r, r)).toArray(UidRangeParcel[]::new); 1708 } 1709 intToUidRangeStableParcels( final @NonNull List<Range<Integer>> ranges)1710 private static UidRangeParcel[] intToUidRangeStableParcels( 1711 final @NonNull List<Range<Integer>> ranges) { 1712 return ranges.stream().map( 1713 r -> new UidRangeParcel(r.getLower(), r.getUpper())).toArray(UidRangeParcel[]::new); 1714 } 1715 assertVpnTransportInfo(NetworkCapabilities nc, int type)1716 private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { 1717 assertNotNull(nc); 1718 final TransportInfo ti = nc.getTransportInfo(); 1719 assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, 1720 ti instanceof VpnTransportInfo); 1721 assertEquals(type, ((VpnTransportInfo) ti).getType()); 1722 1723 } 1724 processBroadcast(Intent intent)1725 private void processBroadcast(Intent intent) { 1726 mServiceContext.sendBroadcast(intent); 1727 waitForIdle(); 1728 } 1729 mockUidNetworkingBlocked()1730 private void mockUidNetworkingBlocked() { 1731 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1732 ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1733 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1734 ).when(mBpfNetMaps).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1735 } 1736 isUidBlocked(int blockedReasons, boolean meteredNetwork)1737 private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { 1738 final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); 1739 if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { 1740 return true; 1741 } 1742 if (meteredNetwork) { 1743 return blockedReasons != BLOCKED_REASON_NONE; 1744 } 1745 return false; 1746 } 1747 setBlockedReasonChanged(int blockedReasons)1748 private void setBlockedReasonChanged(int blockedReasons) { 1749 mBlockedReasons = blockedReasons; 1750 if (mDeps.isAtLeastV()) { 1751 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), 1752 () -> mService.handleBlockedReasonsChanged( 1753 List.of(new Pair<>(Process.myUid(), blockedReasons)) 1754 1755 )); 1756 } else { 1757 mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); 1758 } 1759 } 1760 getNat464Xlat(NetworkAgentWrapper mna)1761 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1762 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1763 } 1764 1765 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1766 volatile int mConfigMeteredMultipathPreference; 1767 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r)1768 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1769 super(c, h, r, new MultinetworkPolicyTrackerTestDependencies(mResources)); 1770 } 1771 1772 @Override configMeteredMultipathPreference()1773 public int configMeteredMultipathPreference() { 1774 return mConfigMeteredMultipathPreference; 1775 } 1776 } 1777 1778 /** 1779 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1780 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1781 */ waitFor(ConditionVariable conditionVariable)1782 static private void waitFor(ConditionVariable conditionVariable) { 1783 if (conditionVariable.block(TIMEOUT_MS)) { 1784 return; 1785 } 1786 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1787 } 1788 doAsUid(final int uid, @NonNull final Supplier<T> what)1789 private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { 1790 mDeps.setCallingUid(uid); 1791 try { 1792 return what.get(); 1793 } finally { 1794 mDeps.setCallingUid(null); 1795 } 1796 } 1797 doAsUid(final int uid, @NonNull final Runnable what)1798 private void doAsUid(final int uid, @NonNull final Runnable what) { 1799 doAsUid(uid, () -> { 1800 what.run(); return Void.TYPE; 1801 }); 1802 } 1803 registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, int uid)1804 private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, 1805 int uid) { 1806 doAsUid(uid, () -> { 1807 mCm.registerNetworkCallback(request, callback); 1808 }); 1809 } 1810 registerDefaultNetworkCallbackAsUid(@onNull final NetworkCallback callback, final int uid)1811 private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, 1812 final int uid) { 1813 doAsUid(uid, () -> { 1814 mCm.registerDefaultNetworkCallback(callback); 1815 waitForIdle(); 1816 }); 1817 } 1818 withPermission(String permission, ThrowingRunnable r)1819 private void withPermission(String permission, ThrowingRunnable r) throws Exception { 1820 try { 1821 mServiceContext.setPermission(permission, PERMISSION_GRANTED); 1822 r.run(); 1823 } finally { 1824 mServiceContext.setPermission(permission, null); 1825 } 1826 } 1827 withPermission(String permission, int pid, int uid, ThrowingRunnable r)1828 private void withPermission(String permission, int pid, int uid, ThrowingRunnable r) 1829 throws Exception { 1830 try { 1831 mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED); 1832 r.run(); 1833 } finally { 1834 mServiceContext.setPermission(permission, pid, uid, null); 1835 } 1836 } 1837 1838 private static final int PRIMARY_USER = 0; 1839 private static final int SECONDARY_USER = 10; 1840 private static final int TERTIARY_USER = 11; 1841 private static final UidRange PRIMARY_UIDRANGE = 1842 UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 1843 private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); 1844 private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); 1845 private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); 1846 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", 1847 UserInfo.FLAG_PRIMARY); 1848 private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); 1849 private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER); 1850 private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER); 1851 1852 private static final int RESTRICTED_USER = 1; 1853 private static final UidRange RESTRICTED_USER_UIDRANGE = 1854 UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 1855 private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", 1856 UserInfo.FLAG_RESTRICTED); 1857 static { 1858 RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; 1859 } 1860 1861 @Before setUp()1862 public void setUp() throws Exception { 1863 mNetIdManager = new TestNetIdManager(); 1864 1865 mContext = InstrumentationRegistry.getContext(); 1866 1867 MockitoAnnotations.initMocks(this); 1868 1869 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1870 // please add it in CSTest and use subclasses of CSTest instead of adding more 1871 // tools in ConnectivityServiceTest. 1872 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 1873 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 1874 doReturn(PRIMARY_USER_INFO).when(mUserManager).getUserInfo(PRIMARY_USER); 1875 // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context 1876 // it was started from, i.e., PRIMARY_USER. 1877 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 1878 doReturn(RESTRICTED_USER_INFO).when(mUserManager).getUserInfo(RESTRICTED_USER); 1879 1880 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1881 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1882 doReturn(applicationInfo).when(mPackageManager) 1883 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 1884 doReturn(applicationInfo.targetSdkVersion).when(mPackageManager) 1885 .getTargetSdkVersion(anyString()); 1886 doReturn(new int[0]).when(mSystemConfigManager).getSystemPermissionUids(anyString()); 1887 1888 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1889 // http://b/25897652 . 1890 if (Looper.myLooper() == null) { 1891 Looper.prepare(); 1892 } 1893 mockDefaultPackages(); 1894 mockHasSystemFeature(FEATURE_WIFI, true); 1895 mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); 1896 mockHasSystemFeature(FEATURE_ETHERNET, true); 1897 doReturn(true).when(mTelephonyManager).isDataCapable(); 1898 1899 FakeSettingsProvider.clearSettingsProvider(); 1900 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1901 new FakeSettingsProvider()); 1902 mServiceContext.setUseRegisteredHandlers(true); 1903 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 1904 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 1905 mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED); 1906 mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED); 1907 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 1908 mServiceContext.setPermission(READ_DEVICE_CONFIG, PERMISSION_GRANTED); 1909 1910 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1911 mAlarmManagerThread.start(); 1912 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1913 1914 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1915 mProxyTracker = new ProxyTracker(mServiceContext, mock(Handler.class), 1916 16 /* EVENT_PROXY_HAS_CHANGED */); 1917 1918 initMockedResources(); 1919 final Context mockResContext = mock(Context.class); 1920 doReturn(mResources).when(mockResContext).getResources(); 1921 ConnectivityResources.setResourcesContextForTest(mockResContext); 1922 mDeps = new ConnectivityServiceDependencies(mockResContext); 1923 doReturn(true).when(mMockKeepaliveTrackerDependencies) 1924 .isAddressTranslationEnabled(mServiceContext); 1925 doReturn(new ConnectivityResources(mockResContext)).when(mMockKeepaliveTrackerDependencies) 1926 .createConnectivityResources(mServiceContext); 1927 doReturn(new int[] {1, 3, 0, 0}).when(mMockKeepaliveTrackerDependencies) 1928 .getSupportedKeepalives(mServiceContext); 1929 mAutoOnOffKeepaliveDependencies = 1930 new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext); 1931 mService = new ConnectivityService(mServiceContext, 1932 mMockDnsResolver, 1933 mock(IpConnectivityLog.class), 1934 mMockNetd, 1935 mDeps); 1936 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1937 mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; 1938 1939 if (mDeps.isAtLeastV()) { 1940 verify(mNetworkPolicyManager, never()).registerNetworkPolicyCallback(any(), any()); 1941 mPolicyCallback = null; 1942 } else { 1943 final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = 1944 ArgumentCaptor.forClass(NetworkPolicyCallback.class); 1945 verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), 1946 policyCallbackCaptor.capture()); 1947 mPolicyCallback = policyCallbackCaptor.getValue(); 1948 } 1949 1950 // Create local CM before sending system ready so that we can answer 1951 // getSystemService() correctly. 1952 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1953 mService.systemReadyInternal(); 1954 verify(mMockDnsResolver).registerUnsolicitedEventListener(any()); 1955 1956 mMockVpn = new MockVpn(); 1957 mCm.bindProcessToNetwork(null); 1958 mQosCallbackTracker = mock(QosCallbackTracker.class); 1959 1960 // Ensure that the default setting for Captive Portals is used for most tests 1961 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 1962 setAlwaysOnNetworks(false); 1963 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1964 1965 mDeps.setChangeIdEnabled( 1966 true, NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, Process.myUid()); 1967 doReturn(PERMISSION_INTERNET).when(mBpfNetMaps).getNetPermForUid(anyInt()); 1968 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1969 // please add it in CSTest and use subclasses of CSTest instead of adding more 1970 // tools in ConnectivityServiceTest. 1971 } 1972 initMockedResources()1973 private void initMockedResources() { 1974 doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); 1975 doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); 1976 doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( 1977 R.array.config_wakeonlan_supported_interfaces); 1978 doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( 1979 R.array.config_networkSupportedKeepaliveCount); 1980 doReturn(new String[0]).when(mResources).getStringArray( 1981 R.array.config_networkNotifySwitches); 1982 doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( 1983 R.array.config_protectedNetworks); 1984 // We don't test the actual notification value strings, so just return an empty array. 1985 // It doesn't matter what the values are as long as it's not null. 1986 doReturn(new String[0]).when(mResources) 1987 .getStringArray(R.array.network_switch_type_name); 1988 1989 doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) 1990 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); 1991 doReturn(R.array.network_switch_type_name).when(mResources) 1992 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); 1993 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 1994 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 1995 doReturn(true).when(mResources) 1996 .getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1997 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 1998 R.integer.config_networkWakeupPacketMask); 1999 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 2000 R.integer.config_networkWakeupPacketMark); 2001 } 2002 2003 class ConnectivityServiceDependencies extends ConnectivityService.Dependencies { 2004 final ConnectivityResources mConnRes; 2005 final ArraySet<Pair<Long, Integer>> mEnabledChangeIds = new ArraySet<>(); 2006 2007 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 2008 // please add it in CSTest and use subclasses of CSTest instead of adding more 2009 // tools in ConnectivityServiceTest. ConnectivityServiceDependencies(final Context mockResContext)2010 ConnectivityServiceDependencies(final Context mockResContext) { 2011 mConnRes = new ConnectivityResources(mockResContext); 2012 } 2013 2014 @Override makeHandlerThread(@onNull final String tag)2015 public HandlerThread makeHandlerThread(@NonNull final String tag) { 2016 return mCsHandlerThread; 2017 } 2018 2019 @Override getNetworkStack()2020 public NetworkStackClientBase getNetworkStack() { 2021 return mNetworkStack; 2022 } 2023 2024 @Override makeProxyTracker(final Context context, final Handler handler)2025 public ProxyTracker makeProxyTracker(final Context context, final Handler handler) { 2026 return mProxyTracker; 2027 } 2028 2029 @Override makeNetIdManager()2030 public NetIdManager makeNetIdManager() { 2031 return mNetIdManager; 2032 } 2033 2034 @Override queryUserAccess(final int uid, final Network network, final ConnectivityService cs)2035 public boolean queryUserAccess(final int uid, final Network network, 2036 final ConnectivityService cs) { 2037 return true; 2038 } 2039 2040 @Override makeMultinetworkPolicyTracker(final Context c, final Handler h, final Runnable r)2041 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(final Context c, 2042 final Handler h, final Runnable r) { 2043 if (null != mPolicyTracker) { 2044 throw new IllegalStateException("Multinetwork policy tracker already initialized"); 2045 } 2046 mPolicyTracker = new WrappedMultinetworkPolicyTracker(mServiceContext, h, r); 2047 return mPolicyTracker; 2048 } 2049 2050 @Override makeAutomaticOnOffKeepaliveTracker(final Context c, final Handler h)2051 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker(final Context c, 2052 final Handler h) { 2053 return new AutomaticOnOffKeepaliveTracker(c, h, mAutoOnOffKeepaliveDependencies); 2054 } 2055 2056 @Override getResources(final Context ctx)2057 public ConnectivityResources getResources(final Context ctx) { 2058 return mConnRes; 2059 } 2060 2061 @Override makeLocationPermissionChecker(final Context context)2062 public LocationPermissionChecker makeLocationPermissionChecker(final Context context) { 2063 return new LocationPermissionChecker(context) { 2064 @Override 2065 protected int getCurrentUser() { 2066 return runAsShell(CREATE_USERS, () -> super.getCurrentUser()); 2067 } 2068 }; 2069 } 2070 2071 private BiConsumer<Integer, Integer> mCarrierPrivilegesLostListener; 2072 2073 @Override makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm, final boolean requestRestrictedWifiEnabled, BiConsumer<Integer, Integer> listener, @NonNull final Handler handler)2074 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 2075 @NonNull final Context context, 2076 @NonNull final TelephonyManager tm, 2077 final boolean requestRestrictedWifiEnabled, 2078 BiConsumer<Integer, Integer> listener, 2079 @NonNull final Handler handler) { 2080 mCarrierPrivilegesLostListener = listener; 2081 return mDeps.isAtLeastT() ? mCarrierPrivilegeAuthenticator : null; 2082 } 2083 2084 @Override makeSatelliteAccessController( @onNull final Context context, Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, @NonNull final Handler connectivityServiceInternalHandler)2085 public SatelliteAccessController makeSatelliteAccessController( 2086 @NonNull final Context context, 2087 Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, 2088 @NonNull final Handler connectivityServiceInternalHandler) { 2089 return mSatelliteAccessController; 2090 } 2091 2092 @Override intentFilterEquals(final PendingIntent a, final PendingIntent b)2093 public boolean intentFilterEquals(final PendingIntent a, final PendingIntent b) { 2094 return runAsShell(GET_INTENT_SENDER_INTENT, () -> a.intentFilterEquals(b)); 2095 } 2096 2097 @GuardedBy("this") 2098 private Integer mCallingUid = null; 2099 2100 @Override getCallingUid()2101 public int getCallingUid() { 2102 synchronized (this) { 2103 if (null != mCallingUid) return mCallingUid; 2104 return super.getCallingUid(); 2105 } 2106 } 2107 2108 // Pass null for the real calling UID setCallingUid(final Integer uid)2109 public void setCallingUid(final Integer uid) { 2110 synchronized (this) { 2111 mCallingUid = uid; 2112 } 2113 } 2114 2115 @GuardedBy("this") 2116 private boolean mCellular464XlatEnabled = true; 2117 2118 @Override getCellular464XlatEnabled()2119 public boolean getCellular464XlatEnabled() { 2120 synchronized (this) { 2121 return mCellular464XlatEnabled; 2122 } 2123 } 2124 setCellular464XlatEnabled(final boolean enabled)2125 public void setCellular464XlatEnabled(final boolean enabled) { 2126 synchronized (this) { 2127 mCellular464XlatEnabled = enabled; 2128 } 2129 } 2130 2131 @GuardedBy("this") 2132 private Integer mConnectionOwnerUid = null; 2133 2134 @Override getConnectionOwnerUid(final int protocol, final InetSocketAddress local, final InetSocketAddress remote)2135 public int getConnectionOwnerUid(final int protocol, final InetSocketAddress local, 2136 final InetSocketAddress remote) { 2137 synchronized (this) { 2138 if (null != mConnectionOwnerUid) return mConnectionOwnerUid; 2139 return super.getConnectionOwnerUid(protocol, local, remote); 2140 } 2141 } 2142 2143 // Pass null to get the production implementation of getConnectionOwnerUid setConnectionOwnerUid(final Integer uid)2144 public void setConnectionOwnerUid(final Integer uid) { 2145 synchronized (this) { 2146 mConnectionOwnerUid = uid; 2147 } 2148 } 2149 2150 final class ReportedInterfaces { 2151 public final Context context; 2152 public final String iface; 2153 public final int[] transportTypes; ReportedInterfaces(final Context c, final String i, final int[] t)2154 ReportedInterfaces(final Context c, final String i, final int[] t) { 2155 context = c; 2156 iface = i; 2157 transportTypes = t; 2158 } 2159 contentEquals(final Context c, final String i, final int[] t)2160 public boolean contentEquals(final Context c, final String i, final int[] t) { 2161 return Objects.equals(context, c) && Objects.equals(iface, i) 2162 && Arrays.equals(transportTypes, t); 2163 } 2164 } 2165 2166 final ArrayTrackRecord<ReportedInterfaces> mReportedInterfaceHistory = 2167 new ArrayTrackRecord<>(); 2168 2169 @Override reportNetworkInterfaceForTransports(final Context context, final String iface, final int[] transportTypes)2170 public void reportNetworkInterfaceForTransports(final Context context, final String iface, 2171 final int[] transportTypes) { 2172 mReportedInterfaceHistory.add(new ReportedInterfaces(context, iface, transportTypes)); 2173 super.reportNetworkInterfaceForTransports(context, iface, transportTypes); 2174 } 2175 2176 @Override isFeatureEnabled(Context context, String name)2177 public boolean isFeatureEnabled(Context context, String name) { 2178 switch (name) { 2179 case ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER: 2180 case ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK: 2181 case ConnectivityFlags.REQUEST_RESTRICTED_WIFI: 2182 case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS: 2183 case KEY_DESTROY_FROZEN_SOCKETS_VERSION: 2184 return true; 2185 default: 2186 return super.isFeatureEnabled(context, name); 2187 } 2188 } 2189 2190 @Override isFeatureNotChickenedOut(Context context, String name)2191 public boolean isFeatureNotChickenedOut(Context context, String name) { 2192 switch (name) { 2193 case ALLOW_SYSUI_CONNECTIVITY_REPORTS: 2194 return true; 2195 case ALLOW_SATALLITE_NETWORK_FALLBACK: 2196 return true; 2197 case INGRESS_TO_VPN_ADDRESS_FILTERING: 2198 return true; 2199 case BACKGROUND_FIREWALL_CHAIN: 2200 return true; 2201 case DELAY_DESTROY_SOCKETS: 2202 return true; 2203 default: 2204 return super.isFeatureNotChickenedOut(context, name); 2205 } 2206 } 2207 setChangeIdEnabled(final boolean enabled, final long changeId, final int uid)2208 public void setChangeIdEnabled(final boolean enabled, final long changeId, final int uid) { 2209 final Pair<Long, Integer> data = new Pair<>(changeId, uid); 2210 // mEnabledChangeIds is read on the handler thread and maybe the test thread, so 2211 // make sure both threads see it before continuing. 2212 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> { 2213 if (enabled) { 2214 mEnabledChangeIds.add(data); 2215 } else { 2216 mEnabledChangeIds.remove(data); 2217 } 2218 }); 2219 } 2220 2221 @Override isChangeEnabled(final long changeId, final int uid)2222 public boolean isChangeEnabled(final long changeId, final int uid) { 2223 return mEnabledChangeIds.contains(new Pair<>(changeId, uid)); 2224 } 2225 2226 // In AOSP, build version codes are all over the place (e.g. at the time of this writing 2227 // U == V). Define custom ones. 2228 private static final int VERSION_UNMOCKED = -1; 2229 private static final int VERSION_R = 1; 2230 private static final int VERSION_S = 2; 2231 private static final int VERSION_T = 3; 2232 private static final int VERSION_U = 4; 2233 private static final int VERSION_V = 5; 2234 private static final int VERSION_MAX = VERSION_V; 2235 private int mSdkLevel = VERSION_UNMOCKED; 2236 setBuildSdk(final int sdkLevel)2237 private void setBuildSdk(final int sdkLevel) { 2238 if (sdkLevel > VERSION_MAX) { 2239 throw new IllegalArgumentException("setBuildSdk must not be called with" 2240 + " Build.VERSION constants but Dependencies.VERSION_* constants"); 2241 } 2242 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> mSdkLevel = sdkLevel); 2243 } 2244 2245 @Override isAtLeastS()2246 public boolean isAtLeastS() { 2247 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastS() 2248 : mSdkLevel >= VERSION_S; 2249 } 2250 2251 @Override isAtLeastT()2252 public boolean isAtLeastT() { 2253 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastT() 2254 : mSdkLevel >= VERSION_T; 2255 } 2256 2257 @Override isAtLeastU()2258 public boolean isAtLeastU() { 2259 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastU() 2260 : mSdkLevel >= VERSION_U; 2261 } 2262 2263 @Override getBpfNetMaps(Context context, INetd netd)2264 public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { 2265 return mBpfNetMaps; 2266 } 2267 2268 @Override getClatCoordinator(INetd netd)2269 public ClatCoordinator getClatCoordinator(INetd netd) { 2270 return mClatCoordinator; 2271 } 2272 2273 final ArrayTrackRecord<Pair<String, Long>> mRateLimitHistory = new ArrayTrackRecord<>(); 2274 final Map<String, Long> mActiveRateLimit = new HashMap<>(); 2275 2276 @Override enableIngressRateLimit(final String iface, final long rateInBytesPerSecond)2277 public void enableIngressRateLimit(final String iface, final long rateInBytesPerSecond) { 2278 mRateLimitHistory.add(new Pair<>(iface, rateInBytesPerSecond)); 2279 // Due to a TC limitation, the rate limit needs to be removed before it can be 2280 // updated. Check that this happened. 2281 assertEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2282 mActiveRateLimit.put(iface, rateInBytesPerSecond); 2283 // verify that clsact qdisc has already been created, otherwise attaching a tc police 2284 // filter will fail. 2285 try { 2286 verify(mMockNetd).networkAddInterface(anyInt(), eq(iface)); 2287 } catch (RemoteException e) { 2288 fail(e.getMessage()); 2289 } 2290 } 2291 2292 @Override disableIngressRateLimit(final String iface)2293 public void disableIngressRateLimit(final String iface) { 2294 mRateLimitHistory.add(new Pair<>(iface, -1L)); 2295 assertNotEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2296 mActiveRateLimit.put(iface, -1L); 2297 } 2298 2299 @Override getBpfProgramId(final int attachType)2300 public int getBpfProgramId(final int attachType) { 2301 return 0; 2302 } 2303 2304 @Override makeBroadcastOptionsShim(BroadcastOptions options)2305 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 2306 reset(mBroadcastOptionsShim); 2307 return mBroadcastOptionsShim; 2308 } 2309 2310 @GuardedBy("this") 2311 private boolean mForceDisableCompatChangeCheck = true; 2312 2313 /** 2314 * By default, the {@link #isChangeEnabled(long, String, UserHandle)} will always return 2315 * true as the mForceDisableCompatChangeCheck is true and compat change check logic is 2316 * never executed. The compat change check logic can be turned on by calling this method. 2317 * If this method is called, the 2318 * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} or 2319 * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} must be 2320 * used to turn on/off the compat change flag. 2321 */ enableCompatChangeCheck()2322 private void enableCompatChangeCheck() { 2323 synchronized (this) { 2324 mForceDisableCompatChangeCheck = false; 2325 } 2326 } 2327 2328 @Override isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)2329 public boolean isChangeEnabled(long changeId, 2330 @NonNull final String packageName, 2331 @NonNull final UserHandle user) { 2332 synchronized (this) { 2333 if (mForceDisableCompatChangeCheck) { 2334 return false; 2335 } else { 2336 return super.isChangeEnabled(changeId, packageName, user); 2337 } 2338 } 2339 } 2340 2341 // Class to be mocked and used to verify destroy sockets methods call 2342 public class DestroySocketsWrapper { destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2343 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2344 final Set<Integer> exemptUids){} destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2345 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids){} 2346 } 2347 2348 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2349 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2350 final Set<Integer> exemptUids) { 2351 // Call mocked destroyLiveTcpSockets so that test can verify this method call 2352 mDestroySocketsWrapper.destroyLiveTcpSockets(ranges, exemptUids); 2353 } 2354 2355 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2356 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) { 2357 // Call mocked destroyLiveTcpSocketsByOwnerUids so that test can verify this method call 2358 // Create copy of ownerUids so that tests can verify the correct value even if the 2359 // ConnectivityService update the ownerUids after this method call. 2360 mDestroySocketsWrapper.destroyLiveTcpSocketsByOwnerUids(new ArraySet<>(ownerUids)); 2361 } 2362 2363 final ArrayTrackRecord<Pair<Integer, Long>>.ReadHead mScheduledEvaluationTimeouts = 2364 new ArrayTrackRecord<Pair<Integer, Long>>().newReadHead(); 2365 @Override scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)2366 public void scheduleEvaluationTimeout(@NonNull Handler handler, 2367 @NonNull final Network network, final long delayMs) { 2368 mScheduledEvaluationTimeouts.add(new Pair<>(network.netId, delayMs)); 2369 super.scheduleEvaluationTimeout(handler, network, delayMs); 2370 } 2371 } 2372 2373 private class AutomaticOnOffKeepaliveTrackerDependencies 2374 extends AutomaticOnOffKeepaliveTracker.Dependencies { 2375 AutomaticOnOffKeepaliveTrackerDependencies(Context context) { 2376 super(context); 2377 } 2378 2379 @Override 2380 public boolean isTetheringFeatureNotChickenedOut(@NonNull final String name) { 2381 // Tests for enabling the feature are verified in AutomaticOnOffKeepaliveTrackerTest. 2382 // Assuming enabled here to focus on ConnectivityService tests. 2383 return true; 2384 } 2385 public KeepaliveTracker newKeepaliveTracker(@NonNull Context context, 2386 @NonNull Handler connectivityserviceHander) { 2387 return new KeepaliveTracker(context, connectivityserviceHander, 2388 new TcpKeepaliveController(connectivityserviceHander), 2389 mMockKeepaliveTrackerDependencies); 2390 } 2391 } 2392 2393 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 2394 doAnswer(inv -> { 2395 final long when = inv.getArgument(1); 2396 final WakeupMessage wakeupMsg = inv.getArgument(3); 2397 final Handler handler = inv.getArgument(4); 2398 2399 long delayMs = when - SystemClock.elapsedRealtime(); 2400 if (delayMs < 0) delayMs = 0; 2401 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 2402 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 2403 + "ms into the future: " + delayMs); 2404 } 2405 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 2406 delayMs); 2407 2408 return null; 2409 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 2410 any(WakeupMessage.class), any()); 2411 2412 doAnswer(inv -> { 2413 final WakeupMessage wakeupMsg = inv.getArgument(0); 2414 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 2415 return null; 2416 }).when(am).cancel(any(WakeupMessage.class)); 2417 } 2418 2419 @After 2420 public void tearDown() throws Exception { 2421 unregisterDefaultNetworkCallbacks(); 2422 maybeTearDownEnterpriseNetwork(); 2423 setAlwaysOnNetworks(false); 2424 if (mCellAgent != null) { 2425 mCellAgent.disconnect(); 2426 mCellAgent = null; 2427 } 2428 if (mWiFiAgent != null) { 2429 mWiFiAgent.disconnect(); 2430 mWiFiAgent = null; 2431 } 2432 if (mEthernetAgent != null) { 2433 mEthernetAgent.disconnect(); 2434 mEthernetAgent = null; 2435 } 2436 2437 if (mQosCallbackMockHelper != null) { 2438 mQosCallbackMockHelper.tearDown(); 2439 mQosCallbackMockHelper = null; 2440 } 2441 mMockVpn.disconnect(); 2442 waitForIdle(); 2443 2444 FakeSettingsProvider.clearSettingsProvider(); 2445 ConnectivityResources.setResourcesContextForTest(null); 2446 2447 for (TestNetworkAgentWrapper agent : mCreatedAgents) { 2448 agent.destroy(); 2449 } 2450 mCreatedAgents.clear(); 2451 2452 mCsHandlerThread.quitSafely(); 2453 mCsHandlerThread.join(); 2454 mAlarmManagerThread.quitSafely(); 2455 mAlarmManagerThread.join(); 2456 } 2457 2458 private void mockDefaultPackages() throws Exception { 2459 final String myPackageName = mContext.getPackageName(); 2460 final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( 2461 myPackageName, PackageManager.GET_PERMISSIONS); 2462 myPackageInfo.setLongVersionCode(9_999_999L); 2463 doReturn(new String[] {myPackageName}).when(mPackageManager) 2464 .getPackagesForUid(Binder.getCallingUid()); 2465 doReturn(myPackageInfo).when(mPackageManager).getPackageInfoAsUser( 2466 eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())); 2467 2468 doReturn(asList(new PackageInfo[] { 2469 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 2470 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 2471 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 2472 })).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); 2473 2474 final ModuleInfo moduleInfo = new ModuleInfo(); 2475 moduleInfo.setPackageName(TETHERING_MODULE_NAME); 2476 doReturn(moduleInfo).when(mPackageManager) 2477 .getModuleInfo(TETHERING_MODULE_NAME, PackageManager.MODULE_APEX_NAME); 2478 doReturn(myPackageInfo).when(mPackageManager) 2479 .getPackageInfo(TETHERING_MODULE_NAME, PackageManager.MATCH_APEX); 2480 2481 // Create a fake always-on VPN package. 2482 final int userId = UserHandle.getCallingUserId(); 2483 final ApplicationInfo applicationInfo = new ApplicationInfo(); 2484 applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. 2485 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 2486 eq(ALWAYS_ON_PACKAGE), anyInt(), eq(userId)); 2487 2488 // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. 2489 ResolveInfo rInfo = new ResolveInfo(); 2490 rInfo.serviceInfo = new ServiceInfo(); 2491 rInfo.serviceInfo.metaData = new Bundle(); 2492 final List<ResolveInfo> services = asList(new ResolveInfo[]{rInfo}); 2493 doReturn(services).when(mPackageManager).queryIntentServicesAsUser( 2494 any(), eq(PackageManager.GET_META_DATA), eq(userId)); 2495 doReturn(Process.myUid()).when(mPackageManager).getPackageUidAsUser( 2496 TEST_PACKAGE_NAME, userId); 2497 doReturn(VPN_UID).when(mPackageManager).getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId); 2498 } 2499 2500 private void verifyActiveNetwork(int transport) { 2501 // Test getActiveNetworkInfo() 2502 assertNotNull(mCm.getActiveNetworkInfo()); 2503 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 2504 // Test getActiveNetwork() 2505 assertNotNull(mCm.getActiveNetwork()); 2506 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 2507 if (!NetworkCapabilities.isValidTransport(transport)) { 2508 throw new IllegalStateException("Unknown transport " + transport); 2509 } 2510 switch (transport) { 2511 case TRANSPORT_WIFI: 2512 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 2513 break; 2514 case TRANSPORT_CELLULAR: 2515 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 2516 break; 2517 case TRANSPORT_ETHERNET: 2518 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 2519 break; 2520 default: 2521 break; 2522 } 2523 // Test getNetworkInfo(Network) 2524 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 2525 assertEquals(transportToLegacyType(transport), 2526 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 2527 assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); 2528 // Test getNetworkCapabilities(Network) 2529 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 2530 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 2531 } 2532 2533 private void verifyNoNetwork() { 2534 waitForIdle(); 2535 // Test getActiveNetworkInfo() 2536 assertNull(mCm.getActiveNetworkInfo()); 2537 // Test getActiveNetwork() 2538 assertNull(mCm.getActiveNetwork()); 2539 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 2540 // Test getAllNetworks() 2541 assertEmpty(mCm.getAllNetworks()); 2542 assertEmpty(mCm.getAllNetworkStateSnapshots()); 2543 } 2544 2545 /** 2546 * Class to simplify expecting broadcasts using BroadcastInterceptingContext. 2547 * Ensures that the receiver is unregistered after the expected broadcast is received. This 2548 * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs 2549 * the receivers' receive method while iterating over the list of receivers, and unregistering 2550 * the receiver during iteration throws ConcurrentModificationException. 2551 */ 2552 private class ExpectedBroadcast extends CompletableFuture<Intent> { 2553 private final BroadcastReceiver mReceiver; 2554 2555 ExpectedBroadcast(BroadcastReceiver receiver) { 2556 mReceiver = receiver; 2557 } 2558 2559 public Intent expectBroadcast(int timeoutMs) throws Exception { 2560 try { 2561 return get(timeoutMs, TimeUnit.MILLISECONDS); 2562 } catch (TimeoutException e) { 2563 fail("Expected broadcast not received after " + timeoutMs + " ms"); 2564 return null; 2565 } finally { 2566 mServiceContext.unregisterReceiver(mReceiver); 2567 } 2568 } 2569 2570 public Intent expectBroadcast() throws Exception { 2571 return expectBroadcast(BROADCAST_TIMEOUT_MS); 2572 } 2573 2574 public void expectNoBroadcast(int timeoutMs) throws Exception { 2575 waitForIdle(); 2576 try { 2577 final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); 2578 fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); 2579 } catch (TimeoutException expected) { 2580 } finally { 2581 mServiceContext.unregisterReceiver(mReceiver); 2582 } 2583 } 2584 } 2585 2586 private ExpectedBroadcast registerBroadcastReceiverThat(final String action, final int count, 2587 @NonNull final Predicate<Intent> filter) { 2588 final IntentFilter intentFilter = new IntentFilter(action); 2589 // AtomicReference allows receiver to access expected even though it is constructed later. 2590 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 2591 final BroadcastReceiver receiver = new BroadcastReceiver() { 2592 private int mRemaining = count; 2593 public void onReceive(Context context, Intent intent) { 2594 logIntent(intent); 2595 if (!filter.test(intent)) return; 2596 if (--mRemaining == 0) { 2597 expectedRef.get().complete(intent); 2598 } 2599 } 2600 }; 2601 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 2602 expectedRef.set(expected); 2603 mServiceContext.registerReceiver(receiver, intentFilter); 2604 return expected; 2605 } 2606 2607 private void logIntent(Intent intent) { 2608 final String action = intent.getAction(); 2609 if (CONNECTIVITY_ACTION.equals(action)) { 2610 final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2611 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2612 Log.d(TAG, "Received " + action + ", type=" + type + " ni=" + ni); 2613 } else if (PROXY_CHANGE_ACTION.equals(action)) { 2614 final ProxyInfo proxy = (ProxyInfo) intent.getExtra( 2615 Proxy.EXTRA_PROXY_INFO, ProxyInfo.buildPacProxy(Uri.EMPTY)); 2616 Log.d(TAG, "Received " + action + ", proxy = " + proxy); 2617 } else { 2618 throw new IllegalArgumentException("Unsupported logging " + action); 2619 } 2620 } 2621 2622 /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ 2623 private ExpectedBroadcast expectConnectivityAction(final int count) { 2624 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, count, intent -> true); 2625 } 2626 2627 private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { 2628 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, 1, intent -> { 2629 final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2630 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2631 return type == actualType 2632 && state == ni.getDetailedState() 2633 && extraInfoInBroadcastHasExpectedNullness(ni); 2634 }); 2635 } 2636 2637 /** Expects that PROXY_CHANGE_ACTION broadcast is received. */ 2638 private ExpectedBroadcast expectProxyChangeAction() { 2639 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> true); 2640 } 2641 2642 private ExpectedBroadcast expectProxyChangeAction(ProxyInfo proxy) { 2643 return expectProxyChangeAction(actualProxy -> proxy.equals(actualProxy)); 2644 } 2645 2646 private ExpectedBroadcast expectProxyChangeAction(Predicate<ProxyInfo> tester) { 2647 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> { 2648 final ProxyInfo actualProxy = (ProxyInfo) intent.getExtra(Proxy.EXTRA_PROXY_INFO, 2649 ProxyInfo.buildPacProxy(Uri.EMPTY)); 2650 return tester.test(actualProxy); 2651 }); 2652 } 2653 2654 private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { 2655 final DetailedState state = ni.getDetailedState(); 2656 if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; 2657 // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION 2658 // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also 2659 // nulls out extraInfo. 2660 if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; 2661 // Can't make any assertions about DISCONNECTED broadcasts. When a network actually 2662 // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo 2663 // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to 2664 // a network switch, extraInfo will likely be populated. 2665 // This is likely a bug in CS, but likely not one we can fix without impacting apps. 2666 return true; 2667 } 2668 2669 @Test 2670 public void testNetworkFeature() throws Exception { 2671 // Connect the cell agent and wait for the connected broadcast. 2672 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2673 mCellAgent.addCapability(NET_CAPABILITY_SUPL); 2674 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2675 mCellAgent.connect(true); 2676 b.expectBroadcast(); 2677 2678 // Build legacy request for SUPL. 2679 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 2680 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 2681 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 2682 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 2683 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 2684 2685 // File request, withdraw it and make sure no broadcast is sent 2686 b = expectConnectivityAction(1); 2687 final TestNetworkCallback callback = new TestNetworkCallback(); 2688 mCm.requestNetwork(legacyRequest, callback); 2689 callback.expect(AVAILABLE, mCellAgent); 2690 mCm.unregisterNetworkCallback(callback); 2691 b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent 2692 2693 // Disconnect the network and expect mobile disconnected broadcast. 2694 b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 2695 mCellAgent.disconnect(); 2696 b.expectBroadcast(); 2697 } 2698 2699 @Test 2700 public void testLingering() throws Exception { 2701 verifyNoNetwork(); 2702 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2703 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2704 assertNull(mCm.getActiveNetworkInfo()); 2705 assertNull(mCm.getActiveNetwork()); 2706 // Test bringing up validated cellular. 2707 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2708 mCellAgent.connect(true); 2709 b.expectBroadcast(); 2710 verifyActiveNetwork(TRANSPORT_CELLULAR); 2711 assertLength(2, mCm.getAllNetworks()); 2712 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2713 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2714 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiAgent.getNetwork()) 2715 || mCm.getAllNetworks()[1].equals(mWiFiAgent.getNetwork())); 2716 // Test bringing up validated WiFi. 2717 b = expectConnectivityAction(2); 2718 mWiFiAgent.connect(true); 2719 b.expectBroadcast(); 2720 verifyActiveNetwork(TRANSPORT_WIFI); 2721 assertLength(2, mCm.getAllNetworks()); 2722 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2723 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2724 assertTrue(mCm.getAllNetworks()[0].equals(mCellAgent.getNetwork()) 2725 || mCm.getAllNetworks()[1].equals(mCellAgent.getNetwork())); 2726 // Test cellular linger timeout. 2727 mCellAgent.expectDisconnected(); 2728 waitForIdle(); 2729 assertLength(1, mCm.getAllNetworks()); 2730 verifyActiveNetwork(TRANSPORT_WIFI); 2731 assertLength(1, mCm.getAllNetworks()); 2732 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 2733 // Test WiFi disconnect. 2734 b = expectConnectivityAction(1); 2735 mWiFiAgent.disconnect(); 2736 b.expectBroadcast(); 2737 verifyNoNetwork(); 2738 } 2739 2740 /** 2741 * Verify a newly created network will be inactive instead of torn down even if no one is 2742 * requesting. 2743 */ 2744 @Test 2745 public void testNewNetworkInactive() throws Exception { 2746 // Create a callback that monitoring the testing network. 2747 final TestNetworkCallback listenCallback = new TestNetworkCallback(); 2748 mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); 2749 2750 // 1. Create a network that is not requested by anyone, and does not satisfy any of the 2751 // default requests. Verify that the network will be inactive instead of torn down. 2752 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2753 mWiFiAgent.connectWithoutInternet(); 2754 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2755 listenCallback.assertNoCallback(); 2756 2757 // Verify that the network will be torn down after nascent expiry. A small period of time 2758 // is added in case of flakiness. 2759 final int nascentTimeoutMs = 2760 mService.mNascentDelayMs + mService.mNascentDelayMs / 4; 2761 listenCallback.expect(LOST, mWiFiAgent, nascentTimeoutMs); 2762 2763 // 2. Create a network that is satisfied by a request comes later. 2764 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2765 mWiFiAgent.connectWithoutInternet(); 2766 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2767 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2768 .addTransportType(TRANSPORT_WIFI).build(); 2769 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 2770 mCm.requestNetwork(wifiRequest, wifiCallback); 2771 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2772 2773 // Verify that the network will be kept since the request is still satisfied. And is able 2774 // to get disconnected as usual if the request is released after the nascent timer expires. 2775 listenCallback.assertNoCallback(nascentTimeoutMs); 2776 mCm.unregisterNetworkCallback(wifiCallback); 2777 listenCallback.expect(LOST, mWiFiAgent); 2778 2779 // 3. Create a network that is satisfied by a request comes later. 2780 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2781 mWiFiAgent.connectWithoutInternet(); 2782 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2783 mCm.requestNetwork(wifiRequest, wifiCallback); 2784 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2785 2786 // Verify that the network will still be torn down after the request gets removed. 2787 mCm.unregisterNetworkCallback(wifiCallback); 2788 listenCallback.expect(LOST, mWiFiAgent); 2789 2790 // There is no need to ensure that LOSING is never sent in the common case that the 2791 // network immediately satisfies a request that was already present, because it is already 2792 // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. 2793 2794 mCm.unregisterNetworkCallback(listenCallback); 2795 } 2796 2797 /** 2798 * Verify a newly created network will be inactive and switch to background if only background 2799 * request is satisfied. 2800 */ 2801 @Test 2802 public void testNewNetworkInactive_bgNetwork() throws Exception { 2803 // Create a callback that monitoring the wifi network. 2804 final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); 2805 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2806 .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); 2807 2808 // Create callbacks that can monitor background and foreground mobile networks. 2809 // This is done by granting using background networks permission before registration. Thus, 2810 // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. 2811 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2812 final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); 2813 final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); 2814 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2815 .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); 2816 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2817 .addTransportType(TRANSPORT_CELLULAR) 2818 .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); 2819 2820 // Connect wifi, which satisfies default request. 2821 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2822 mWiFiAgent.connect(true); 2823 wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 2824 2825 // Connect a cellular network, verify that satisfies only the background callback. 2826 setAlwaysOnNetworks(true); 2827 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2828 mCellAgent.connect(true); 2829 bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 2830 fgMobileListenCallback.assertNoCallback(); 2831 assertFalse(isForegroundNetwork(mCellAgent)); 2832 2833 mCellAgent.disconnect(); 2834 bgMobileListenCallback.expect(LOST, mCellAgent); 2835 fgMobileListenCallback.assertNoCallback(); 2836 2837 mCm.unregisterNetworkCallback(wifiListenCallback); 2838 mCm.unregisterNetworkCallback(bgMobileListenCallback); 2839 mCm.unregisterNetworkCallback(fgMobileListenCallback); 2840 } 2841 2842 @Test 2843 public void testBinderDeathAfterUnregister() throws Exception { 2844 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 2845 .addTransportType(TRANSPORT_WIFI) 2846 .build(); 2847 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 2848 final Messenger messenger = new Messenger(handler); 2849 final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>(); 2850 final Binder binder = new Binder() { 2851 private DeathRecipient mDeathRecipient; 2852 @Override 2853 public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2854 synchronized (this) { 2855 mDeathRecipient = recipient; 2856 } 2857 super.linkToDeath(recipient, flags); 2858 deathRecipient.complete(recipient); 2859 } 2860 2861 @Override 2862 public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2863 synchronized (this) { 2864 if (null == mDeathRecipient) { 2865 throw new IllegalStateException(); 2866 } 2867 mDeathRecipient = null; 2868 } 2869 return super.unlinkToDeath(recipient, flags); 2870 } 2871 }; 2872 final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder, 2873 NetworkCallback.FLAG_NONE, mContext.getOpPackageName(), 2874 mContext.getAttributionTag()); 2875 mService.releaseNetworkRequest(request); 2876 deathRecipient.get().binderDied(); 2877 // Wait for the release message to be processed. 2878 waitForIdle(); 2879 // After waitForIdle(), the message was processed and the service didn't crash. 2880 } 2881 2882 // TODO : migrate to @Parameterized 2883 @Test 2884 public void testValidatedCellularOutscoresUnvalidatedWiFi_CanTimeShare() throws Exception { 2885 // The behavior of this test should be the same whether the radio can time share or not. 2886 doTestValidatedCellularOutscoresUnvalidatedWiFi(true); 2887 } 2888 2889 // TODO : migrate to @Parameterized 2890 @Test 2891 public void testValidatedCellularOutscoresUnvalidatedWiFi_CannotTimeShare() throws Exception { 2892 doTestValidatedCellularOutscoresUnvalidatedWiFi(false); 2893 } 2894 2895 private void doTestValidatedCellularOutscoresUnvalidatedWiFi( 2896 final boolean cellRadioTimesharingCapable) throws Exception { 2897 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2898 // Test bringing up unvalidated WiFi 2899 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2900 ExpectedBroadcast b = expectConnectivityAction(1); 2901 mWiFiAgent.connect(false); 2902 b.expectBroadcast(); 2903 verifyActiveNetwork(TRANSPORT_WIFI); 2904 // Test bringing up unvalidated cellular 2905 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2906 mCellAgent.connect(false); 2907 waitForIdle(); 2908 verifyActiveNetwork(TRANSPORT_WIFI); 2909 // Test cellular disconnect. 2910 mCellAgent.disconnect(); 2911 waitForIdle(); 2912 verifyActiveNetwork(TRANSPORT_WIFI); 2913 // Test bringing up validated cellular 2914 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2915 b = expectConnectivityAction(2); 2916 mCellAgent.connect(true); 2917 b.expectBroadcast(); 2918 verifyActiveNetwork(TRANSPORT_CELLULAR); 2919 // Test cellular disconnect. 2920 b = expectConnectivityAction(2); 2921 mCellAgent.disconnect(); 2922 b.expectBroadcast(); 2923 verifyActiveNetwork(TRANSPORT_WIFI); 2924 // Test WiFi disconnect. 2925 b = expectConnectivityAction(1); 2926 mWiFiAgent.disconnect(); 2927 b.expectBroadcast(); 2928 verifyNoNetwork(); 2929 } 2930 2931 // TODO : migrate to @Parameterized 2932 @Test 2933 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CanTimeShare() throws Exception { 2934 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(true); 2935 } 2936 2937 // TODO : migrate to @Parameterized 2938 @Test 2939 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CannotTimeShare() throws Exception { 2940 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(false); 2941 } 2942 2943 private void doTestUnvalidatedWifiOutscoresUnvalidatedCellular( 2944 final boolean cellRadioTimesharingCapable) throws Exception { 2945 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2946 // Test bringing up unvalidated cellular. 2947 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2948 ExpectedBroadcast b = expectConnectivityAction(1); 2949 mCellAgent.connect(false); 2950 b.expectBroadcast(); 2951 verifyActiveNetwork(TRANSPORT_CELLULAR); 2952 // Test bringing up unvalidated WiFi. 2953 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2954 b = expectConnectivityAction(2); 2955 mWiFiAgent.connect(false); 2956 b.expectBroadcast(); 2957 verifyActiveNetwork(TRANSPORT_WIFI); 2958 // Test WiFi disconnect. 2959 b = expectConnectivityAction(2); 2960 mWiFiAgent.disconnect(); 2961 b.expectBroadcast(); 2962 verifyActiveNetwork(TRANSPORT_CELLULAR); 2963 // Test cellular disconnect. 2964 b = expectConnectivityAction(1); 2965 mCellAgent.disconnect(); 2966 b.expectBroadcast(); 2967 verifyNoNetwork(); 2968 } 2969 2970 // TODO : migrate to @Parameterized 2971 @Test 2972 public void testUnlingeringDoesNotValidate_CanTimeShare() throws Exception { 2973 doTestUnlingeringDoesNotValidate(true); 2974 } 2975 2976 // TODO : migrate to @Parameterized 2977 @Test 2978 public void testUnlingeringDoesNotValidate_CannotTimeShare() throws Exception { 2979 doTestUnlingeringDoesNotValidate(false); 2980 } 2981 2982 private void doTestUnlingeringDoesNotValidate( 2983 final boolean cellRadioTimesharingCapable) throws Exception { 2984 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2985 // Test bringing up unvalidated WiFi. 2986 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2987 ExpectedBroadcast b = expectConnectivityAction(1); 2988 mWiFiAgent.connect(false); 2989 b.expectBroadcast(); 2990 verifyActiveNetwork(TRANSPORT_WIFI); 2991 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 2992 NET_CAPABILITY_VALIDATED)); 2993 // Test bringing up validated cellular. 2994 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2995 b = expectConnectivityAction(2); 2996 mCellAgent.connect(true); 2997 b.expectBroadcast(); 2998 verifyActiveNetwork(TRANSPORT_CELLULAR); 2999 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3000 NET_CAPABILITY_VALIDATED)); 3001 // Test cellular disconnect. 3002 b = expectConnectivityAction(2); 3003 mCellAgent.disconnect(); 3004 b.expectBroadcast(); 3005 verifyActiveNetwork(TRANSPORT_WIFI); 3006 // Unlingering a network should not cause it to be marked as validated. 3007 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3008 NET_CAPABILITY_VALIDATED)); 3009 } 3010 3011 // TODO : migrate to @Parameterized 3012 @Test 3013 public void testRequestMigrationToSameTransport_CanTimeShare() throws Exception { 3014 // Simulate a device where the cell radio is capable of time sharing 3015 mService.mCellularRadioTimesharingCapable = true; 3016 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, true); 3017 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 3018 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 3019 } 3020 3021 // TODO : migrate to @Parameterized 3022 @Test 3023 public void testRequestMigrationToSameTransport_CannotTimeShare() throws Exception { 3024 // Simulate a device where the cell radio is not capable of time sharing 3025 mService.mCellularRadioTimesharingCapable = false; 3026 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, false); 3027 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 3028 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 3029 } 3030 3031 private void doTestRequestMigrationToSameTransport(final int transport, 3032 final boolean expectLingering) throws Exception { 3033 // To speed up tests the linger delay is very short by default in tests but this 3034 // test needs to make sure the delay is not incurred so a longer value is safer (it 3035 // reduces the risk that a bug exists but goes undetected). The alarm manager in the test 3036 // throws and crashes CS if this is set to anything more than the below constant though. 3037 mService.mLingerDelayMs = UNREASONABLY_LONG_ALARM_WAIT_MS; 3038 3039 final TestNetworkCallback generalCb = new TestNetworkCallback(); 3040 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 3041 mCm.registerNetworkCallback( 3042 new NetworkRequest.Builder().addTransportType(transport).build(), 3043 generalCb); 3044 mCm.registerDefaultNetworkCallback(defaultCb); 3045 3046 // Bring up net agent 1 3047 final TestNetworkAgentWrapper net1 = new TestNetworkAgentWrapper(transport); 3048 net1.connect(true); 3049 // Make sure the default request is on net 1 3050 generalCb.expectAvailableThenValidatedCallbacks(net1); 3051 defaultCb.expectAvailableThenValidatedCallbacks(net1); 3052 3053 // Bring up net 2 with primary and mms 3054 final TestNetworkAgentWrapper net2 = new TestNetworkAgentWrapper(transport); 3055 net2.addCapability(NET_CAPABILITY_MMS); 3056 net2.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 3057 net2.connect(true); 3058 3059 // Make sure the default request goes to net 2 3060 generalCb.expectAvailableCallbacksUnvalidated(net2); 3061 if (expectLingering) { 3062 generalCb.expectLosing(net1); 3063 } 3064 generalCb.expectCaps(net2, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3065 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 3066 3067 // Make sure cell 1 is unwanted immediately if the radio can't time share, but only 3068 // after some delay if it can. 3069 if (expectLingering) { 3070 net1.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // always incurs the timeout 3071 generalCb.assertNoCallback(); 3072 // assertNotDisconnected waited for TEST_CALLBACK_TIMEOUT_MS, so waiting for the 3073 // linger period gives TEST_CALLBACK_TIMEOUT_MS time for the event to process. 3074 net1.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 3075 } else { 3076 net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3077 } 3078 net1.disconnect(); 3079 generalCb.expect(LOST, net1); 3080 3081 // Remove primary from net 2 3082 net2.setScore(new NetworkScore.Builder().build()); 3083 // Request MMS 3084 final TestNetworkCallback mmsCallback = new TestNetworkCallback(); 3085 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 3086 mmsCallback); 3087 mmsCallback.expectAvailableCallbacksValidated(net2); 3088 3089 // Bring up net 3 with primary but without MMS 3090 final TestNetworkAgentWrapper net3 = new TestNetworkAgentWrapper(transport); 3091 net3.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 3092 net3.connect(true); 3093 3094 // Make sure default goes to net 3, but the MMS request doesn't 3095 generalCb.expectAvailableThenValidatedCallbacks(net3); 3096 defaultCb.expectAvailableDoubleValidatedCallbacks(net3); 3097 mmsCallback.assertNoCallback(); 3098 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // Always incurs the timeout 3099 3100 // Revoke MMS request and make sure net 2 is torn down with the appropriate delay 3101 mCm.unregisterNetworkCallback(mmsCallback); 3102 if (expectLingering) { 3103 // If the radio can time share, the linger delay hasn't elapsed yet, so apps will 3104 // get LOSING. If the radio can't time share, this is a hard loss, since the last 3105 // request keeping up this network has been removed and the network isn't lingering 3106 // for any other request. 3107 generalCb.expectLosing(net2); 3108 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3109 // Timeout 0 because after a while LOST will actually arrive 3110 generalCb.assertNoCallback(0 /* timeoutMs */); 3111 net2.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 3112 } else { 3113 net2.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3114 } 3115 net2.disconnect(); 3116 generalCb.expect(LOST, net2); 3117 defaultCb.assertNoCallback(); 3118 3119 net3.disconnect(); 3120 mCm.unregisterNetworkCallback(defaultCb); 3121 mCm.unregisterNetworkCallback(generalCb); 3122 } 3123 3124 // TODO : migrate to @Parameterized 3125 @Test 3126 public void testCellularOutscoresWeakWifi_CanTimeShare() throws Exception { 3127 // The behavior of this test should be the same whether the radio can time share or not. 3128 doTestCellularOutscoresWeakWifi(true); 3129 } 3130 3131 // TODO : migrate to @Parameterized 3132 @Test 3133 public void testCellularOutscoresWeakWifi_CannotTimeShare() throws Exception { 3134 doTestCellularOutscoresWeakWifi(false); 3135 } 3136 3137 private void doTestCellularOutscoresWeakWifi( 3138 final boolean cellRadioTimesharingCapable) throws Exception { 3139 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3140 // Test bringing up validated cellular. 3141 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3142 ExpectedBroadcast b = expectConnectivityAction(1); 3143 mCellAgent.connect(true); 3144 b.expectBroadcast(); 3145 verifyActiveNetwork(TRANSPORT_CELLULAR); 3146 // Test bringing up validated WiFi. 3147 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3148 b = expectConnectivityAction(2); 3149 mWiFiAgent.connect(true); 3150 b.expectBroadcast(); 3151 verifyActiveNetwork(TRANSPORT_WIFI); 3152 // Test WiFi getting really weak. 3153 b = expectConnectivityAction(2); 3154 mWiFiAgent.adjustScore(-11); 3155 b.expectBroadcast(); 3156 verifyActiveNetwork(TRANSPORT_CELLULAR); 3157 // Test WiFi restoring signal strength. 3158 b = expectConnectivityAction(2); 3159 mWiFiAgent.adjustScore(11); 3160 b.expectBroadcast(); 3161 verifyActiveNetwork(TRANSPORT_WIFI); 3162 } 3163 3164 // TODO : migrate to @Parameterized 3165 @Test 3166 public void testReapingNetwork_CanTimeShare() throws Exception { 3167 doTestReapingNetwork(true); 3168 } 3169 3170 // TODO : migrate to @Parameterized 3171 @Test 3172 public void testReapingNetwork_CannotTimeShare() throws Exception { 3173 doTestReapingNetwork(false); 3174 } 3175 3176 private void doTestReapingNetwork( 3177 final boolean cellRadioTimesharingCapable) throws Exception { 3178 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3179 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 3180 // Expect it to be torn down immediately because it satisfies no requests. 3181 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3182 mWiFiAgent.connectWithoutInternet(); 3183 mWiFiAgent.expectDisconnected(); 3184 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 3185 // Expect it to be torn down immediately because it satisfies no requests. 3186 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3187 mCellAgent.connectWithoutInternet(); 3188 mCellAgent.expectDisconnected(); 3189 // Test bringing up validated WiFi. 3190 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3191 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 3192 mWiFiAgent.connect(true); 3193 b.expectBroadcast(); 3194 verifyActiveNetwork(TRANSPORT_WIFI); 3195 // Test bringing up unvalidated cellular. 3196 // Expect it to be torn down because it could never be the highest scoring network 3197 // satisfying the default request even if it validated. 3198 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3199 mCellAgent.connect(false); 3200 mCellAgent.expectDisconnected(); 3201 verifyActiveNetwork(TRANSPORT_WIFI); 3202 mWiFiAgent.disconnect(); 3203 mWiFiAgent.expectDisconnected(); 3204 } 3205 3206 // TODO : migrate to @Parameterized 3207 @Test 3208 public void testCellularFallback_CanTimeShare() throws Exception { 3209 doTestCellularFallback(true); 3210 } 3211 3212 // TODO : migrate to @Parameterized 3213 @Test 3214 public void testCellularFallback_CannotTimeShare() throws Exception { 3215 doTestCellularFallback(false); 3216 } 3217 3218 private void doTestCellularFallback( 3219 final boolean cellRadioTimesharingCapable) throws Exception { 3220 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3221 // Test bringing up validated cellular. 3222 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3223 ExpectedBroadcast b = expectConnectivityAction(1); 3224 mCellAgent.connect(true); 3225 b.expectBroadcast(); 3226 verifyActiveNetwork(TRANSPORT_CELLULAR); 3227 // Test bringing up validated WiFi. 3228 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3229 b = expectConnectivityAction(2); 3230 mWiFiAgent.connect(true); 3231 b.expectBroadcast(); 3232 verifyActiveNetwork(TRANSPORT_WIFI); 3233 // Reevaluate WiFi (it'll instantly fail DNS). 3234 b = expectConnectivityAction(2); 3235 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3236 NET_CAPABILITY_VALIDATED)); 3237 mCm.reportBadNetwork(mWiFiAgent.getNetwork()); 3238 // Should quickly fall back to Cellular. 3239 b.expectBroadcast(); 3240 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3241 NET_CAPABILITY_VALIDATED)); 3242 verifyActiveNetwork(TRANSPORT_CELLULAR); 3243 // Reevaluate cellular (it'll instantly fail DNS). 3244 b = expectConnectivityAction(2); 3245 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3246 NET_CAPABILITY_VALIDATED)); 3247 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3248 // Should quickly fall back to WiFi. 3249 b.expectBroadcast(); 3250 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3251 NET_CAPABILITY_VALIDATED)); 3252 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3253 NET_CAPABILITY_VALIDATED)); 3254 verifyActiveNetwork(TRANSPORT_WIFI); 3255 } 3256 3257 // TODO : migrate to @Parameterized 3258 @Test 3259 public void testWiFiFallback_CanTimeShare() throws Exception { 3260 doTestWiFiFallback(true); 3261 } 3262 3263 // TODO : migrate to @Parameterized 3264 @Test 3265 public void testWiFiFallback_CannotTimeShare() throws Exception { 3266 doTestWiFiFallback(false); 3267 } 3268 3269 private void doTestWiFiFallback( 3270 final boolean cellRadioTimesharingCapable) throws Exception { 3271 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3272 // Test bringing up unvalidated WiFi. 3273 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3274 ExpectedBroadcast b = expectConnectivityAction(1); 3275 mWiFiAgent.connect(false); 3276 b.expectBroadcast(); 3277 verifyActiveNetwork(TRANSPORT_WIFI); 3278 // Test bringing up validated cellular. 3279 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3280 b = expectConnectivityAction(2); 3281 mCellAgent.connect(true); 3282 b.expectBroadcast(); 3283 verifyActiveNetwork(TRANSPORT_CELLULAR); 3284 // Reevaluate cellular (it'll instantly fail DNS). 3285 b = expectConnectivityAction(2); 3286 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3287 NET_CAPABILITY_VALIDATED)); 3288 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3289 // Should quickly fall back to WiFi. 3290 b.expectBroadcast(); 3291 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3292 NET_CAPABILITY_VALIDATED)); 3293 verifyActiveNetwork(TRANSPORT_WIFI); 3294 } 3295 3296 @Test 3297 public void testRequiresValidation() { 3298 assertTrue(NetworkMonitorUtils.isValidationRequired(false /* isDunValidationRequired */, 3299 false /* isVpnValidationRequired */, 3300 mCm.getDefaultRequest().networkCapabilities)); 3301 } 3302 3303 /** 3304 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 3305 * this class receives, by calling expect() exactly once each time a callback is 3306 * received. assertNoCallback may be called at any time. 3307 */ 3308 private class TestNetworkCallback extends TestableNetworkCallback { 3309 TestNetworkCallback() { 3310 // In the context of this test, the testable network callbacks should use waitForIdle 3311 // before calling assertNoCallback in an effort to detect issues where a callback is 3312 // not yet sent but a message currently in the queue of a handler will cause it to 3313 // be sent soon. 3314 super(TEST_CALLBACK_TIMEOUT_MS, TEST_CALLBACK_TIMEOUT_MS, 3315 ConnectivityServiceTest.this::waitForIdle); 3316 } 3317 3318 public CallbackEntry.Losing expectLosing(final HasNetwork n, final long timeoutMs) { 3319 final CallbackEntry.Losing losing = expect(LOSING, n, timeoutMs); 3320 final int maxMsToLive = losing.getMaxMsToLive(); 3321 if (maxMsToLive < 0 || maxMsToLive > mService.mLingerDelayMs) { 3322 // maxMsToLive is the value that was received in the onLosing callback. That must 3323 // not be negative, so check that. 3324 // Also, maxMsToLive is the remaining time until the network expires. 3325 // mService.mLingerDelayMs is how long the network takes from when it's first 3326 // detected to be unneeded to when it expires, so maxMsToLive should never 3327 // be greater than that. 3328 fail(String.format("Invalid linger time value %d, must be between %d and %d", 3329 maxMsToLive, 0, mService.mLingerDelayMs)); 3330 } 3331 return losing; 3332 } 3333 3334 public CallbackEntry.Losing expectLosing(final HasNetwork n) { 3335 return expectLosing(n, getDefaultTimeoutMs()); 3336 } 3337 } 3338 3339 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 3340 // only be declared in a static or top level type". 3341 static void assertNoCallbacks(final long timeoutMs, TestNetworkCallback ... callbacks) { 3342 for (TestNetworkCallback c : callbacks) { 3343 c.assertNoCallback(timeoutMs); 3344 } 3345 } 3346 3347 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 3348 for (TestNetworkCallback c : callbacks) { 3349 c.assertNoCallback(); // each callback uses its own timeout 3350 } 3351 } 3352 3353 static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { 3354 for (TestNetworkCallback c : callbacks) { 3355 c.expect(LOST, network); 3356 } 3357 } 3358 3359 static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, 3360 NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { 3361 for (TestNetworkCallback c : callbacks) { 3362 c.expect(AVAILABLE, network); 3363 c.expectCaps(network, cb -> !cb.hasCapability(NET_CAPABILITY_VALIDATED) 3364 && Objects.equals(specifier, cb.getNetworkSpecifier())); 3365 c.expect(LINK_PROPERTIES_CHANGED, network); 3366 c.expect(BLOCKED_STATUS, network); 3367 } 3368 } 3369 3370 @Test 3371 public void testNetworkDoesntMatchRequestsUntilConnected() throws Exception { 3372 final TestNetworkCallback cb = new TestNetworkCallback(); 3373 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3374 .addTransportType(TRANSPORT_WIFI).build(); 3375 mCm.requestNetwork(wifiRequest, cb); 3376 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3377 // Updating the score triggers a rematch. 3378 mWiFiAgent.setScore(new NetworkScore.Builder().build()); 3379 cb.assertNoCallback(); 3380 mWiFiAgent.connect(false); 3381 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3382 cb.assertNoCallback(); 3383 mCm.unregisterNetworkCallback(cb); 3384 } 3385 3386 @Test 3387 public void testNetworkNotVisibleUntilConnected() throws Exception { 3388 final TestNetworkCallback cb = new TestNetworkCallback(); 3389 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3390 .addTransportType(TRANSPORT_WIFI).build(); 3391 mCm.registerNetworkCallback(wifiRequest, cb); 3392 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3393 final NetworkCapabilities nc = mWiFiAgent.getNetworkCapabilities(); 3394 nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 3395 mWiFiAgent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 3396 cb.assertNoCallback(); 3397 mWiFiAgent.connect(false); 3398 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3399 final CallbackEntry found = CollectionUtils.findLast(cb.getHistory(), 3400 it -> it instanceof CallbackEntry.CapabilitiesChanged); 3401 assertTrue(((CallbackEntry.CapabilitiesChanged) found).getCaps() 3402 .hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 3403 cb.assertNoCallback(); 3404 mCm.unregisterNetworkCallback(cb); 3405 } 3406 3407 @Test 3408 public void testStateChangeNetworkCallbacks() throws Exception { 3409 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 3410 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 3411 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3412 final NetworkRequest genericRequest = new NetworkRequest.Builder() 3413 .clearCapabilities().build(); 3414 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3415 .addTransportType(TRANSPORT_WIFI).build(); 3416 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3417 .addTransportType(TRANSPORT_CELLULAR).build(); 3418 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 3419 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 3420 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 3421 3422 // Test unvalidated networks 3423 ExpectedBroadcast b = expectConnectivityAction(1); 3424 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3425 mCellAgent.connect(false); 3426 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3427 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3428 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3429 b.expectBroadcast(); 3430 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3431 3432 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3433 mCellAgent.adjustScore(-1); 3434 waitForIdle(); 3435 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3436 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3437 3438 b = expectConnectivityAction(2); 3439 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3440 mWiFiAgent.connect(false); 3441 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3442 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3443 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3444 b.expectBroadcast(); 3445 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3446 3447 b = expectConnectivityAction(2); 3448 mWiFiAgent.disconnect(); 3449 genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3450 wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3451 cellNetworkCallback.assertNoCallback(); 3452 b.expectBroadcast(); 3453 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3454 3455 b = expectConnectivityAction(1); 3456 mCellAgent.disconnect(); 3457 genericNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3458 cellNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3459 b.expectBroadcast(); 3460 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3461 3462 // Test validated networks 3463 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3464 mCellAgent.connect(true); 3465 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3466 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3467 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3468 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3469 3470 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3471 mCellAgent.adjustScore(-1); 3472 waitForIdle(); 3473 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3474 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3475 3476 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3477 mWiFiAgent.connect(true); 3478 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3479 genericNetworkCallback.expectLosing(mCellAgent); 3480 genericNetworkCallback.expectCaps(mWiFiAgent, 3481 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3482 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3483 cellNetworkCallback.expectLosing(mCellAgent); 3484 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3485 // Cell will disconnect after the lingering period. Before that elapses check that 3486 // there have been no callbacks. 3487 assertNoCallbacks(0 /* timeoutMs */, 3488 genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3489 3490 mWiFiAgent.disconnect(); 3491 genericNetworkCallback.expect(LOST, mWiFiAgent); 3492 wifiNetworkCallback.expect(LOST, mWiFiAgent); 3493 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3494 3495 mCellAgent.disconnect(); 3496 genericNetworkCallback.expect(LOST, mCellAgent); 3497 cellNetworkCallback.expect(LOST, mCellAgent); 3498 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3499 } 3500 3501 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 3502 final TestNetworkCallback callback = new TestNetworkCallback(); 3503 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3504 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3505 .addTransportType(TRANSPORT_WIFI).build(); 3506 mCm.registerNetworkCallback(wifiRequest, callback); 3507 mCm.registerDefaultNetworkCallback(defaultCallback); 3508 3509 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3510 mWiFiAgent.connect(false); 3511 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3512 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3513 3514 final LinkProperties newLp = new LinkProperties(); 3515 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 3516 final CaptivePortalData capportData = new CaptivePortalData.Builder() 3517 .setCaptive(true).build(); 3518 3519 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 3520 newLp.setCaptivePortalApiUrl(capportUrl); 3521 mWiFiAgent.sendLinkProperties(newLp); 3522 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3523 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3524 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3525 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3526 3527 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 3528 mWiFiAgent.notifyCapportApiDataChanged(capportData); 3529 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3530 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3531 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3532 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3533 3534 final LinkProperties lp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 3535 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 3536 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 3537 } 3538 3539 @Test 3540 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 3541 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3542 PERMISSION_DENIED); 3543 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3544 doNetworkCallbacksSanitizationTest(true /* sanitized */); 3545 } 3546 3547 @Test 3548 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 3549 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3550 PERMISSION_GRANTED); 3551 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3552 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3553 } 3554 3555 @Test 3556 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 3557 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3558 PERMISSION_DENIED); 3559 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3560 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3561 } 3562 3563 @Test 3564 public void testOwnerUidCannotChange() throws Exception { 3565 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 3566 final int originalOwnerUid = Process.myUid(); 3567 ncTemplate.setOwnerUid(originalOwnerUid); 3568 3569 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 3570 mWiFiAgent.connect(false); 3571 waitForIdle(); 3572 3573 // Send ConnectivityService an update to the mWiFiAgent's capabilities that changes 3574 // the owner UID and an unrelated capability. 3575 NetworkCapabilities agentCapabilities = mWiFiAgent.getNetworkCapabilities(); 3576 assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); 3577 agentCapabilities.setOwnerUid(42); 3578 assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3579 agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); 3580 mWiFiAgent.setNetworkCapabilities(agentCapabilities, true); 3581 waitForIdle(); 3582 3583 // Owner UIDs are not visible without location permission. 3584 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 3585 Manifest.permission.ACCESS_FINE_LOCATION); 3586 3587 // Check that the capability change has been applied but the owner UID is not modified. 3588 NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 3589 assertEquals(originalOwnerUid, nc.getOwnerUid()); 3590 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3591 } 3592 3593 @Test 3594 public void testMultipleLingering() throws Exception { 3595 // This test would be flaky with the default 120ms timer: that is short enough that 3596 // lingered networks are torn down before assertions can be run. We don't want to mock the 3597 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 3598 // in detecting races. Furthermore, sometimes the test is running while Phenotype is running 3599 // so hot that the test doesn't get the CPU for multiple hundreds of milliseconds, so this 3600 // needs to be suitably long. 3601 mService.mLingerDelayMs = 2_000; 3602 3603 NetworkRequest request = new NetworkRequest.Builder() 3604 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 3605 .build(); 3606 TestNetworkCallback callback = new TestNetworkCallback(); 3607 mCm.registerNetworkCallback(request, callback); 3608 3609 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3610 mCm.registerDefaultNetworkCallback(defaultCallback); 3611 3612 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3613 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3614 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3615 3616 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3617 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3618 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3619 3620 mCellAgent.connect(true); 3621 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3622 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3623 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3624 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3625 3626 mWiFiAgent.connect(true); 3627 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 3628 // We then get LOSING when wifi validates and cell is outscored. 3629 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3630 // TODO: Investigate sending validated before losing. 3631 callback.expectLosing(mCellAgent); 3632 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3633 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3634 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3635 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3636 3637 mEthernetAgent.connect(true); 3638 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3639 // TODO: Investigate sending validated before losing. 3640 callback.expectLosing(mWiFiAgent); 3641 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3642 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3643 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 3644 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3645 3646 mEthernetAgent.disconnect(); 3647 callback.expect(LOST, mEthernetAgent); 3648 defaultCallback.expect(LOST, mEthernetAgent); 3649 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3650 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3651 3652 for (int i = 0; i < 4; i++) { 3653 TestNetworkAgentWrapper oldNetwork, newNetwork; 3654 if (i % 2 == 0) { 3655 mWiFiAgent.adjustScore(-15); 3656 oldNetwork = mWiFiAgent; 3657 newNetwork = mCellAgent; 3658 } else { 3659 mWiFiAgent.adjustScore(15); 3660 oldNetwork = mCellAgent; 3661 newNetwork = mWiFiAgent; 3662 3663 } 3664 callback.expectLosing(oldNetwork); 3665 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 3666 // longer lingering? 3667 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 3668 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 3669 } 3670 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3671 3672 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 3673 // if the network is still up. 3674 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 3675 // We expect a notification about the capabilities change, and nothing else. 3676 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 3677 defaultCallback.assertNoCallback(); 3678 callback.expect(LOST, mWiFiAgent); 3679 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3680 3681 // Wifi no longer satisfies our listen, which is for an unmetered network. 3682 // But because its score is 55, it's still up (and the default network). 3683 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3684 3685 // Disconnect our test networks. 3686 mWiFiAgent.disconnect(); 3687 defaultCallback.expect(LOST, mWiFiAgent); 3688 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3689 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3690 mCellAgent.disconnect(); 3691 defaultCallback.expect(LOST, mCellAgent); 3692 waitForIdle(); 3693 assertEquals(null, mCm.getActiveNetwork()); 3694 3695 mCm.unregisterNetworkCallback(callback); 3696 waitForIdle(); 3697 3698 // Check that a network is only lingered or torn down if it would not satisfy a request even 3699 // if it validated. 3700 request = new NetworkRequest.Builder().clearCapabilities().build(); 3701 callback = new TestNetworkCallback(); 3702 3703 mCm.registerNetworkCallback(request, callback); 3704 3705 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3706 mCellAgent.connect(false); // Score: 10 3707 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 3708 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3709 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3710 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3711 3712 // Bring up wifi with a score of 20. 3713 // Cell stays up because it would satisfy the default request if it validated. 3714 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3715 mWiFiAgent.connect(false); // Score: 20 3716 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3717 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3718 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3719 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3720 3721 mWiFiAgent.disconnect(); 3722 callback.expect(LOST, mWiFiAgent); 3723 defaultCallback.expect(LOST, mWiFiAgent); 3724 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3725 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3726 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3727 3728 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 3729 // it's arguably correct to linger it, since it was the default network before it validated. 3730 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3731 mWiFiAgent.connect(true); 3732 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3733 // TODO: Investigate sending validated before losing. 3734 callback.expectLosing(mCellAgent); 3735 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3736 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3737 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3738 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3739 3740 mWiFiAgent.disconnect(); 3741 callback.expect(LOST, mWiFiAgent); 3742 defaultCallback.expect(LOST, mWiFiAgent); 3743 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3744 mCellAgent.disconnect(); 3745 callback.expect(LOST, mCellAgent); 3746 defaultCallback.expect(LOST, mCellAgent); 3747 waitForIdle(); 3748 assertEquals(null, mCm.getActiveNetwork()); 3749 3750 // If a network is lingering, and we add and remove a request from it, resume lingering. 3751 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3752 mCellAgent.connect(true); 3753 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3754 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3755 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3756 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3757 mWiFiAgent.connect(true); 3758 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3759 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3760 // TODO: Investigate sending validated before losing. 3761 callback.expectLosing(mCellAgent); 3762 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3763 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3764 3765 NetworkRequest cellRequest = new NetworkRequest.Builder() 3766 .addTransportType(TRANSPORT_CELLULAR).build(); 3767 NetworkCallback noopCallback = new NetworkCallback(); 3768 mCm.requestNetwork(cellRequest, noopCallback); 3769 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 3770 // lingering? 3771 mCm.unregisterNetworkCallback(noopCallback); 3772 callback.expectLosing(mCellAgent); 3773 3774 // Similar to the above: lingering can start even after the lingered request is removed. 3775 // Disconnect wifi and switch to cell. 3776 mWiFiAgent.disconnect(); 3777 callback.expect(LOST, mWiFiAgent); 3778 defaultCallback.expect(LOST, mWiFiAgent); 3779 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3780 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3781 3782 // Cell is now the default network. Pin it with a cell-specific request. 3783 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 3784 mCm.requestNetwork(cellRequest, noopCallback); 3785 3786 // Now connect wifi, and expect it to become the default network. 3787 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3788 mWiFiAgent.connect(true); 3789 callback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3790 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3791 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3792 // The default request is lingering on cell, but nothing happens to cell, and we send no 3793 // callbacks for it, because it's kept up by cellRequest. 3794 callback.assertNoCallback(); 3795 // Now unregister cellRequest and expect cell to start lingering. 3796 mCm.unregisterNetworkCallback(noopCallback); 3797 callback.expectLosing(mCellAgent); 3798 3799 // Let linger run its course. 3800 callback.assertNoCallback(0 /* timeoutMs */); 3801 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 3802 callback.expect(LOST, mCellAgent, lingerTimeoutMs); 3803 3804 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 3805 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 3806 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 3807 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3808 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3809 mEthernetAgent.connect(true); 3810 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3811 callback.expectLosing(mWiFiAgent); 3812 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3813 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3814 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3815 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3816 3817 // Let linger run its course. 3818 callback.expect(LOST, mWiFiAgent, lingerTimeoutMs); 3819 3820 // Clean up. 3821 mEthernetAgent.disconnect(); 3822 callback.expect(LOST, mEthernetAgent); 3823 defaultCallback.expect(LOST, mEthernetAgent); 3824 trackDefaultCallback.expect(LOST, mEthernetAgent); 3825 3826 mCm.unregisterNetworkCallback(callback); 3827 mCm.unregisterNetworkCallback(defaultCallback); 3828 mCm.unregisterNetworkCallback(trackDefaultCallback); 3829 } 3830 3831 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 3832 grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); 3833 } 3834 3835 private void grantUsingBackgroundNetworksPermissionForUid( 3836 final int uid, final String packageName) throws Exception { 3837 doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager) 3838 .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)); 3839 3840 // Send a broadcast indicating a package was installed. 3841 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 3842 addedIntent.putExtra(Intent.EXTRA_UID, uid); 3843 addedIntent.setData(Uri.parse("package:" + packageName)); 3844 processBroadcast(addedIntent); 3845 } 3846 3847 @Test 3848 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 3849 setAlwaysOnNetworks(true); 3850 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3851 NetworkRequest request = new NetworkRequest.Builder() 3852 .clearCapabilities() 3853 .build(); 3854 TestNetworkCallback callback = new TestNetworkCallback(); 3855 mCm.registerNetworkCallback(request, callback); 3856 3857 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3858 mCm.registerDefaultNetworkCallback(defaultCallback); 3859 3860 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3861 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3862 3863 mCellAgent.connect(true); 3864 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3865 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3866 3867 // Wifi comes up and cell lingers. 3868 mWiFiAgent.connect(true); 3869 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3870 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3871 callback.expectLosing(mCellAgent); 3872 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3873 3874 // File a request for cellular, then release it. 3875 NetworkRequest cellRequest = new NetworkRequest.Builder() 3876 .addTransportType(TRANSPORT_CELLULAR).build(); 3877 NetworkCallback noopCallback = new NetworkCallback(); 3878 mCm.requestNetwork(cellRequest, noopCallback); 3879 mCm.unregisterNetworkCallback(noopCallback); 3880 callback.expectLosing(mCellAgent); 3881 3882 // Let linger run its course. 3883 callback.assertNoCallback(); 3884 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 3885 callback.expectCaps(mCellAgent, lingerTimeoutMs, 3886 c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 3887 3888 // Clean up. 3889 mCm.unregisterNetworkCallback(defaultCallback); 3890 mCm.unregisterNetworkCallback(callback); 3891 } 3892 3893 /** Expects the specified notification and returns the notification ID. */ 3894 private int expectNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3895 verify(mNotificationManager, timeout(TIMEOUT_MS)).notify( 3896 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), 3897 eq(type.eventId), any()); 3898 return type.eventId; 3899 } 3900 3901 private void expectNoNotification(@NonNull final TestNetworkAgentWrapper agent) { 3902 verify(mNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any()); 3903 } 3904 3905 /** 3906 * Expects the specified notification happens when the unvalidated prompt message arrives 3907 * 3908 * @return the notification ID. 3909 **/ 3910 private int expectUnvalidationCheckWillNotify(TestNetworkAgentWrapper agent, 3911 NotificationType type) { 3912 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /* delayMs */); 3913 waitForIdle(); 3914 return expectNotification(agent, type); 3915 } 3916 3917 /** 3918 * Expects that the notification for the specified network is cleared. 3919 * 3920 * This generally happens when the network disconnects or when the newtwork validates. During 3921 * normal usage the notification is also cleared by the system when the notification is tapped. 3922 */ 3923 private void expectClearNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3924 verify(mNotificationManager, timeout(TIMEOUT_MS)).cancel( 3925 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), eq(type.eventId)); 3926 } 3927 3928 /** 3929 * Expects that no notification happens when the unvalidated prompt message arrives 3930 * 3931 * @return the notification ID. 3932 **/ 3933 private void expectUnvalidationCheckWillNotNotify(TestNetworkAgentWrapper agent) { 3934 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /*delayMs */); 3935 waitForIdle(); 3936 expectNoNotification(agent); 3937 } 3938 3939 private void expectDisconnectAndClearNotifications(TestNetworkCallback callback, 3940 TestNetworkAgentWrapper agent, NotificationType type) { 3941 callback.expect(LOST, agent); 3942 expectClearNotification(agent, type); 3943 } 3944 3945 private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { 3946 return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 3947 /*secure=*/ false, VpnManager.TYPE_VPN_NONE, /*excludeLocalRoutes=*/ false); 3948 } 3949 3950 private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { 3951 return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, 3952 secure, vpnType, /*excludeLocalRoutes=*/ false); 3953 } 3954 3955 @Test 3956 public void testNetworkAgentCallbacks() throws Exception { 3957 // Keeps track of the order of events that happen in this test. 3958 final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); 3959 3960 final NetworkRequest request = new NetworkRequest.Builder() 3961 .addTransportType(TRANSPORT_WIFI).build(); 3962 final TestNetworkCallback callback = new TestNetworkCallback(); 3963 3964 // Expectations for state when various callbacks fire. These expectations run on the handler 3965 // thread and not on the test thread because they need to prevent the handler thread from 3966 // advancing while they examine state. 3967 3968 // 1. When onCreated fires, netd has been told to create the network. 3969 final Consumer<NetworkAgent> onNetworkCreated = (agent) -> { 3970 eventOrder.offer("onNetworkCreated"); 3971 try { 3972 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 3973 agent.getNetwork().getNetId(), INetd.PERMISSION_NONE)); 3974 } catch (RemoteException impossible) { 3975 fail(); 3976 } 3977 }; 3978 3979 // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just 3980 // check that it is fired at some point after disconnect. 3981 final Consumer<NetworkAgent> onNetworkUnwanted = (agent) -> { 3982 eventOrder.offer("onNetworkUnwanted"); 3983 }; 3984 3985 // 3. While the teardown timer is running, connectivity APIs report the network is gone, but 3986 // netd has not yet been told to destroy it. 3987 final Consumer<Network> duringTeardown = (network) -> { 3988 eventOrder.offer("timePasses"); 3989 assertNull(mCm.getLinkProperties(network)); 3990 try { 3991 verify(mMockNetd, never()).networkDestroy(network.getNetId()); 3992 } catch (RemoteException impossible) { 3993 fail(); 3994 } 3995 }; 3996 3997 // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, 3998 // and netd has been told to destroy it. 3999 final Consumer<NetworkAgent> onNetworkDisconnected = (agent) -> { 4000 eventOrder.offer("onNetworkDisconnected"); 4001 assertNull(mCm.getLinkProperties(agent.getNetwork())); 4002 try { 4003 verify(mMockNetd).networkDestroy(agent.getNetwork().getNetId()); 4004 } catch (RemoteException impossible) { 4005 fail(); 4006 } 4007 }; 4008 4009 final NetworkAgentWrapper.Callbacks callbacks = new NetworkAgentWrapper.Callbacks( 4010 onNetworkCreated, onNetworkUnwanted, onNetworkDisconnected); 4011 4012 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, callbacks); 4013 4014 if (mService.shouldCreateNetworksImmediately()) { 4015 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4016 } else { 4017 assertNull(eventOrder.poll()); 4018 } 4019 4020 // Connect a network, and file a request for it after it has come up, to ensure the nascent 4021 // timer is cleared and the test does not have to wait for it. Filing the request after the 4022 // network has come up is necessary because ConnectivityService does not appear to clear the 4023 // nascent timer if the first request satisfied by the network was filed before the network 4024 // connected. 4025 // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. 4026 mWiFiAgent.connectWithoutInternet(); 4027 if (!mService.shouldCreateNetworksImmediately()) { 4028 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4029 } else { 4030 waitForIdle(); 4031 assertNull(eventOrder.poll()); 4032 } 4033 mCm.requestNetwork(request, callback); 4034 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4035 4036 // Set teardown delay and make sure CS has processed it. 4037 mWiFiAgent.getNetworkAgent().setTeardownDelayMillis(300); 4038 waitForIdle(); 4039 4040 // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. 4041 // The delay must be long enough it will run after the unregisterNetworkCallback has torn 4042 // down the network and started the teardown timer, and short enough that the lambda is 4043 // scheduled to run before the teardown timer. 4044 final Handler h = new Handler(mCsHandlerThread.getLooper()); 4045 h.postDelayed(() -> duringTeardown.accept(mWiFiAgent.getNetwork()), 150); 4046 4047 // Disconnect the network and check that events happened in the right order. 4048 mCm.unregisterNetworkCallback(callback); 4049 assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4050 assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4051 assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4052 4053 mCm.unregisterNetworkCallback(callback); 4054 } 4055 4056 @Test 4057 public void testExplicitlySelected() throws Exception { 4058 final NetworkRequest request = new NetworkRequest.Builder() 4059 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4060 .build(); 4061 final TestNetworkCallback callback = new TestNetworkCallback(); 4062 mCm.registerNetworkCallback(request, callback); 4063 4064 // Bring up validated cell 4065 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4066 mCellAgent.connect(true); 4067 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 4068 4069 // Bring up unvalidated wifi with explicitlySelected=true. 4070 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4071 mWiFiAgent.explicitlySelected(true, false); 4072 mWiFiAgent.connect(false); 4073 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4074 4075 // Cell remains the default. 4076 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4077 4078 // Expect a high-priority NO_INTERNET notification. 4079 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 4080 4081 // Lower WiFi's score to lower than cell, and check that it doesn't disconnect because 4082 // it's explicitly selected. 4083 mWiFiAgent.adjustScore(-40); 4084 mWiFiAgent.adjustScore(40); 4085 callback.assertNoCallback(); 4086 4087 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 4088 // wifi even though it's unvalidated. 4089 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), true, false); 4090 callback.expectLosing(mCellAgent); 4091 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4092 4093 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 4094 mWiFiAgent.disconnect(); 4095 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 4096 4097 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4098 mWiFiAgent.explicitlySelected(true, false); 4099 mWiFiAgent.connect(false); 4100 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4101 4102 // Expect a high-priority NO_INTERNET notification. 4103 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 4104 4105 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 4106 // network to disconnect. 4107 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), false, false); 4108 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 4109 reset(mNotificationManager); 4110 4111 // Reconnect, again with explicitlySelected=true, but this time validate. 4112 // Expect no notifications. 4113 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4114 mWiFiAgent.explicitlySelected(true, false); 4115 mWiFiAgent.connect(true); 4116 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4117 callback.expectLosing(mCellAgent); 4118 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4119 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4120 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4121 4122 // Now request cell so it doesn't disconnect during the test 4123 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4124 .clearCapabilities().addTransportType(TRANSPORT_CELLULAR).build(); 4125 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 4126 mCm.requestNetwork(cellRequest, cellCallback); 4127 4128 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 4129 mEthernetAgent.connect(true); 4130 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 4131 callback.expectLosing(mWiFiAgent); 4132 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4133 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 4134 callback.assertNoCallback(); 4135 4136 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 4137 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 4138 // wifi immediately. 4139 mWiFiAgent.disconnect(); 4140 callback.expect(LOST, mWiFiAgent); 4141 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4142 mWiFiAgent.explicitlySelected(true, true); 4143 mWiFiAgent.connect(false); 4144 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4145 callback.expectLosing(mEthernetAgent); 4146 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4147 mEthernetAgent.disconnect(); 4148 callback.expect(LOST, mEthernetAgent); 4149 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4150 4151 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 4152 // Check that the network is not scored specially and that the device prefers cell data. 4153 mWiFiAgent.disconnect(); 4154 callback.expect(LOST, mWiFiAgent); 4155 4156 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4157 mWiFiAgent.explicitlySelected(false, true); 4158 mWiFiAgent.connect(false); 4159 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4160 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4161 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4162 4163 // Clean up. 4164 mWiFiAgent.disconnect(); 4165 mCellAgent.disconnect(); 4166 4167 callback.expect(LOST, mWiFiAgent); 4168 callback.expect(LOST, mCellAgent); 4169 mCm.unregisterNetworkCallback(cellCallback); 4170 } 4171 4172 private void doTestFirstEvaluation( 4173 @NonNull final Consumer<TestNetworkAgentWrapper> doConnect, 4174 final boolean waitForSecondCaps, 4175 final boolean evaluatedByValidation) 4176 throws Exception { 4177 final NetworkRequest request = new NetworkRequest.Builder() 4178 .addTransportType(TRANSPORT_WIFI) 4179 .build(); 4180 TestNetworkCallback callback = new TestNetworkCallback(); 4181 mCm.registerNetworkCallback(request, callback); 4182 4183 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4184 doConnect.accept(mWiFiAgent); 4185 // Expect the available callbacks, but don't require specific values for their arguments 4186 // since this method doesn't know how the network was connected. 4187 callback.expect(AVAILABLE, mWiFiAgent); 4188 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4189 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent); 4190 callback.expect(BLOCKED_STATUS, mWiFiAgent); 4191 if (waitForSecondCaps) { 4192 // This is necessary because of b/245893397, the same bug that happens where we use 4193 // expectAvailableDoubleValidatedCallbacks. 4194 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4195 } 4196 final NetworkAgentInfo nai = 4197 mService.getNetworkAgentInfoForNetwork(mWiFiAgent.getNetwork()); 4198 final long firstEvaluation = nai.getFirstEvaluationConcludedTime(); 4199 if (evaluatedByValidation) { 4200 assertNotEquals(0L, firstEvaluation); 4201 } else { 4202 assertEquals(0L, firstEvaluation); 4203 } 4204 mService.scheduleEvaluationTimeout(mWiFiAgent.getNetwork(), 0L /* timeout */); 4205 waitForIdle(); 4206 if (evaluatedByValidation) { 4207 assertEquals(firstEvaluation, nai.getFirstEvaluationConcludedTime()); 4208 } else { 4209 assertNotEquals(0L, nai.getFirstEvaluationConcludedTime()); 4210 } 4211 mWiFiAgent.disconnect(); 4212 callback.expect(LOST, mWiFiAgent); 4213 4214 mCm.unregisterNetworkCallback(callback); 4215 } 4216 4217 @Test 4218 public void testEverEvaluated() throws Exception { 4219 doTestFirstEvaluation(naw -> naw.connect(true /* validated */), 4220 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4221 doTestFirstEvaluation(naw -> naw.connectWithPartialConnectivity(), 4222 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4223 doTestFirstEvaluation(naw -> naw.connectWithCaptivePortal(TEST_REDIRECT_URL, false), 4224 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4225 doTestFirstEvaluation(naw -> naw.connect(false /* validated */), 4226 false /* waitForSecondCaps */, false /* immediatelyEvaluated */); 4227 } 4228 4229 private void tryNetworkFactoryRequests(int capability) throws Exception { 4230 // Verify NOT_RESTRICTED is set appropriately 4231 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 4232 .build().networkCapabilities; 4233 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN 4234 || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA 4235 || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS 4236 || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP 4237 || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP 4238 || capability == NET_CAPABILITY_ENTERPRISE || capability == NET_CAPABILITY_MMTEL) { 4239 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4240 } else { 4241 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4242 } 4243 4244 NetworkCapabilities filter = new NetworkCapabilities(); 4245 filter.addTransportType(TRANSPORT_CELLULAR); 4246 filter.addCapability(capability); 4247 // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add 4248 // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, 4249 // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. 4250 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4251 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4252 handlerThread.start(); 4253 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4254 mServiceContext, "testFactory", filter, mCsHandlerThread); 4255 testFactory.setScoreFilter(45); 4256 testFactory.register(); 4257 4258 final NetworkCallback networkCallback; 4259 if (capability != NET_CAPABILITY_INTERNET) { 4260 // If the capability passed in argument is part of the default request, then the 4261 // factory will see the default request. Otherwise the filter will prevent the 4262 // factory from seeing it. In that case, add a request so it can be tested. 4263 assertFalse(testFactory.getMyStartRequested()); 4264 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 4265 networkCallback = new NetworkCallback(); 4266 mCm.requestNetwork(request, networkCallback); 4267 } else { 4268 networkCallback = null; 4269 } 4270 testFactory.expectRequestAdd(); 4271 testFactory.assertRequestCountEquals(1); 4272 assertTrue(testFactory.getMyStartRequested()); 4273 4274 // Now bring in a higher scored network. 4275 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4276 // When testAgent connects, because of its score (50 legacy int / cell transport) 4277 // it will beat or equal the testFactory's offer, so the request will be removed. 4278 // Note the agent as validated only if the capability is INTERNET, as it's the only case 4279 // where it makes sense. 4280 testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); 4281 testAgent.addCapability(capability); 4282 testFactory.expectRequestRemove(); 4283 testFactory.assertRequestCountEquals(0); 4284 assertFalse(testFactory.getMyStartRequested()); 4285 4286 // Add a request and make sure it's not sent to the factory, because the agent 4287 // is satisfying it better. 4288 final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); 4289 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); 4290 expectNoRequestChanged(testFactory); 4291 testFactory.assertRequestCountEquals(0); 4292 assertFalse(testFactory.getMyStartRequested()); 4293 4294 // If using legacy scores, make the test agent weak enough to have the exact same score as 4295 // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. 4296 // If not using legacy score, this is a no-op and the "same score removes request" behavior 4297 // has already been tested above. 4298 testAgent.adjustScore(-5); 4299 expectNoRequestChanged(testFactory); 4300 assertFalse(testFactory.getMyStartRequested()); 4301 4302 // Make the test agent weak enough that the factory will see the two requests (the one that 4303 // was just sent, and either the default one or the one sent at the top of this test if 4304 // the default won't be seen). 4305 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); 4306 testFactory.expectRequestAdds(2); 4307 testFactory.assertRequestCountEquals(2); 4308 assertTrue(testFactory.getMyStartRequested()); 4309 4310 // Now unregister and make sure the request is removed. 4311 mCm.unregisterNetworkCallback(cb); 4312 testFactory.expectRequestRemove(); 4313 4314 // Bring in a bunch of requests. 4315 assertEquals(1, testFactory.getMyRequestCount()); 4316 ConnectivityManager.NetworkCallback[] networkCallbacks = 4317 new ConnectivityManager.NetworkCallback[10]; 4318 for (int i = 0; i< networkCallbacks.length; i++) { 4319 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 4320 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4321 builder.addCapability(capability); 4322 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 4323 } 4324 testFactory.expectRequestAdds(10); 4325 testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request 4326 assertTrue(testFactory.getMyStartRequested()); 4327 4328 // Remove the requests. 4329 for (int i = 0; i < networkCallbacks.length; i++) { 4330 mCm.unregisterNetworkCallback(networkCallbacks[i]); 4331 } 4332 testFactory.expectRequestRemoves(10); 4333 testFactory.assertRequestCountEquals(1); 4334 assertTrue(testFactory.getMyStartRequested()); 4335 4336 // Adjust the agent score up again. Expect the request to be withdrawn. 4337 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); 4338 testFactory.expectRequestRemove(); 4339 testFactory.assertRequestCountEquals(0); 4340 assertFalse(testFactory.getMyStartRequested()); 4341 4342 // Drop the higher scored network. 4343 testAgent.disconnect(); 4344 testFactory.expectRequestAdd(); 4345 testFactory.assertRequestCountEquals(1); 4346 assertEquals(1, testFactory.getMyRequestCount()); 4347 assertTrue(testFactory.getMyStartRequested()); 4348 4349 testFactory.terminate(); 4350 testFactory.assertNoRequestChanged(); 4351 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 4352 4353 handlerThread.quitSafely(); 4354 handlerThread.join(); 4355 } 4356 4357 @Test 4358 public void testNetworkFactoryRequests() throws Exception { 4359 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 4360 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 4361 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 4362 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 4363 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 4364 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 4365 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 4366 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 4367 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 4368 tryNetworkFactoryRequests(NET_CAPABILITY_MMTEL); 4369 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 4370 tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); 4371 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 4372 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 4373 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 4374 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 4375 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 4376 tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); 4377 tryNetworkFactoryRequests(NET_CAPABILITY_BIP); 4378 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 4379 } 4380 4381 @Test 4382 public void testRegisterIgnoringScore() throws Exception { 4383 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4384 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); 4385 mWiFiAgent.connect(true /* validated */); 4386 4387 // Make sure the factory sees the default network 4388 final NetworkCapabilities filter = new NetworkCapabilities(); 4389 filter.addTransportType(TRANSPORT_CELLULAR); 4390 filter.addCapability(NET_CAPABILITY_INTERNET); 4391 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4392 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4393 handlerThread.start(); 4394 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4395 mServiceContext, "testFactory", filter, mCsHandlerThread); 4396 testFactory.register(); 4397 4398 final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), 4399 mServiceContext, "testFactoryAll", filter, mCsHandlerThread); 4400 testFactoryAll.registerIgnoringScore(); 4401 4402 // The regular test factory should not see the request, because WiFi is stronger than cell. 4403 expectNoRequestChanged(testFactory); 4404 // With ignoringScore though the request is seen. 4405 testFactoryAll.expectRequestAdd(); 4406 4407 // The legacy int will be ignored anyway, set the only other knob to true 4408 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) 4409 .setTransportPrimary(true).build()); 4410 4411 expectNoRequestChanged(testFactory); // still not seeing the request 4412 expectNoRequestChanged(testFactoryAll); // still seeing the request 4413 4414 mWiFiAgent.disconnect(); 4415 handlerThread.quitSafely(); 4416 handlerThread.join(); 4417 } 4418 4419 @Test 4420 public void testNetworkFactoryUnregister() throws Exception { 4421 // Make sure the factory sees the default network 4422 final NetworkCapabilities filter = new NetworkCapabilities(); 4423 filter.addCapability(NET_CAPABILITY_INTERNET); 4424 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4425 4426 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4427 handlerThread.start(); 4428 4429 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 4430 // does not crash. 4431 for (int i = 0; i < 100; i++) { 4432 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4433 mServiceContext, "testFactory", filter, mCsHandlerThread); 4434 // Register the factory and don't be surprised when the default request arrives. 4435 testFactory.register(); 4436 testFactory.expectRequestAdd(); 4437 4438 testFactory.setScoreFilter(42); 4439 testFactory.terminate(); 4440 testFactory.assertNoRequestChanged(); 4441 4442 if (i % 2 == 0) { 4443 try { 4444 testFactory.register(); 4445 fail("Re-registering terminated NetworkFactory should throw"); 4446 } catch (IllegalStateException expected) { 4447 } 4448 } 4449 } 4450 handlerThread.quitSafely(); 4451 handlerThread.join(); 4452 } 4453 4454 @Test 4455 public void testNoMutableNetworkRequests() throws Exception { 4456 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4457 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4458 final NetworkRequest request1 = new NetworkRequest.Builder() 4459 .addCapability(NET_CAPABILITY_VALIDATED) 4460 .build(); 4461 final NetworkRequest request2 = new NetworkRequest.Builder() 4462 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 4463 .build(); 4464 4465 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4466 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 4467 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 4468 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 4469 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 4470 } 4471 4472 @Test 4473 public void testNoAllowedUidsInNetworkRequests() throws Exception { 4474 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4475 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4476 final NetworkRequest r = new NetworkRequest.Builder().build(); 4477 final ArraySet<Integer> allowedUids = new ArraySet<>(); 4478 allowedUids.add(6); 4479 allowedUids.add(9); 4480 r.networkCapabilities.setAllowedUids(allowedUids); 4481 4482 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4483 final NetworkCallback cb = new NetworkCallback(); 4484 4485 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4486 assertThrows(expected, () -> mCm.requestNetwork(r, cb)); 4487 assertThrows(expected, () -> mCm.requestNetwork(r, pendingIntent)); 4488 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb)); 4489 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb, handler)); 4490 assertThrows(expected, () -> mCm.registerNetworkCallback(r, pendingIntent)); 4491 assertThrows(expected, () -> mCm.registerBestMatchingNetworkCallback(r, cb, handler)); 4492 4493 // Make sure that resetting the access UIDs to the empty set will allow calling 4494 // requestNetwork and registerNetworkCallback. 4495 r.networkCapabilities.setAllowedUids(Collections.emptySet()); 4496 mCm.requestNetwork(r, cb); 4497 mCm.unregisterNetworkCallback(cb); 4498 mCm.registerNetworkCallback(r, cb); 4499 mCm.unregisterNetworkCallback(cb); 4500 } 4501 4502 @Test 4503 public void testMMSonWiFi() throws Exception { 4504 // Test bringing up cellular without MMS NetworkRequest gets reaped 4505 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4506 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4507 mCellAgent.connectWithoutInternet(); 4508 mCellAgent.expectDisconnected(); 4509 waitForIdle(); 4510 assertEmpty(mCm.getAllNetworks()); 4511 verifyNoNetwork(); 4512 4513 // Test bringing up validated WiFi. 4514 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4515 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 4516 mWiFiAgent.connect(true); 4517 b.expectBroadcast(); 4518 verifyActiveNetwork(TRANSPORT_WIFI); 4519 4520 // Register MMS NetworkRequest 4521 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4522 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4523 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4524 mCm.requestNetwork(builder.build(), networkCallback); 4525 4526 // Test bringing up unvalidated cellular with MMS 4527 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4528 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4529 mCellAgent.connectWithoutInternet(); 4530 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 4531 verifyActiveNetwork(TRANSPORT_WIFI); 4532 4533 // Test releasing NetworkRequest disconnects cellular with MMS 4534 mCm.unregisterNetworkCallback(networkCallback); 4535 mCellAgent.expectDisconnected(); 4536 verifyActiveNetwork(TRANSPORT_WIFI); 4537 } 4538 4539 @Test 4540 public void testMMSonCell() throws Exception { 4541 // Test bringing up cellular without MMS 4542 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4543 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 4544 mCellAgent.connect(false); 4545 b.expectBroadcast(); 4546 verifyActiveNetwork(TRANSPORT_CELLULAR); 4547 4548 // Register MMS NetworkRequest 4549 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4550 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4551 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4552 mCm.requestNetwork(builder.build(), networkCallback); 4553 4554 // Test bringing up MMS cellular network 4555 TestNetworkAgentWrapper 4556 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4557 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4558 mmsNetworkAgent.connectWithoutInternet(); 4559 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 4560 verifyActiveNetwork(TRANSPORT_CELLULAR); 4561 4562 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 4563 mCm.unregisterNetworkCallback(networkCallback); 4564 mmsNetworkAgent.expectDisconnected(); 4565 verifyActiveNetwork(TRANSPORT_CELLULAR); 4566 } 4567 4568 @Test 4569 public void testPartialConnectivity() throws Exception { 4570 // Register network callback. 4571 NetworkRequest request = new NetworkRequest.Builder() 4572 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4573 .build(); 4574 TestNetworkCallback callback = new TestNetworkCallback(); 4575 mCm.registerNetworkCallback(request, callback); 4576 4577 // Bring up validated mobile data. 4578 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4579 mCellAgent.connect(true); 4580 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 4581 4582 // Bring up wifi with partial connectivity. 4583 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4584 mWiFiAgent.connectWithPartialConnectivity(); 4585 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4586 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4587 4588 // Mobile data should be the default network. 4589 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4590 callback.assertNoCallback(); 4591 4592 // Expect a PARTIAL_CONNECTIVITY notification. The notification appears as soon as partial 4593 // connectivity is detected, and is low priority because the network was not explicitly 4594 // selected by the user. This happens if we reconnect to a network where the user previously 4595 // accepted partial connectivity without checking "always". 4596 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4597 4598 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 4599 // probe. 4600 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4601 // If the user chooses yes to use this partial connectivity wifi, switch the default 4602 // network to wifi and check if wifi becomes valid or not. 4603 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4604 false /* always */); 4605 // If user accepts partial connectivity network, 4606 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 4607 waitForIdle(); 4608 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4609 4610 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4611 // validated. 4612 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4613 callback.expectLosing(mCellAgent); 4614 NetworkCapabilities nc = 4615 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4616 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4617 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4618 4619 // Once the network validates, the notification disappears. 4620 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4621 4622 // Disconnect and reconnect wifi with partial connectivity again. 4623 mWiFiAgent.disconnect(); 4624 callback.expect(LOST, mWiFiAgent); 4625 4626 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4627 mWiFiAgent.connectWithPartialConnectivity(); 4628 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4629 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4630 4631 // Mobile data should be the default network. 4632 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4633 waitForIdle(); 4634 4635 // Expect a low-priority PARTIAL_CONNECTIVITY notification as soon as partial connectivity 4636 // is detected. 4637 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4638 4639 // If the user chooses no, disconnect wifi immediately. 4640 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), false /* accept */, 4641 false /* always */); 4642 callback.expect(LOST, mWiFiAgent); 4643 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4644 reset(mNotificationManager); 4645 4646 // If the user accepted partial connectivity before, and the device connects to that network 4647 // again, but now the network has full connectivity, then the network shouldn't contain 4648 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 4649 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4650 // acceptUnvalidated is also used as setting for accepting partial networks. 4651 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4652 mWiFiAgent.connect(true); 4653 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4654 4655 // If user accepted partial connectivity network before, 4656 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4657 // ConnectivityService#updateNetworkInfo(). 4658 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4659 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4660 callback.expectLosing(mCellAgent); 4661 nc = callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4662 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4663 4664 // Wifi should be the default network. 4665 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4666 mWiFiAgent.disconnect(); 4667 callback.expect(LOST, mWiFiAgent); 4668 4669 // The user accepted partial connectivity and selected "don't ask again". Now the user 4670 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 4671 // connectivity is detected. 4672 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4673 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4674 mWiFiAgent.connectWithPartialConnectivity(); 4675 // If user accepted partial connectivity network before, 4676 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4677 // ConnectivityService#updateNetworkInfo(). 4678 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4679 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4680 callback.expectLosing(mCellAgent); 4681 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4682 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4683 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4684 4685 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4686 4687 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4688 // validated. 4689 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4690 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4691 mWiFiAgent.disconnect(); 4692 callback.expect(LOST, mWiFiAgent); 4693 4694 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 4695 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 4696 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4697 mWiFiAgent.explicitlySelected(false /* explicitlySelected */, true /* acceptUnvalidated */); 4698 4699 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 4700 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 4701 // notifyNetworkConnected. 4702 mWiFiAgent.connectWithPartialValidConnectivity(false /* privateDnsProbeSent */); 4703 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4704 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4705 callback.expectLosing(mCellAgent); 4706 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4707 && c.hasCapability(NET_CAPABILITY_VALIDATED)); 4708 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4709 mWiFiAgent.disconnect(); 4710 callback.expect(LOST, mWiFiAgent); 4711 verifyNoMoreInteractions(mNotificationManager); 4712 } 4713 4714 @Test 4715 public void testCaptivePortalOnPartialConnectivity() throws Exception { 4716 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 4717 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 4718 .addTransportType(TRANSPORT_WIFI) 4719 .build(); 4720 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 4721 4722 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4723 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4724 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4725 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4726 4727 // Bring up a network with a captive portal. 4728 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4729 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4730 String redirectUrl = "http://android.com/path"; 4731 mWiFiAgent.connectWithCaptivePortal(redirectUrl, false /* privateDnsProbeSent */); 4732 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4733 assertEquals(mWiFiAgent.waitForRedirectUrl(), redirectUrl); 4734 4735 // This is necessary because of b/245893397, the same bug that happens where we use 4736 // expectAvailableDoubleValidatedCallbacks. 4737 // TODO : fix b/245893397 and remove this. 4738 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4739 4740 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4741 mCm.startCaptivePortalApp(mWiFiAgent.getNetwork()); 4742 verify(mWiFiAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)).launchCaptivePortalApp(); 4743 4744 // Report that the captive portal is dismissed with partial connectivity, and check that 4745 // callbacks are fired with PARTIAL and without CAPTIVE_PORTAL. 4746 mWiFiAgent.setNetworkPartial(); 4747 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4748 waitForIdle(); 4749 wifiCallback.expectCaps(mWiFiAgent, 4750 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4751 && !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4752 4753 // Report partial connectivity is accepted. 4754 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4755 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4756 false /* always */); 4757 waitForIdle(); 4758 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4759 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4760 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4761 validatedCallback.expectCaps(mWiFiAgent, 4762 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4763 4764 mCm.unregisterNetworkCallback(wifiCallback); 4765 mCm.unregisterNetworkCallback(validatedCallback); 4766 } 4767 4768 @Test 4769 public void testCaptivePortal() throws Exception { 4770 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4771 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4772 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4773 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4774 4775 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4776 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4777 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4778 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4779 4780 // Bring up a network with a captive portal. 4781 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4782 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4783 String firstRedirectUrl = "http://example.com/firstPath"; 4784 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4785 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4786 assertEquals(mWiFiAgent.waitForRedirectUrl(), firstRedirectUrl); 4787 4788 // Take down network. 4789 // Expect onLost callback. 4790 mWiFiAgent.disconnect(); 4791 captivePortalCallback.expect(LOST, mWiFiAgent); 4792 4793 // Bring up a network with a captive portal. 4794 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4795 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4796 String secondRedirectUrl = "http://example.com/secondPath"; 4797 mWiFiAgent.connectWithCaptivePortal(secondRedirectUrl, false /* privateDnsProbeSent */); 4798 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4799 assertEquals(mWiFiAgent.waitForRedirectUrl(), secondRedirectUrl); 4800 4801 // Make captive portal disappear then revalidate. 4802 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 4803 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4804 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4805 captivePortalCallback.expect(LOST, mWiFiAgent); 4806 4807 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 4808 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4809 4810 // Break network connectivity. 4811 // Expect NET_CAPABILITY_VALIDATED onLost callback. 4812 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 4813 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 4814 validatedCallback.expect(LOST, mWiFiAgent); 4815 } 4816 4817 private Intent startCaptivePortalApp(TestNetworkAgentWrapper networkAgent) throws Exception { 4818 Network network = networkAgent.getNetwork(); 4819 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4820 mCm.startCaptivePortalApp(network); 4821 waitForIdle(); 4822 verify(networkAgent.mNetworkMonitor).launchCaptivePortalApp(); 4823 4824 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 4825 final Bundle testBundle = new Bundle(); 4826 final String testKey = "testkey"; 4827 final String testValue = "testvalue"; 4828 testBundle.putString(testKey, testValue); 4829 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 4830 PERMISSION_GRANTED); 4831 mCm.startCaptivePortalApp(network, testBundle); 4832 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 4833 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 4834 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 4835 return signInIntent; 4836 } 4837 4838 @Test 4839 public void testCaptivePortalApp() throws Exception { 4840 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4841 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4842 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4843 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4844 4845 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4846 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4847 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4848 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4849 4850 // Bring up wifi. 4851 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4852 mWiFiAgent.connect(true); 4853 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4854 Network wifiNetwork = mWiFiAgent.getNetwork(); 4855 4856 // Check that calling startCaptivePortalApp does nothing. 4857 final int fastTimeoutMs = 100; 4858 mCm.startCaptivePortalApp(wifiNetwork); 4859 waitForIdle(); 4860 verify(mWiFiAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 4861 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 4862 4863 // Turn into a captive portal. 4864 mWiFiAgent.setNetworkPortal("http://example.com", false /* privateDnsProbeSent */); 4865 mCm.reportNetworkConnectivity(wifiNetwork, false); 4866 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4867 validatedCallback.expect(LOST, mWiFiAgent); 4868 // This is necessary because of b/245893397, the same bug that happens where we use 4869 // expectAvailableDoubleValidatedCallbacks. 4870 // TODO : fix b/245893397 and remove this. 4871 captivePortalCallback.expectCaps(mWiFiAgent); 4872 4873 startCaptivePortalApp(mWiFiAgent); 4874 4875 // Report that the captive portal is dismissed, and check that callbacks are fired 4876 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4877 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4878 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4879 captivePortalCallback.expect(LOST, mWiFiAgent); 4880 4881 mCm.unregisterNetworkCallback(validatedCallback); 4882 mCm.unregisterNetworkCallback(captivePortalCallback); 4883 } 4884 4885 @Test 4886 public void testCaptivePortalApp_IgnoreNetwork() throws Exception { 4887 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4888 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4889 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4890 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4891 4892 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4893 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false); 4894 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4895 4896 final Intent signInIntent = startCaptivePortalApp(mWiFiAgent); 4897 final CaptivePortal captivePortal = signInIntent 4898 .getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL); 4899 4900 captivePortal.ignoreNetwork(); 4901 waitForIdle(); 4902 4903 // Since network will disconnect, ensure no notification of response to NetworkMonitor 4904 verify(mWiFiAgent.mNetworkMonitor, never()) 4905 .notifyCaptivePortalAppFinished(CaptivePortal.APP_RETURN_UNWANTED); 4906 4907 // Report that the network is disconnected 4908 mWiFiAgent.expectDisconnected(); 4909 mWiFiAgent.expectPreventReconnectReceived(); 4910 verify(mWiFiAgent.mNetworkMonitor).notifyNetworkDisconnected(); 4911 captivePortalCallback.expect(LOST, mWiFiAgent); 4912 4913 mCm.unregisterNetworkCallback(captivePortalCallback); 4914 } 4915 4916 @Test 4917 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 4918 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4919 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4920 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4921 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4922 4923 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4924 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4925 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4926 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4927 4928 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4929 // Bring up a network with a captive portal. 4930 // Expect it to fail to connect and not result in any callbacks. 4931 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4932 final String firstRedirectUrl = "http://example.com/firstPath"; 4933 4934 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4935 mWiFiAgent.expectDisconnected(); 4936 mWiFiAgent.expectPreventReconnectReceived(); 4937 4938 assertNoCallbacks(captivePortalCallback, validatedCallback); 4939 } 4940 4941 @Test 4942 public void testNoAvoidCaptivePortalOnWearProxy() throws Exception { 4943 // Bring up a BLUETOOTH network which is companion proxy on wear 4944 // then set captive portal. 4945 mockHasSystemFeature(PackageManager.FEATURE_WATCH, true); 4946 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4947 TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH); 4948 final String firstRedirectUrl = "http://example.com/firstPath"; 4949 4950 btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4951 btAgent.assertNotDisconnected(TIMEOUT_MS); 4952 } 4953 4954 @Test 4955 public void testAvoidCaptivePortalOnBluetooth() throws Exception { 4956 // When not on Wear, BLUETOOTH is just regular network, 4957 // then set captive portal. 4958 mockHasSystemFeature(PackageManager.FEATURE_WATCH, false); 4959 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4960 TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH); 4961 final String firstRedirectUrl = "http://example.com/firstPath"; 4962 4963 btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4964 4965 btAgent.expectDisconnected(); 4966 btAgent.expectPreventReconnectReceived(); 4967 } 4968 4969 @Test 4970 public void testCaptivePortalApi() throws Exception { 4971 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4972 4973 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4974 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4975 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4976 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4977 4978 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4979 final String redirectUrl = "http://example.com/firstPath"; 4980 4981 mWiFiAgent.connectWithCaptivePortal(redirectUrl, 4982 false /* privateDnsProbeSent */); 4983 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4984 4985 final CaptivePortalData testData = new CaptivePortalData.Builder() 4986 .setUserPortalUrl(Uri.parse(redirectUrl)) 4987 .setBytesRemaining(12345L) 4988 .build(); 4989 4990 mWiFiAgent.notifyCapportApiDataChanged(testData); 4991 4992 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4993 cb -> testData.equals(cb.getLp().getCaptivePortalData())); 4994 4995 final LinkProperties newLps = new LinkProperties(); 4996 newLps.setMtu(1234); 4997 mWiFiAgent.sendLinkProperties(newLps); 4998 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 4999 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5000 cb -> testData.equals(cb.getLp().getCaptivePortalData()) 5001 && cb.getLp().getMtu() == 1234); 5002 } 5003 5004 private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { 5005 // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks 5006 // with sensitive (captive portal) data 5007 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5008 5009 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 5010 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 5011 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 5012 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 5013 5014 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5015 5016 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, 5017 false /* privateDnsProbeSent */); 5018 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5019 return captivePortalCallback; 5020 } 5021 5022 private class CaptivePortalTestData { 5023 CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, 5024 CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, 5025 CaptivePortalData expectedMergedOtherData) { 5026 mNaPasspointData = naPasspointData; 5027 mCapportData = capportData; 5028 mNaOtherData = naOtherData; 5029 mExpectedMergedPasspointData = expectedMergedPasspointData; 5030 mExpectedMergedOtherData = expectedMergedOtherData; 5031 } 5032 5033 public final CaptivePortalData mNaPasspointData; 5034 public final CaptivePortalData mCapportData; 5035 public final CaptivePortalData mNaOtherData; 5036 public final CaptivePortalData mExpectedMergedPasspointData; 5037 public final CaptivePortalData mExpectedMergedOtherData; 5038 5039 } 5040 5041 private CaptivePortalTestData setupCaptivePortalData() { 5042 final CaptivePortalData capportData = new CaptivePortalData.Builder() 5043 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5044 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 5045 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 5046 .setExpiryTime(1000000L) 5047 .setBytesRemaining(12345L) 5048 .build(); 5049 5050 final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() 5051 .setBytesRemaining(80802L) 5052 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 5053 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5054 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 5055 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5056 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5057 5058 final CaptivePortalData naOtherData = new CaptivePortalData.Builder() 5059 .setBytesRemaining(80802L) 5060 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), 5061 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 5062 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), 5063 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 5064 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5065 5066 final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() 5067 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5068 .setBytesRemaining(12345L) 5069 .setExpiryTime(1000000L) 5070 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 5071 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5072 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 5073 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5074 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5075 5076 final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() 5077 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5078 .setBytesRemaining(12345L) 5079 .setExpiryTime(1000000L) 5080 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 5081 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 5082 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5083 return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, 5084 expectedMergedPasspointData, expectedMergedOtherData); 5085 } 5086 5087 @Test 5088 public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { 5089 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5090 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5091 5092 // Baseline capport data 5093 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5094 5095 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5096 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 5097 5098 // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm 5099 // that API data gets precedence on the bytes remaining. 5100 final LinkProperties linkProperties = new LinkProperties(); 5101 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5102 mWiFiAgent.sendLinkProperties(linkProperties); 5103 5104 // Make sure that the capport data is merged 5105 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5106 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 5107 cb.getLp().getCaptivePortalData())); 5108 5109 // Now send this information from non-Passpoint source, confirm that Capport data takes 5110 // precedence 5111 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 5112 mWiFiAgent.sendLinkProperties(linkProperties); 5113 5114 // Make sure that the capport data is merged 5115 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5116 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 5117 cb.getLp().getCaptivePortalData())); 5118 5119 // Create a new LP with no Network agent capport data 5120 final LinkProperties newLps = new LinkProperties(); 5121 newLps.setMtu(1234); 5122 mWiFiAgent.sendLinkProperties(newLps); 5123 // CaptivePortalData is not lost and has the original values when LPs are received from the 5124 // NetworkAgent 5125 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5126 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData()) 5127 && cb.getLp().getMtu() == 1234); 5128 5129 // Now send capport data only from the Network agent 5130 mWiFiAgent.notifyCapportApiDataChanged(null); 5131 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5132 cb -> cb.getLp().getCaptivePortalData() == null); 5133 5134 newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5135 mWiFiAgent.sendLinkProperties(newLps); 5136 5137 // Make sure that only the network agent capport data is available 5138 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5139 cb -> captivePortalTestData.mNaPasspointData.equals( 5140 cb.getLp().getCaptivePortalData())); 5141 } 5142 5143 @Test 5144 public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { 5145 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5146 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5147 5148 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5149 // on the bytes remaining. 5150 final LinkProperties linkProperties = new LinkProperties(); 5151 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5152 mWiFiAgent.sendLinkProperties(linkProperties); 5153 5154 // Make sure that the data is saved correctly 5155 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5156 cb -> captivePortalTestData.mNaPasspointData.equals( 5157 cb.getLp().getCaptivePortalData())); 5158 5159 // Expected merged data: Network agent data is preferred, and values that are not used by 5160 // it are merged from capport data 5161 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5162 5163 // Make sure that the Capport data is merged correctly 5164 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5165 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 5166 cb.getLp().getCaptivePortalData())); 5167 5168 // Now set the naData to null 5169 linkProperties.setCaptivePortalData(null); 5170 mWiFiAgent.sendLinkProperties(linkProperties); 5171 5172 // Make sure that the Capport data is retained correctly 5173 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5174 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 5175 } 5176 5177 @Test 5178 public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() 5179 throws Exception { 5180 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5181 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5182 5183 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5184 // on the bytes remaining. 5185 final LinkProperties linkProperties = new LinkProperties(); 5186 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 5187 mWiFiAgent.sendLinkProperties(linkProperties); 5188 5189 // Make sure that the data is saved correctly 5190 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5191 cb -> captivePortalTestData.mNaOtherData.equals(cb.getLp().getCaptivePortalData())); 5192 5193 // Expected merged data: Network agent data is preferred, and values that are not used by 5194 // it are merged from capport data 5195 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5196 5197 // Make sure that the Capport data is merged correctly 5198 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5199 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 5200 cb.getLp().getCaptivePortalData())); 5201 } 5202 5203 private NetworkRequest.Builder newWifiRequestBuilder() { 5204 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 5205 } 5206 5207 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 5208 static class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 5209 Parcelable { 5210 public static final Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier> CREATOR = 5211 new Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier>() { 5212 public ConfidentialMatchAllNetworkSpecifier createFromParcel(Parcel in) { 5213 return new ConfidentialMatchAllNetworkSpecifier(); 5214 } 5215 5216 public ConfidentialMatchAllNetworkSpecifier[] newArray(int size) { 5217 return new ConfidentialMatchAllNetworkSpecifier[size]; 5218 } 5219 }; 5220 @Override 5221 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5222 return true; 5223 } 5224 5225 @Override 5226 public int describeContents() { 5227 return 0; 5228 } 5229 5230 @Override 5231 public void writeToParcel(Parcel dest, int flags) {} 5232 5233 @Override 5234 public NetworkSpecifier redact() { 5235 return null; 5236 } 5237 } 5238 5239 // A network specifier that matches either another LocalNetworkSpecifier with the same 5240 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 5241 static class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 5242 public static final Parcelable.Creator<LocalStringNetworkSpecifier> CREATOR = 5243 new Parcelable.Creator<LocalStringNetworkSpecifier>() { 5244 public LocalStringNetworkSpecifier createFromParcel(Parcel in) { 5245 return new LocalStringNetworkSpecifier(in); 5246 } 5247 5248 public LocalStringNetworkSpecifier[] newArray(int size) { 5249 return new LocalStringNetworkSpecifier[size]; 5250 } 5251 }; 5252 private String mString; 5253 5254 LocalStringNetworkSpecifier(String string) { 5255 mString = string; 5256 } 5257 5258 LocalStringNetworkSpecifier(Parcel in) { 5259 mString = in.readString(); 5260 } 5261 5262 @Override 5263 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5264 if (other instanceof LocalStringNetworkSpecifier) { 5265 return TextUtils.equals(mString, 5266 ((LocalStringNetworkSpecifier) other).mString); 5267 } 5268 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 5269 return false; 5270 } 5271 5272 @Override 5273 public int describeContents() { 5274 return 0; 5275 } 5276 @Override 5277 public void writeToParcel(Parcel dest, int flags) { 5278 dest.writeString(mString); 5279 } 5280 } 5281 5282 /** 5283 * Verify request matching behavior with network specifiers. 5284 * 5285 * This test does not check updating the specifier on a live network because the specifier is 5286 * immutable and this triggers a WTF in 5287 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. 5288 */ 5289 @Test 5290 public void testNetworkSpecifier() throws Exception { 5291 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 5292 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 5293 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 5294 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 5295 (NetworkSpecifier) null).build(); 5296 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 5297 new LocalStringNetworkSpecifier("foo")).build(); 5298 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 5299 new LocalStringNetworkSpecifier("bar")).build(); 5300 5301 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 5302 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 5303 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 5304 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 5305 TestNetworkCallback cFoo = new TestNetworkCallback(); 5306 TestNetworkCallback cBar = new TestNetworkCallback(); 5307 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 5308 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 5309 5310 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 5311 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 5312 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 5313 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 5314 mCm.registerNetworkCallback(rFoo, cFoo); 5315 mCm.registerNetworkCallback(rBar, cBar); 5316 5317 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 5318 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 5319 5320 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5321 mWiFiAgent.connect(false); 5322 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5323 cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5324 assertNoCallbacks(cFoo, cBar); 5325 5326 mWiFiAgent.disconnect(); 5327 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5328 5329 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5330 mWiFiAgent.setNetworkSpecifier(nsFoo); 5331 mWiFiAgent.connect(false); 5332 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsFoo, 5333 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5334 cBar.assertNoCallback(); 5335 assertEquals(nsFoo, 5336 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5337 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5338 5339 mWiFiAgent.disconnect(); 5340 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5341 5342 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5343 mWiFiAgent.setNetworkSpecifier(nsBar); 5344 mWiFiAgent.connect(false); 5345 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsBar, 5346 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5347 cFoo.assertNoCallback(); 5348 assertEquals(nsBar, 5349 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5350 5351 mWiFiAgent.disconnect(); 5352 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5353 cFoo.assertNoCallback(); 5354 5355 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5356 mWiFiAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 5357 mWiFiAgent.connect(false); 5358 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5359 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5360 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5361 5362 mWiFiAgent.disconnect(); 5363 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5364 } 5365 5366 /** 5367 * @return the context's attribution tag 5368 */ 5369 private String getAttributionTag() { 5370 return mContext.getAttributionTag(); 5371 } 5372 5373 static class NonParcelableSpecifier extends NetworkSpecifier { 5374 @Override 5375 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5376 return false; 5377 } 5378 } 5379 static class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 5380 public static final Parcelable.Creator<NonParcelableSpecifier> CREATOR = 5381 new Parcelable.Creator<NonParcelableSpecifier>() { 5382 public NonParcelableSpecifier createFromParcel(Parcel in) { 5383 return new NonParcelableSpecifier(); 5384 } 5385 5386 public NonParcelableSpecifier[] newArray(int size) { 5387 return new NonParcelableSpecifier[size]; 5388 } 5389 }; 5390 @Override public int describeContents() { 5391 return 0; 5392 } 5393 @Override public void writeToParcel(Parcel p, int flags) {} 5394 } 5395 5396 @Test 5397 public void testInvalidNetworkSpecifier() { 5398 assertThrows(IllegalArgumentException.class, () -> { 5399 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 5400 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5401 }); 5402 5403 assertThrows(IllegalArgumentException.class, () -> { 5404 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 5405 networkCapabilities.addTransportType(TRANSPORT_WIFI) 5406 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5407 mService.requestNetwork(Process.INVALID_UID, networkCapabilities, 5408 NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, 5409 ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, 5410 mContext.getPackageName(), getAttributionTag()); 5411 }); 5412 5413 final NetworkRequest.Builder builder = 5414 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 5415 assertThrows(ClassCastException.class, () -> { 5416 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 5417 Parcel parcelW = Parcel.obtain(); 5418 builder.build().writeToParcel(parcelW, 0); 5419 }); 5420 5421 final NetworkRequest nr = 5422 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 5423 .setNetworkSpecifier(new ParcelableSpecifier()) 5424 .build(); 5425 assertNotNull(nr); 5426 5427 assertThrows(BadParcelableException.class, () -> { 5428 Parcel parcelW = Parcel.obtain(); 5429 nr.writeToParcel(parcelW, 0); 5430 byte[] bytes = parcelW.marshall(); 5431 parcelW.recycle(); 5432 5433 Parcel parcelR = Parcel.obtain(); 5434 parcelR.unmarshall(bytes, 0, bytes.length); 5435 parcelR.setDataPosition(0); 5436 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 5437 }); 5438 } 5439 5440 @Test 5441 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 5442 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5443 mWiFiAgent.connect(false); 5444 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 5445 TestNetworkCallback networkCallback = new TestNetworkCallback(); 5446 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 5447 assertThrows(SecurityException.class, () -> { 5448 mCm.requestNetwork(networkRequest, networkCallback); 5449 }); 5450 } 5451 5452 @Test 5453 public void testInvalidSignalStrength() { 5454 NetworkRequest r = new NetworkRequest.Builder() 5455 .addCapability(NET_CAPABILITY_INTERNET) 5456 .addTransportType(TRANSPORT_WIFI) 5457 .setSignalStrength(-75) 5458 .build(); 5459 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 5460 // permission should get SecurityException. 5461 assertThrows(SecurityException.class, () -> 5462 mCm.registerNetworkCallback(r, new NetworkCallback())); 5463 5464 assertThrows(SecurityException.class, () -> 5465 mCm.registerNetworkCallback(r, PendingIntent.getService( 5466 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5467 5468 // Requesting a Network with signal strength should get IllegalArgumentException. 5469 assertThrows(IllegalArgumentException.class, () -> 5470 mCm.requestNetwork(r, new NetworkCallback())); 5471 5472 assertThrows(IllegalArgumentException.class, () -> 5473 mCm.requestNetwork(r, PendingIntent.getService( 5474 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5475 } 5476 5477 @Test 5478 public void testRegisterDefaultNetworkCallback() throws Exception { 5479 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 5480 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 5481 defaultNetworkCallback.assertNoCallback(); 5482 5483 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5484 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 5485 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); 5486 systemDefaultCallback.assertNoCallback(); 5487 5488 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 5489 // whenever Wi-Fi is up. Without this, the mobile network agent is 5490 // reaped before any other activity can take place. 5491 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5492 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5493 .addTransportType(TRANSPORT_CELLULAR).build(); 5494 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5495 cellNetworkCallback.assertNoCallback(); 5496 5497 // Bring up cell and expect CALLBACK_AVAILABLE. 5498 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5499 mCellAgent.connect(true); 5500 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5501 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5502 systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5503 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5504 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5505 5506 // Bring up wifi and expect CALLBACK_AVAILABLE. 5507 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5508 mWiFiAgent.connect(true); 5509 cellNetworkCallback.assertNoCallback(); 5510 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5511 systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5512 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5513 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5514 5515 // Bring down cell. Expect no default network callback, since it wasn't the default. 5516 mCellAgent.disconnect(); 5517 cellNetworkCallback.expect(LOST, mCellAgent); 5518 defaultNetworkCallback.assertNoCallback(); 5519 systemDefaultCallback.assertNoCallback(); 5520 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5521 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5522 5523 // Bring up cell. Expect no default network callback, since it won't be the default. 5524 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5525 mCellAgent.connect(true); 5526 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5527 defaultNetworkCallback.assertNoCallback(); 5528 systemDefaultCallback.assertNoCallback(); 5529 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5530 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5531 5532 // Bring down wifi. Expect the default network callback to notified of LOST wifi 5533 // followed by AVAILABLE cell. 5534 mWiFiAgent.disconnect(); 5535 cellNetworkCallback.assertNoCallback(); 5536 defaultNetworkCallback.expect(LOST, mWiFiAgent); 5537 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5538 systemDefaultCallback.expect(LOST, mWiFiAgent); 5539 systemDefaultCallback.expectAvailableCallbacksValidated(mCellAgent); 5540 mCellAgent.disconnect(); 5541 cellNetworkCallback.expect(LOST, mCellAgent); 5542 defaultNetworkCallback.expect(LOST, mCellAgent); 5543 systemDefaultCallback.expect(LOST, mCellAgent); 5544 waitForIdle(); 5545 assertEquals(null, mCm.getActiveNetwork()); 5546 5547 mMockVpn.establishForMyUid(); 5548 assertUidRangesUpdatedForMyUid(true); 5549 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5550 systemDefaultCallback.assertNoCallback(); 5551 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5552 assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); 5553 5554 mMockVpn.disconnect(); 5555 defaultNetworkCallback.expect(LOST, mMockVpn); 5556 systemDefaultCallback.assertNoCallback(); 5557 waitForIdle(); 5558 assertEquals(null, mCm.getActiveNetwork()); 5559 } 5560 5561 @Test 5562 public void testAdditionalStateCallbacks() throws Exception { 5563 // File a network request for mobile. 5564 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5565 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5566 .addTransportType(TRANSPORT_CELLULAR).build(); 5567 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5568 5569 // Bring up the mobile network. 5570 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5571 mCellAgent.connect(true); 5572 5573 // We should get onAvailable(), onCapabilitiesChanged(), and 5574 // onLinkPropertiesChanged() in rapid succession. Additionally, we 5575 // should get onCapabilitiesChanged() when the mobile network validates. 5576 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5577 cellNetworkCallback.assertNoCallback(); 5578 5579 // Update LinkProperties. 5580 final LinkProperties lp = new LinkProperties(); 5581 lp.setInterfaceName("foonet_data0"); 5582 mCellAgent.sendLinkProperties(lp); 5583 // We should get onLinkPropertiesChanged(). 5584 cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 5585 cellNetworkCallback.assertNoCallback(); 5586 5587 // Suspend the network. 5588 mCellAgent.suspend(); 5589 cellNetworkCallback.expectCaps(mCellAgent, 5590 c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5591 cellNetworkCallback.expect(SUSPENDED, mCellAgent); 5592 cellNetworkCallback.assertNoCallback(); 5593 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 5594 5595 // Register a garden variety default network request. 5596 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 5597 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5598 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 5599 // as well as onNetworkSuspended() in rapid succession. 5600 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellAgent, true); 5601 dfltNetworkCallback.assertNoCallback(); 5602 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5603 5604 mCellAgent.resume(); 5605 cellNetworkCallback.expectCaps(mCellAgent, 5606 c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5607 cellNetworkCallback.expect(RESUMED, mCellAgent); 5608 cellNetworkCallback.assertNoCallback(); 5609 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 5610 5611 dfltNetworkCallback = new TestNetworkCallback(); 5612 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5613 // This time onNetworkSuspended should not be called. 5614 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5615 dfltNetworkCallback.assertNoCallback(); 5616 5617 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5618 mCm.unregisterNetworkCallback(cellNetworkCallback); 5619 } 5620 5621 @Test 5622 public void testRegisterPrivilegedDefaultCallbacksRequirePermissions() throws Exception { 5623 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5624 mCellAgent.connect(false /* validated */); 5625 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5626 5627 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5628 final TestNetworkCallback callback = new TestNetworkCallback(); 5629 assertThrows(SecurityException.class, 5630 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); 5631 callback.assertNoCallback(); 5632 assertThrows(SecurityException.class, 5633 () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); 5634 callback.assertNoCallback(); 5635 5636 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 5637 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5638 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5639 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5640 mCm.unregisterNetworkCallback(callback); 5641 5642 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5643 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5644 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5645 mCm.unregisterNetworkCallback(callback); 5646 5647 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 5648 mServiceContext.setPermission(NETWORK_SETUP_WIZARD, PERMISSION_GRANTED); 5649 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5650 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5651 mCm.unregisterNetworkCallback(callback); 5652 5653 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5654 mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); 5655 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5656 mCm.unregisterNetworkCallback(callback); 5657 } 5658 5659 @Test 5660 public void testNetworkCallbackWithNullUids() throws Exception { 5661 final NetworkRequest request = new NetworkRequest.Builder() 5662 .removeCapability(NET_CAPABILITY_NOT_VPN) 5663 .build(); 5664 final TestNetworkCallback callback = new TestNetworkCallback(); 5665 mCm.registerNetworkCallback(request, callback); 5666 5667 // Attempt to file a callback for networks applying to another UID. This does not actually 5668 // work, because this code does not currently have permission to do so. The callback behaves 5669 // exactly the same as the one registered just above. 5670 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5671 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5672 .removeCapability(NET_CAPABILITY_NOT_VPN) 5673 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5674 .build(); 5675 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5676 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5677 5678 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5679 .removeCapability(NET_CAPABILITY_NOT_VPN) 5680 .setIncludeOtherUidNetworks(true) 5681 .build(); 5682 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5683 mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback); 5684 5685 // Both callbacks see a network with no specifier that applies to their UID. 5686 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5687 mWiFiAgent.connect(false /* validated */); 5688 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5689 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5690 includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5691 mWiFiAgent.disconnect(); 5692 callback.expect(LOST, mWiFiAgent); 5693 otherUidCallback.expect(LOST, mWiFiAgent); 5694 includeOtherUidsCallback.expect(LOST, mWiFiAgent); 5695 5696 // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID. 5697 final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 5698 final Set<UidRange> vpnRanges = Collections.singleton(range); 5699 mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges); 5700 includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5701 callback.assertNoCallback(); 5702 otherUidCallback.assertNoCallback(); 5703 5704 mMockVpn.disconnect(); 5705 includeOtherUidsCallback.expect(LOST, mMockVpn); 5706 callback.assertNoCallback(); 5707 otherUidCallback.assertNoCallback(); 5708 } 5709 5710 private static class RedactableNetworkSpecifier extends NetworkSpecifier { 5711 public static final int ID_INVALID = -1; 5712 5713 public final int networkId; 5714 5715 RedactableNetworkSpecifier(int networkId) { 5716 this.networkId = networkId; 5717 } 5718 5719 @Override 5720 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5721 return other instanceof RedactableNetworkSpecifier 5722 && this.networkId == ((RedactableNetworkSpecifier) other).networkId; 5723 } 5724 5725 @Override 5726 public NetworkSpecifier redact() { 5727 return new RedactableNetworkSpecifier(ID_INVALID); 5728 } 5729 } 5730 5731 @Test 5732 public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception { 5733 final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42); 5734 final NetworkRequest request = new NetworkRequest.Builder() 5735 .addCapability(NET_CAPABILITY_INTERNET) 5736 .addTransportType(TRANSPORT_WIFI) 5737 .setNetworkSpecifier(specifier) 5738 .build(); 5739 final TestNetworkCallback callback = new TestNetworkCallback(); 5740 mCm.registerNetworkCallback(request, callback); 5741 5742 // Attempt to file a callback for networks applying to another UID. This does not actually 5743 // work, because this code does not currently have permission to do so. The callback behaves 5744 // exactly the same as the one registered just above. 5745 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5746 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5747 .addCapability(NET_CAPABILITY_INTERNET) 5748 .addTransportType(TRANSPORT_WIFI) 5749 .setNetworkSpecifier(specifier) 5750 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5751 .build(); 5752 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5753 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5754 5755 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5756 .addCapability(NET_CAPABILITY_INTERNET) 5757 .addTransportType(TRANSPORT_WIFI) 5758 .setNetworkSpecifier(specifier) 5759 .setIncludeOtherUidNetworks(true) 5760 .build(); 5761 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5762 mCm.registerNetworkCallback(includeOtherUidsRequest, callback); 5763 5764 // Only the regular callback sees the network, because callbacks filed with no UID have 5765 // their specifiers redacted. 5766 final LinkProperties emptyLp = new LinkProperties(); 5767 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 5768 .addTransportType(TRANSPORT_WIFI) 5769 .setNetworkSpecifier(specifier); 5770 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate); 5771 mWiFiAgent.connect(false /* validated */); 5772 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5773 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5774 includeOtherUidsCallback.assertNoCallback(); 5775 } 5776 5777 private void setCaptivePortalMode(int mode) { 5778 ContentResolver cr = mServiceContext.getContentResolver(); 5779 Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); 5780 } 5781 5782 private void setAlwaysOnNetworks(boolean enable) { 5783 ContentResolver cr = mServiceContext.getContentResolver(); 5784 Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, 5785 enable ? 1 : 0); 5786 mService.updateAlwaysOnNetworks(); 5787 waitForIdle(); 5788 } 5789 5790 private void setPrivateDnsSettings(int mode, String specifier) { 5791 ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); 5792 ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); 5793 mService.updatePrivateDnsSettings(); 5794 waitForIdle(); 5795 } 5796 5797 private void setIngressRateLimit(int rateLimitInBytesPerSec) { 5798 ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mServiceContext, 5799 rateLimitInBytesPerSec); 5800 mService.updateIngressRateLimit(); 5801 waitForIdle(); 5802 } 5803 5804 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 5805 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 5806 assertNotNull(nc); 5807 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 5808 } 5809 5810 @Test 5811 public void testBackgroundNetworks() throws Exception { 5812 // Create a cellular background request. 5813 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5814 final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); 5815 mCm.requestBackgroundNetwork(new NetworkRequest.Builder() 5816 .addTransportType(TRANSPORT_CELLULAR).build(), 5817 cellBgCallback, mCsHandlerThread.getThreadHandler()); 5818 5819 // Make callbacks for monitoring. 5820 final NetworkRequest request = new NetworkRequest.Builder().build(); 5821 final NetworkRequest fgRequest = new NetworkRequest.Builder() 5822 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 5823 final TestNetworkCallback callback = new TestNetworkCallback(); 5824 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 5825 mCm.registerNetworkCallback(request, callback); 5826 mCm.registerNetworkCallback(fgRequest, fgCallback); 5827 5828 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5829 mCellAgent.connect(true); 5830 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 5831 fgCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5832 assertTrue(isForegroundNetwork(mCellAgent)); 5833 5834 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5835 mWiFiAgent.connect(true); 5836 5837 // When wifi connects, cell lingers. 5838 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5839 callback.expectLosing(mCellAgent); 5840 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5841 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5842 fgCallback.expectLosing(mCellAgent); 5843 fgCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5844 assertTrue(isForegroundNetwork(mCellAgent)); 5845 assertTrue(isForegroundNetwork(mWiFiAgent)); 5846 5847 // When lingering is complete, cell is still there but is now in the background. 5848 waitForIdle(); 5849 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 5850 fgCallback.expect(LOST, mCellAgent, timeoutMs); 5851 // Expect a network capabilities update sans FOREGROUND. 5852 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5853 assertFalse(isForegroundNetwork(mCellAgent)); 5854 assertTrue(isForegroundNetwork(mWiFiAgent)); 5855 5856 // File a cell request and check that cell comes into the foreground. 5857 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5858 .addTransportType(TRANSPORT_CELLULAR).build(); 5859 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 5860 mCm.requestNetwork(cellRequest, cellCallback); 5861 cellCallback.expectAvailableCallbacksValidated(mCellAgent); 5862 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5863 // Expect a network capabilities update with FOREGROUND, because the most recent 5864 // request causes its state to change. 5865 cellCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5866 callback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5867 assertTrue(isForegroundNetwork(mCellAgent)); 5868 assertTrue(isForegroundNetwork(mWiFiAgent)); 5869 5870 // Release the request. The network immediately goes into the background, since it was not 5871 // lingering. 5872 mCm.unregisterNetworkCallback(cellCallback); 5873 fgCallback.expect(LOST, mCellAgent); 5874 // Expect a network capabilities update sans FOREGROUND. 5875 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5876 assertFalse(isForegroundNetwork(mCellAgent)); 5877 assertTrue(isForegroundNetwork(mWiFiAgent)); 5878 5879 // Disconnect wifi and check that cell is foreground again. 5880 mWiFiAgent.disconnect(); 5881 callback.expect(LOST, mWiFiAgent); 5882 fgCallback.expect(LOST, mWiFiAgent); 5883 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5884 assertTrue(isForegroundNetwork(mCellAgent)); 5885 5886 mCm.unregisterNetworkCallback(callback); 5887 mCm.unregisterNetworkCallback(fgCallback); 5888 mCm.unregisterNetworkCallback(cellBgCallback); 5889 } 5890 5891 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. 5892 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 5893 // TODO: turn this unit test into a real benchmarking test. 5894 // Benchmarks connecting and switching performance in the presence of a large number of 5895 // NetworkRequests. 5896 // 1. File NUM_REQUESTS requests. 5897 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 5898 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 5899 // and NUM_REQUESTS onAvailable callbacks to fire. 5900 // See how long it took. 5901 final int NUM_REQUESTS = 90; 5902 final int REGISTER_TIME_LIMIT_MS = 200; 5903 final int CONNECT_TIME_LIMIT_MS = 60; 5904 final int SWITCH_TIME_LIMIT_MS = 60; 5905 final int UNREGISTER_TIME_LIMIT_MS = 20; 5906 5907 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 5908 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 5909 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 5910 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 5911 5912 for (int i = 0; i < NUM_REQUESTS; i++) { 5913 callbacks[i] = new NetworkCallback() { 5914 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 5915 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 5916 }; 5917 } 5918 5919 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 5920 for (NetworkCallback cb : callbacks) { 5921 mCm.registerNetworkCallback(request, cb); 5922 } 5923 }); 5924 5925 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5926 // Don't request that the network validate, because otherwise connect() will block until 5927 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 5928 // and we won't actually measure anything. 5929 mCellAgent.connect(false); 5930 5931 long onAvailableDispatchingDuration = durationOf(() -> { 5932 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 5933 }); 5934 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 5935 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 5936 onAvailableDispatchingDuration)); 5937 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 5938 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 5939 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 5940 5941 // Give wifi a high enough score that we'll linger cell when wifi comes up. 5942 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5943 mWiFiAgent.adjustScore(40); 5944 mWiFiAgent.connect(false); 5945 5946 long onLostDispatchingDuration = durationOf(() -> { 5947 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 5948 }); 5949 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 5950 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 5951 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 5952 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 5953 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 5954 5955 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 5956 for (NetworkCallback cb : callbacks) { 5957 mCm.unregisterNetworkCallback(cb); 5958 } 5959 }); 5960 } 5961 5962 @Test 5963 public void testMobileDataAlwaysOn() throws Exception { 5964 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5965 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5966 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5967 .addTransportType(TRANSPORT_CELLULAR).build(); 5968 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 5969 5970 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 5971 handlerThread.start(); 5972 NetworkCapabilities filter = new NetworkCapabilities() 5973 .addTransportType(TRANSPORT_CELLULAR) 5974 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5975 .addCapability(NET_CAPABILITY_INTERNET); 5976 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 5977 mServiceContext, "testFactory", filter, mCsHandlerThread); 5978 testFactory.setScoreFilter(40); 5979 5980 // Register the factory and expect it to start looking for a network. 5981 testFactory.register(); 5982 5983 try { 5984 // Expect the factory to receive the default network request. 5985 testFactory.expectRequestAdd(); 5986 testFactory.assertRequestCountEquals(1); 5987 assertTrue(testFactory.getMyStartRequested()); 5988 5989 // Bring up wifi. The factory stops looking for a network. 5990 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5991 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 5992 mWiFiAgent.connect(true); 5993 // The network connects with a low score, so the offer can still beat it and 5994 // nothing happens. Then the network validates, and the offer with its filter score 5995 // of 40 can no longer beat it and the request is removed. 5996 testFactory.expectRequestRemove(); 5997 testFactory.assertRequestCountEquals(0); 5998 5999 assertFalse(testFactory.getMyStartRequested()); 6000 6001 // Turn on mobile data always on. This request will not match the wifi request, so 6002 // it will be sent to the test factory whose filters allow to see it. 6003 setAlwaysOnNetworks(true); 6004 testFactory.expectRequestAdd(); 6005 testFactory.assertRequestCountEquals(1); 6006 6007 assertTrue(testFactory.getMyStartRequested()); 6008 6009 // Bring up cell data and check that the factory stops looking. 6010 assertLength(1, mCm.getAllNetworks()); 6011 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6012 mCellAgent.connect(false); 6013 cellNetworkCallback.expectAvailableCallbacks(mCellAgent, false, false, false, 6014 TEST_CALLBACK_TIMEOUT_MS); 6015 // When cell connects, it will satisfy the "mobile always on request" right away 6016 // by virtue of being the only network that can satisfy the request. However, its 6017 // score is low (50 - 40 = 10) so the test factory can still hope to beat it. 6018 expectNoRequestChanged(testFactory); 6019 6020 // Next, cell validates. This gives it a score of 50 and the test factory can't 6021 // hope to beat that according to its filters. It will see the message that its 6022 // offer is now unnecessary. 6023 mCellAgent.setNetworkValid(true); 6024 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 6025 // validated – see testPartialConnectivity. 6026 mCm.reportNetworkConnectivity(mCellAgent.getNetwork(), true); 6027 cellNetworkCallback.expectCaps(mCellAgent, 6028 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6029 testFactory.expectRequestRemove(); 6030 testFactory.assertRequestCountEquals(0); 6031 // Accordingly, the factory shouldn't be started. 6032 assertFalse(testFactory.getMyStartRequested()); 6033 6034 // Check that cell data stays up. 6035 waitForIdle(); 6036 verifyActiveNetwork(TRANSPORT_WIFI); 6037 assertLength(2, mCm.getAllNetworks()); 6038 6039 // Cell disconnects. There is still the "mobile data always on" request outstanding, 6040 // and the test factory should see it now that it isn't hopelessly outscored. 6041 mCellAgent.disconnect(); 6042 cellNetworkCallback.expect(LOST, mCellAgent); 6043 // Wait for the network to be removed from internal structures before 6044 // calling synchronous getter 6045 waitForIdle(); 6046 assertLength(1, mCm.getAllNetworks()); 6047 testFactory.expectRequestAdd(); 6048 testFactory.assertRequestCountEquals(1); 6049 6050 // Reconnect cell validated, see the request disappear again. Then withdraw the 6051 // mobile always on request. This will tear down cell, and there shouldn't be a 6052 // blip where the test factory briefly sees the request or anything. 6053 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6054 mCellAgent.connect(true); 6055 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6056 waitForIdle(); 6057 assertLength(2, mCm.getAllNetworks()); 6058 testFactory.expectRequestRemove(); 6059 testFactory.assertRequestCountEquals(0); 6060 setAlwaysOnNetworks(false); 6061 expectNoRequestChanged(testFactory); 6062 testFactory.assertRequestCountEquals(0); 6063 assertFalse(testFactory.getMyStartRequested()); 6064 // ... and cell data to be torn down immediately since it is no longer nascent. 6065 cellNetworkCallback.expect(LOST, mCellAgent); 6066 waitForIdle(); 6067 assertLength(1, mCm.getAllNetworks()); 6068 testFactory.terminate(); 6069 testFactory.assertNoRequestChanged(); 6070 } finally { 6071 mCm.unregisterNetworkCallback(cellNetworkCallback); 6072 handlerThread.quitSafely(); 6073 handlerThread.join(); 6074 } 6075 } 6076 6077 @Test 6078 public void testSetAllowBadWifiUntil() throws Exception { 6079 runAsShell(NETWORK_SETTINGS, 6080 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L)); 6081 waitForIdle(); 6082 testAvoidBadWifiConfig_controlledBySettings(); 6083 6084 runAsShell(NETWORK_SETTINGS, 6085 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L)); 6086 waitForIdle(); 6087 testAvoidBadWifiConfig_ignoreSettings(); 6088 } 6089 6090 private void testAvoidBadWifiConfig_controlledBySettings() { 6091 final ContentResolver cr = mServiceContext.getContentResolver(); 6092 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 6093 6094 Settings.Global.putString(cr, settingName, "0"); 6095 mPolicyTracker.reevaluate(); 6096 waitForIdle(); 6097 assertFalse(mService.avoidBadWifi()); 6098 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6099 6100 Settings.Global.putString(cr, settingName, "1"); 6101 mPolicyTracker.reevaluate(); 6102 waitForIdle(); 6103 assertTrue(mService.avoidBadWifi()); 6104 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6105 6106 Settings.Global.putString(cr, settingName, null); 6107 mPolicyTracker.reevaluate(); 6108 waitForIdle(); 6109 assertFalse(mService.avoidBadWifi()); 6110 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6111 } 6112 6113 private void testAvoidBadWifiConfig_ignoreSettings() { 6114 final ContentResolver cr = mServiceContext.getContentResolver(); 6115 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 6116 6117 String[] values = new String[] {null, "0", "1"}; 6118 for (int i = 0; i < values.length; i++) { 6119 Settings.Global.putString(cr, settingName, values[i]); 6120 mPolicyTracker.reevaluate(); 6121 waitForIdle(); 6122 String msg = String.format("config=false, setting=%s", values[i]); 6123 assertTrue(mService.avoidBadWifi()); 6124 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 6125 } 6126 } 6127 6128 @Test 6129 public void testAvoidBadWifiSetting() throws Exception { 6130 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6131 testAvoidBadWifiConfig_ignoreSettings(); 6132 6133 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6134 testAvoidBadWifiConfig_controlledBySettings(); 6135 } 6136 6137 @Test 6138 public void testActivelyPreferBadWifiSetting() throws Exception { 6139 doReturn(1).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 6140 mPolicyTracker.reevaluate(); 6141 waitForIdle(); 6142 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6143 6144 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 6145 mPolicyTracker.reevaluate(); 6146 waitForIdle(); 6147 if (mDeps.isAtLeastU()) { 6148 // U+ ignore the setting and always actively prefers bad wifi 6149 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6150 } else { 6151 assertFalse(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6152 } 6153 } 6154 6155 @Test 6156 public void testOffersAvoidsBadWifi() throws Exception { 6157 // Normal mode : the carrier doesn't restrict moving away from bad wifi. 6158 // This has getAvoidBadWifi return true. 6159 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6160 // Don't request cell separately for the purposes of this test. 6161 setAlwaysOnNetworks(false); 6162 6163 final NetworkProvider cellProvider = new NetworkProvider(mServiceContext, 6164 mCsHandlerThread.getLooper(), "Cell provider"); 6165 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 6166 mCsHandlerThread.getLooper(), "Wifi provider"); 6167 6168 mCm.registerNetworkProvider(cellProvider); 6169 mCm.registerNetworkProvider(wifiProvider); 6170 6171 final NetworkScore cellScore = new NetworkScore.Builder().build(); 6172 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 6173 final NetworkCapabilities defaultCaps = new NetworkCapabilities.Builder() 6174 .addCapability(NET_CAPABILITY_INTERNET) 6175 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6176 .build(); 6177 final NetworkCapabilities cellCaps = new NetworkCapabilities.Builder() 6178 .addTransportType(TRANSPORT_CELLULAR) 6179 .addCapability(NET_CAPABILITY_INTERNET) 6180 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6181 .build(); 6182 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 6183 .addTransportType(TRANSPORT_WIFI) 6184 .addCapability(NET_CAPABILITY_INTERNET) 6185 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6186 .build(); 6187 final TestableNetworkOfferCallback cellCallback = new TestableNetworkOfferCallback( 6188 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6189 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 6190 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6191 6192 // Offer callbacks will run on the CS handler thread in this test. 6193 cellProvider.registerNetworkOffer(cellScore, cellCaps, r -> r.run(), cellCallback); 6194 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 6195 6196 // Both providers see the default request. 6197 cellCallback.expectOnNetworkNeeded(defaultCaps); 6198 wifiCallback.expectOnNetworkNeeded(defaultCaps); 6199 6200 // Listen to cell and wifi to know when agents are finished processing 6201 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6202 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6203 .addTransportType(TRANSPORT_CELLULAR).build(); 6204 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 6205 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 6206 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6207 .addTransportType(TRANSPORT_WIFI).build(); 6208 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 6209 6210 // Cell connects and validates. 6211 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 6212 new LinkProperties(), null /* ncTemplate */, cellProvider); 6213 mCellAgent.connect(true); 6214 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6215 cellCallback.assertNoCallback(); 6216 wifiCallback.assertNoCallback(); 6217 6218 // Bring up wifi. At first it's invalidated, so cell is still needed. 6219 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6220 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6221 mWiFiAgent.connect(false); 6222 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6223 cellCallback.assertNoCallback(); 6224 wifiCallback.assertNoCallback(); 6225 6226 // Wifi validates. Cell is no longer needed, because it's outscored. 6227 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6228 // Have CS reconsider the network (see testPartialConnectivity) 6229 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6230 wifiNetworkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6231 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6232 wifiCallback.assertNoCallback(); 6233 6234 // Wifi is no longer validated. Cell is needed again. 6235 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6236 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6237 wifiNetworkCallback.expectCaps(mWiFiAgent, 6238 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6239 cellCallback.expectOnNetworkNeeded(defaultCaps); 6240 wifiCallback.assertNoCallback(); 6241 6242 // Disconnect wifi and pretend the carrier restricts moving away from bad wifi. 6243 mWiFiAgent.disconnect(); 6244 wifiNetworkCallback.expect(LOST, mWiFiAgent); 6245 // This has getAvoidBadWifi return false. This test doesn't change the value of the 6246 // associated setting. 6247 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6248 mPolicyTracker.reevaluate(); 6249 waitForIdle(); 6250 6251 // Connect wifi again, cell is needed until wifi validates. 6252 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6253 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6254 mWiFiAgent.connect(false); 6255 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6256 cellCallback.assertNoCallback(); 6257 wifiCallback.assertNoCallback(); 6258 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6259 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6260 wifiNetworkCallback.expectCaps(mWiFiAgent, 6261 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6262 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6263 wifiCallback.assertNoCallback(); 6264 6265 // Wifi loses validation. Because the device doesn't avoid bad wifis, cell is 6266 // not needed. 6267 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6268 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6269 wifiNetworkCallback.expectCaps(mWiFiAgent, 6270 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6271 cellCallback.assertNoCallback(); 6272 wifiCallback.assertNoCallback(); 6273 } 6274 6275 public void doTestPreferBadWifi(final boolean avoidBadWifi, 6276 final boolean preferBadWifi, final boolean explicitlySelected, 6277 @NonNull Predicate<Long> checkUnvalidationTimeout) throws Exception { 6278 // Pretend we're on a carrier that restricts switching away from bad wifi, and 6279 // depending on the parameter one that may indeed prefer bad wifi. 6280 doReturn(avoidBadWifi ? 1 : 0).when(mResources) 6281 .getInteger(R.integer.config_networkAvoidBadWifi); 6282 doReturn(preferBadWifi ? 1 : 0).when(mResources) 6283 .getInteger(R.integer.config_activelyPreferBadWifi); 6284 mPolicyTracker.reevaluate(); 6285 6286 registerDefaultNetworkCallbacks(); 6287 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6288 .clearCapabilities() 6289 .addTransportType(TRANSPORT_WIFI) 6290 .build(); 6291 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 6292 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 6293 6294 // Bring up validated cell and unvalidated wifi. 6295 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6296 mCellAgent.connect(true); 6297 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6298 6299 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6300 mWiFiAgent.explicitlySelected(explicitlySelected, false /* acceptUnvalidated */); 6301 mWiFiAgent.connect(false); 6302 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6303 6304 assertNotNull(mDeps.mScheduledEvaluationTimeouts.poll(TIMEOUT_MS, 6305 t -> t.first == mWiFiAgent.getNetwork().netId 6306 && checkUnvalidationTimeout.test(t.second))); 6307 6308 if (!avoidBadWifi && preferBadWifi) { 6309 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.LOST_INTERNET); 6310 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6311 } else { 6312 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 6313 mDefaultNetworkCallback.assertNoCallback(); 6314 } 6315 } 6316 6317 @Test 6318 public void testPreferBadWifi_doNotAvoid_doNotPrefer() throws Exception { 6319 // Starting with U this mode is no longer supported and can't actually be tested 6320 assumeFalse(mDeps.isAtLeastU()); 6321 doTestPreferBadWifi(false /* avoidBadWifi */, false /* preferBadWifi */, 6322 false /* explicitlySelected */, timeout -> timeout < 14_000); 6323 } 6324 6325 @Test 6326 public void testPreferBadWifi_doNotAvoid_doPrefer_notExplicit() throws Exception { 6327 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6328 false /* explicitlySelected */, timeout -> timeout > 14_000); 6329 } 6330 6331 @Test 6332 public void testPreferBadWifi_doNotAvoid_doPrefer_explicitlySelected() throws Exception { 6333 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6334 true /* explicitlySelected */, timeout -> timeout < 14_000); 6335 } 6336 6337 @Test 6338 public void testPreferBadWifi_doAvoid_doNotPrefer() throws Exception { 6339 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6340 doTestPreferBadWifi(true /* avoidBadWifi */, false /* preferBadWifi */, 6341 false /* explicitlySelected */, timeout -> timeout < 14_000); 6342 } 6343 6344 @Test 6345 public void testPreferBadWifi_doAvoid_doPrefer() throws Exception { 6346 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6347 doTestPreferBadWifi(true /* avoidBadWifi */, true /* preferBadWifi */, 6348 false /* explicitlySelected */, timeout -> timeout < 14_000); 6349 } 6350 6351 @Test 6352 public void testAvoidBadWifi() throws Exception { 6353 final ContentResolver cr = mServiceContext.getContentResolver(); 6354 6355 // Pretend we're on a carrier that restricts switching away from bad wifi. 6356 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6357 6358 // File a request for cell to ensure it doesn't go down. 6359 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6360 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6361 .addTransportType(TRANSPORT_CELLULAR).build(); 6362 mCm.requestNetwork(cellRequest, cellNetworkCallback); 6363 6364 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 6365 mCm.registerDefaultNetworkCallback(defaultCallback); 6366 6367 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 6368 .addTransportType(TRANSPORT_WIFI) 6369 .addCapability(NET_CAPABILITY_VALIDATED) 6370 .build(); 6371 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 6372 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 6373 6374 // Prompt mode, so notifications can be tested 6375 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6376 mPolicyTracker.reevaluate(); 6377 6378 // Bring up validated cell. 6379 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6380 mCellAgent.connect(true); 6381 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6382 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6383 Network cellNetwork = mCellAgent.getNetwork(); 6384 6385 // Bring up validated wifi. 6386 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6387 mWiFiAgent.connect(true); 6388 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6389 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6390 Network wifiNetwork = mWiFiAgent.getNetwork(); 6391 6392 // Fail validation on wifi. 6393 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6394 mCm.reportNetworkConnectivity(wifiNetwork, false); 6395 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6396 validatedWifiCallback.expect(LOST, mWiFiAgent); 6397 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6398 6399 // Because avoid bad wifi is off, we don't switch to cellular. 6400 defaultCallback.assertNoCallback(); 6401 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6402 NET_CAPABILITY_VALIDATED)); 6403 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6404 NET_CAPABILITY_VALIDATED)); 6405 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6406 6407 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 6408 // that we switch back to cell. 6409 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6410 mPolicyTracker.reevaluate(); 6411 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6412 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6413 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6414 6415 // Switch back to a restrictive carrier. 6416 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6417 mPolicyTracker.reevaluate(); 6418 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6419 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6420 // A notification was already shown for this very network. 6421 expectNoNotification(mWiFiAgent); 6422 6423 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 6424 // In principle this is a little bit unrealistic because the switch to a less restrictive 6425 // carrier above should have remove the notification but this doesn't matter for the 6426 // purposes of this test. 6427 mCm.setAvoidUnvalidated(wifiNetwork); 6428 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6429 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6430 NET_CAPABILITY_VALIDATED)); 6431 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6432 NET_CAPABILITY_VALIDATED)); 6433 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6434 6435 // Disconnect and reconnect wifi to clear the one-time switch above. 6436 mWiFiAgent.disconnect(); 6437 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6438 mWiFiAgent.connect(true); 6439 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6440 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6441 wifiNetwork = mWiFiAgent.getNetwork(); 6442 6443 // Fail validation on wifi and expect the dialog to appear. 6444 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6445 mCm.reportNetworkConnectivity(wifiNetwork, false); 6446 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6447 validatedWifiCallback.expect(LOST, mWiFiAgent); 6448 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6449 6450 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 6451 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6452 mPolicyTracker.reevaluate(); 6453 6454 // We now switch to cell. 6455 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6456 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6457 NET_CAPABILITY_VALIDATED)); 6458 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6459 NET_CAPABILITY_VALIDATED)); 6460 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6461 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6462 6463 // Simulate the user turning the cellular fallback setting off and then on. 6464 // We switch to wifi and then to cell. 6465 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6466 mPolicyTracker.reevaluate(); 6467 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6468 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6469 // Notification is cleared again because CS doesn't particularly remember that it has 6470 // cleared it before, and if it hasn't cleared it before then it should do so now. 6471 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6472 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6473 mPolicyTracker.reevaluate(); 6474 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6475 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6476 6477 // If cell goes down, we switch to wifi. 6478 mCellAgent.disconnect(); 6479 defaultCallback.expect(LOST, mCellAgent); 6480 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6481 validatedWifiCallback.assertNoCallback(); 6482 // Notification is cleared yet again because the device switched to wifi. 6483 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6484 6485 mCm.unregisterNetworkCallback(cellNetworkCallback); 6486 mCm.unregisterNetworkCallback(validatedWifiCallback); 6487 mCm.unregisterNetworkCallback(defaultCallback); 6488 } 6489 6490 @Test 6491 public void testMeteredMultipathPreferenceSetting() throws Exception { 6492 final ContentResolver cr = mServiceContext.getContentResolver(); 6493 final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; 6494 6495 for (int config : asList(0, 3, 2)) { 6496 for (String setting: asList(null, "0", "2", "1")) { 6497 mPolicyTracker.mConfigMeteredMultipathPreference = config; 6498 Settings.Global.putString(cr, settingName, setting); 6499 mPolicyTracker.reevaluate(); 6500 waitForIdle(); 6501 6502 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 6503 String msg = String.format("config=%d, setting=%s", config, setting); 6504 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 6505 } 6506 } 6507 } 6508 6509 /** 6510 * Validate that a satisfied network request does not trigger onUnavailable() once the 6511 * time-out period expires. 6512 */ 6513 @Test 6514 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6515 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6516 NetworkCapabilities.TRANSPORT_WIFI).build(); 6517 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6518 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6519 6520 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6521 mWiFiAgent.connect(false); 6522 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6523 TEST_CALLBACK_TIMEOUT_MS); 6524 6525 // pass timeout and validate that UNAVAILABLE is not called 6526 networkCallback.assertNoCallback(); 6527 } 6528 6529 /** 6530 * Validate that a satisfied network request followed by a disconnected (lost) network does 6531 * not trigger onUnavailable() once the time-out period expires. 6532 */ 6533 @Test 6534 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6535 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6536 NetworkCapabilities.TRANSPORT_WIFI).build(); 6537 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6538 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6539 6540 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6541 mWiFiAgent.connect(false); 6542 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6543 TEST_CALLBACK_TIMEOUT_MS); 6544 mWiFiAgent.disconnect(); 6545 networkCallback.expect(LOST, mWiFiAgent); 6546 6547 // Validate that UNAVAILABLE is not called 6548 networkCallback.assertNoCallback(); 6549 } 6550 6551 /** 6552 * Validate that when a time-out is specified for a network request the onUnavailable() 6553 * callback is called when time-out expires. Then validate that if network request is 6554 * (somehow) satisfied - the callback isn't called later. 6555 */ 6556 @Test 6557 public void testTimedoutNetworkRequest() throws Exception { 6558 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6559 NetworkCapabilities.TRANSPORT_WIFI).build(); 6560 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6561 final int timeoutMs = 10; 6562 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6563 6564 // pass timeout and validate that UNAVAILABLE is called 6565 networkCallback.expect(UNAVAILABLE); 6566 6567 // create a network satisfying request - validate that request not triggered 6568 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6569 mWiFiAgent.connect(false); 6570 networkCallback.assertNoCallback(); 6571 } 6572 6573 /** 6574 * Validate that when a network request is unregistered (cancelled), no posterior event can 6575 * trigger the callback. 6576 */ 6577 @Test 6578 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 6579 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6580 NetworkCapabilities.TRANSPORT_WIFI).build(); 6581 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6582 final int timeoutMs = 10; 6583 6584 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6585 mCm.unregisterNetworkCallback(networkCallback); 6586 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 6587 // that this callback will not be called. 6588 networkCallback.assertNoCallback(); 6589 6590 // create a network satisfying request - validate that request not triggered 6591 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6592 mWiFiAgent.connect(false); 6593 networkCallback.assertNoCallback(); 6594 } 6595 6596 @Test 6597 public void testUnfulfillableNetworkRequest() throws Exception { 6598 runUnfulfillableNetworkRequest(false); 6599 } 6600 6601 @Test 6602 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 6603 runUnfulfillableNetworkRequest(true); 6604 } 6605 6606 /** 6607 * Validate the callback flow for a factory releasing a request as unfulfillable. 6608 */ 6609 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 6610 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6611 NetworkCapabilities.TRANSPORT_WIFI).build(); 6612 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6613 6614 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 6615 handlerThread.start(); 6616 NetworkCapabilities filter = new NetworkCapabilities() 6617 .addTransportType(TRANSPORT_WIFI) 6618 .addCapability(NET_CAPABILITY_INTERNET) 6619 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 6620 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 6621 mServiceContext, "testFactory", filter, mCsHandlerThread); 6622 testFactory.setScoreFilter(40); 6623 6624 // Register the factory and expect it to receive the default request. 6625 testFactory.register(); 6626 testFactory.expectRequestAdd(); 6627 6628 try { 6629 // Now file the test request and expect it. 6630 mCm.requestNetwork(nr, networkCallback); 6631 final NetworkRequest newRequest = testFactory.expectRequestAdd().request; 6632 6633 if (preUnregister) { 6634 mCm.unregisterNetworkCallback(networkCallback); 6635 6636 // The request has been released : the factory should see it removed 6637 // immediately. 6638 testFactory.expectRequestRemove(); 6639 6640 // Simulate the factory releasing the request as unfulfillable: no-op since 6641 // the callback has already been unregistered (but a test that no exceptions are 6642 // thrown). 6643 testFactory.triggerUnfulfillable(newRequest); 6644 } else { 6645 // Simulate the factory releasing the request as unfulfillable and expect 6646 // onUnavailable! 6647 testFactory.triggerUnfulfillable(newRequest); 6648 6649 networkCallback.expect(UNAVAILABLE); 6650 6651 // Declaring a request unfulfillable releases it automatically. 6652 testFactory.expectRequestRemove(); 6653 6654 // unregister network callback - a no-op (since already freed by the 6655 // on-unavailable), but should not fail or throw exceptions. 6656 mCm.unregisterNetworkCallback(networkCallback); 6657 6658 // The factory should not see any further removal, as this request has 6659 // already been removed. 6660 } 6661 } finally { 6662 testFactory.terminate(); 6663 handlerThread.quitSafely(); 6664 handlerThread.join(); 6665 } 6666 } 6667 6668 @Test 6669 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6670 @DisableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6671 public void testSelfCertifiedCapabilitiesDisabled() 6672 throws Exception { 6673 mDeps.enableCompatChangeCheck(); 6674 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6675 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6676 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6677 .build(); 6678 final TestNetworkCallback cb = new TestNetworkCallback(); 6679 mCm.requestNetwork(networkRequest, cb); 6680 mCm.unregisterNetworkCallback(cb); 6681 } 6682 6683 /** Set the networkSliceResourceId to 0 will result in NameNotFoundException be thrown. */ 6684 private void setupMockForNetworkCapabilitiesResources(int networkSliceResourceId) 6685 throws PackageManager.NameNotFoundException { 6686 if (networkSliceResourceId == 0) { 6687 doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getProperty( 6688 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6689 mContext.getPackageName()); 6690 } else { 6691 final PackageManager.Property property = new PackageManager.Property( 6692 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6693 networkSliceResourceId, 6694 true /* isResource */, 6695 mContext.getPackageName(), 6696 "dummyClass" 6697 ); 6698 doReturn(property).when(mPackageManager).getProperty( 6699 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6700 mContext.getPackageName()); 6701 doReturn(mContext.getResources()).when(mPackageManager).getResourcesForApplication( 6702 mContext.getPackageName()); 6703 } 6704 } 6705 6706 @Test 6707 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6708 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6709 public void requestNetwork_withoutPrioritizeBandwidthDeclaration_shouldThrowException() 6710 throws Exception { 6711 mDeps.enableCompatChangeCheck(); 6712 setupMockForNetworkCapabilitiesResources( 6713 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_latency); 6714 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6715 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6716 .build(); 6717 final TestNetworkCallback cb = new TestNetworkCallback(); 6718 final Exception e = assertThrows(SecurityException.class, 6719 () -> mCm.requestNetwork(networkRequest, cb)); 6720 assertThat(e.getMessage(), 6721 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH)); 6722 } 6723 6724 @Test 6725 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6726 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6727 public void requestNetwork_withoutPrioritizeLatencyDeclaration_shouldThrowException() 6728 throws Exception { 6729 mDeps.enableCompatChangeCheck(); 6730 setupMockForNetworkCapabilitiesResources( 6731 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_bandwidth); 6732 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6733 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6734 .build(); 6735 final TestNetworkCallback cb = new TestNetworkCallback(); 6736 final Exception e = assertThrows(SecurityException.class, 6737 () -> mCm.requestNetwork(networkRequest, cb)); 6738 assertThat(e.getMessage(), 6739 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY)); 6740 } 6741 6742 @Test 6743 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6744 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6745 public void requestNetwork_withoutNetworkSliceProperty_shouldThrowException() throws Exception { 6746 mDeps.enableCompatChangeCheck(); 6747 setupMockForNetworkCapabilitiesResources(0 /* networkSliceResourceId */); 6748 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6749 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6750 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6751 .build(); 6752 final TestNetworkCallback cb = new TestNetworkCallback(); 6753 final Exception e = assertThrows(SecurityException.class, 6754 () -> mCm.requestNetwork(networkRequest, cb)); 6755 assertThat(e.getMessage(), 6756 containsString(ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES)); 6757 } 6758 6759 @Test 6760 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6761 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6762 public void requestNetwork_withNetworkSliceDeclaration_shouldSucceed() throws Exception { 6763 mDeps.enableCompatChangeCheck(); 6764 setupMockForNetworkCapabilitiesResources( 6765 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6766 6767 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6768 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6769 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6770 .build(); 6771 final TestNetworkCallback cb = new TestNetworkCallback(); 6772 mCm.requestNetwork(networkRequest, cb); 6773 mCm.unregisterNetworkCallback(cb); 6774 } 6775 6776 @Test 6777 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6778 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6779 public void requestNetwork_withNetworkSliceDeclaration_shouldUseCache() throws Exception { 6780 mDeps.enableCompatChangeCheck(); 6781 setupMockForNetworkCapabilitiesResources( 6782 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6783 6784 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6785 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6786 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6787 .build(); 6788 final TestNetworkCallback cb = new TestNetworkCallback(); 6789 mCm.requestNetwork(networkRequest, cb); 6790 mCm.unregisterNetworkCallback(cb); 6791 6792 // Second call should use caches 6793 mCm.requestNetwork(networkRequest, cb); 6794 mCm.unregisterNetworkCallback(cb); 6795 6796 // PackageManager's API only called once because the second call is using cache. 6797 verify(mPackageManager, times(1)).getProperty( 6798 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6799 mContext.getPackageName()); 6800 verify(mPackageManager, times(1)).getResourcesForApplication( 6801 mContext.getPackageName()); 6802 } 6803 6804 /** 6805 * Validate the service throws if request with CBS but without carrier privilege. 6806 */ 6807 @Test 6808 public void testCBSRequestWithoutCarrierPrivilege() throws Exception { 6809 final NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6810 TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_CBS).build(); 6811 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6812 6813 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 6814 // Now file the test request and expect the service throws. 6815 assertThrows(SecurityException.class, () -> mCm.requestNetwork(nr, networkCallback)); 6816 } 6817 6818 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 6819 6820 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 6821 6822 private class CallbackValue { 6823 public CallbackType callbackType; 6824 public int error; 6825 6826 public CallbackValue(CallbackType type) { 6827 this.callbackType = type; 6828 this.error = PacketKeepalive.SUCCESS; 6829 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6830 } 6831 6832 public CallbackValue(CallbackType type, int error) { 6833 this.callbackType = type; 6834 this.error = error; 6835 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6836 } 6837 6838 @Override 6839 public boolean equals(Object o) { 6840 return o instanceof CallbackValue && 6841 this.callbackType == ((CallbackValue) o).callbackType && 6842 this.error == ((CallbackValue) o).error; 6843 } 6844 6845 @Override 6846 public String toString() { 6847 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 6848 } 6849 } 6850 6851 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6852 6853 @Override 6854 public void onStarted() { 6855 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6856 } 6857 6858 @Override 6859 public void onStopped() { 6860 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6861 } 6862 6863 @Override 6864 public void onError(int error) { 6865 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6866 } 6867 6868 private void expect(CallbackValue callbackValue) throws InterruptedException { 6869 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6870 } 6871 6872 public void expectStarted() throws Exception { 6873 expect(new CallbackValue(CallbackType.ON_STARTED)); 6874 } 6875 6876 public void expectStopped() throws Exception { 6877 expect(new CallbackValue(CallbackType.ON_STOPPED)); 6878 } 6879 6880 public void expectError(int error) throws Exception { 6881 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 6882 } 6883 } 6884 6885 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 6886 6887 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 6888 6889 private class CallbackValue { 6890 public CallbackType callbackType; 6891 public int error; 6892 6893 CallbackValue(CallbackType type) { 6894 this.callbackType = type; 6895 this.error = SocketKeepalive.SUCCESS; 6896 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6897 } 6898 6899 CallbackValue(CallbackType type, int error) { 6900 this.callbackType = type; 6901 this.error = error; 6902 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6903 } 6904 6905 @Override 6906 public boolean equals(Object o) { 6907 return o instanceof CallbackValue 6908 && this.callbackType == ((CallbackValue) o).callbackType 6909 && this.error == ((CallbackValue) o).error; 6910 } 6911 6912 @Override 6913 public String toString() { 6914 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 6915 error); 6916 } 6917 } 6918 6919 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6920 private final Executor mExecutor; 6921 6922 TestSocketKeepaliveCallback(@NonNull Executor executor) { 6923 mExecutor = executor; 6924 } 6925 6926 @Override 6927 public void onStarted() { 6928 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6929 } 6930 6931 @Override 6932 public void onStopped() { 6933 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6934 } 6935 6936 @Override 6937 public void onError(int error) { 6938 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6939 } 6940 6941 private void expect(CallbackValue callbackValue) throws InterruptedException { 6942 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6943 6944 } 6945 6946 public void expectStarted() throws InterruptedException { 6947 expect(new CallbackValue(CallbackType.ON_STARTED)); 6948 } 6949 6950 public void expectStopped() throws InterruptedException { 6951 expect(new CallbackValue(CallbackType.ON_STOPPED)); 6952 } 6953 6954 public void expectError(int error) throws InterruptedException { 6955 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 6956 } 6957 6958 public void assertNoCallback() { 6959 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 6960 CallbackValue cv = mCallbacks.peek(); 6961 assertNull("Unexpected callback: " + cv, cv); 6962 } 6963 } 6964 6965 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 6966 // Ensure the network is disconnected before anything else occurs 6967 if (mWiFiAgent != null) { 6968 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork())); 6969 } 6970 6971 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6972 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 6973 mWiFiAgent.connect(true); 6974 b.expectBroadcast(); 6975 verifyActiveNetwork(TRANSPORT_WIFI); 6976 mWiFiAgent.sendLinkProperties(lp); 6977 waitForIdle(); 6978 return mWiFiAgent.getNetwork(); 6979 } 6980 6981 @Test 6982 public void testPacketKeepalives() throws Exception { 6983 final LinkAddress v4Addr = new LinkAddress("192.0.2.129/24"); 6984 final InetAddress myIPv4 = v4Addr.getAddress(); 6985 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 6986 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 6987 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6988 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 6989 doReturn(getClatInterfaceConfigParcel(v4Addr)).when(mMockNetd) 6990 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 6991 final int validKaInterval = 15; 6992 final int invalidKaInterval = 9; 6993 6994 LinkProperties lp = new LinkProperties(); 6995 lp.setInterfaceName(MOBILE_IFNAME); 6996 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6997 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6998 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6999 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7000 7001 Network notMyNet = new Network(61234); 7002 Network myNet = connectKeepaliveNetwork(lp); 7003 7004 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 7005 PacketKeepalive ka; 7006 7007 // Attempt to start keepalives with invalid parameters and check for errors. 7008 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 7009 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 7010 7011 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 7012 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 7013 7014 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 7015 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7016 7017 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 7018 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7019 7020 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 7021 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 7022 7023 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 7024 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 7025 7026 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7027 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 7028 7029 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7030 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 7031 7032 // Check that a started keepalive can be stopped. 7033 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 7034 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7035 callback.expectStarted(); 7036 mWiFiAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 7037 ka.stop(); 7038 callback.expectStopped(); 7039 7040 // Check that deleting the IP address stops the keepalive. 7041 LinkProperties bogusLp = new LinkProperties(lp); 7042 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7043 callback.expectStarted(); 7044 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 7045 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 7046 mWiFiAgent.sendLinkProperties(bogusLp); 7047 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7048 mWiFiAgent.sendLinkProperties(lp); 7049 7050 // Check that a started keepalive is stopped correctly when the network disconnects. 7051 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7052 callback.expectStarted(); 7053 mWiFiAgent.disconnect(); 7054 mWiFiAgent.expectDisconnected(); 7055 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 7056 7057 // ... and that stopping it after that has no adverse effects. 7058 waitForIdle(); 7059 final Network myNetAlias = myNet; 7060 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 7061 ka.stop(); 7062 7063 // Reconnect. 7064 myNet = connectKeepaliveNetwork(lp); 7065 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 7066 7067 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 7068 mWiFiAgent.setExpectedKeepaliveSlot(1); 7069 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7070 callback.expectStarted(); 7071 7072 // The second one gets slot 2. 7073 mWiFiAgent.setExpectedKeepaliveSlot(2); 7074 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 7075 PacketKeepalive ka2 = mCm.startNattKeepalive( 7076 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 7077 callback2.expectStarted(); 7078 7079 // Now stop the first one and create a third. This also gets slot 1. 7080 ka.stop(); 7081 callback.expectStopped(); 7082 7083 mWiFiAgent.setExpectedKeepaliveSlot(1); 7084 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 7085 PacketKeepalive ka3 = mCm.startNattKeepalive( 7086 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 7087 callback3.expectStarted(); 7088 7089 ka2.stop(); 7090 callback2.expectStopped(); 7091 7092 ka3.stop(); 7093 callback3.expectStopped(); 7094 } 7095 7096 // Helper method to prepare the executor and run test 7097 private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) 7098 throws Exception { 7099 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 7100 final Executor executorInline = (Runnable r) -> r.run(); 7101 functor.accept(executorSingleThread); 7102 executorSingleThread.shutdown(); 7103 functor.accept(executorInline); 7104 } 7105 7106 @Test 7107 public void testNattSocketKeepalives() throws Exception { 7108 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 7109 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 7110 } 7111 7112 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 7113 // TODO: 1. Move this outside of ConnectivityServiceTest. 7114 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 7115 // 3. Mock ipsec service. 7116 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 7117 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 7118 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 7119 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7120 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 7121 7122 final int validKaInterval = 15; 7123 final int invalidKaInterval = 9; 7124 7125 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 7126 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 7127 final int srcPort = testSocket.getPort(); 7128 7129 LinkProperties lp = new LinkProperties(); 7130 lp.setInterfaceName("wlan12"); 7131 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7132 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7133 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7134 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7135 7136 Network notMyNet = new Network(61234); 7137 Network myNet = connectKeepaliveNetwork(lp); 7138 7139 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7140 7141 // Attempt to start keepalives with invalid parameters and check for errors. 7142 // Invalid network. 7143 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7144 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7145 ka.start(validKaInterval); 7146 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7147 } 7148 7149 // Invalid interval. 7150 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7151 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7152 ka.start(invalidKaInterval); 7153 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 7154 } 7155 7156 // Invalid destination. 7157 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7158 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 7159 ka.start(validKaInterval); 7160 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7161 } 7162 7163 // Invalid source; 7164 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7165 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 7166 ka.start(validKaInterval); 7167 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7168 } 7169 7170 // Basic check before testing started keepalive. 7171 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7172 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7173 ka.start(validKaInterval); 7174 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 7175 } 7176 7177 // Check that a started keepalive can be stopped. 7178 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7179 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7180 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7181 ka.start(validKaInterval); 7182 callback.expectStarted(); 7183 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7184 ka.stop(); 7185 callback.expectStopped(); 7186 7187 // Check that keepalive could be restarted. 7188 ka.start(validKaInterval); 7189 callback.expectStarted(); 7190 ka.stop(); 7191 callback.expectStopped(); 7192 7193 // Check that keepalive can be restarted without waiting for callback. 7194 ka.start(validKaInterval); 7195 callback.expectStarted(); 7196 ka.stop(); 7197 ka.start(validKaInterval); 7198 callback.expectStopped(); 7199 callback.expectStarted(); 7200 ka.stop(); 7201 callback.expectStopped(); 7202 } 7203 7204 // Check that deleting the IP address stops the keepalive. 7205 LinkProperties bogusLp = new LinkProperties(lp); 7206 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7207 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7208 ka.start(validKaInterval); 7209 callback.expectStarted(); 7210 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 7211 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 7212 mWiFiAgent.sendLinkProperties(bogusLp); 7213 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7214 mWiFiAgent.sendLinkProperties(lp); 7215 } 7216 7217 // Check that a started keepalive is stopped correctly when the network disconnects. 7218 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7219 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7220 ka.start(validKaInterval); 7221 callback.expectStarted(); 7222 mWiFiAgent.disconnect(); 7223 mWiFiAgent.expectDisconnected(); 7224 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7225 7226 // ... and that stopping it after that has no adverse effects. 7227 waitForIdle(); 7228 assertNull(mCm.getNetworkCapabilities(myNet)); 7229 ka.stop(); 7230 callback.assertNoCallback(); 7231 } 7232 7233 // Reconnect. 7234 myNet = connectKeepaliveNetwork(lp); 7235 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7236 7237 // Check that a stop followed by network disconnects does not result in crash. 7238 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7239 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7240 ka.start(validKaInterval); 7241 callback.expectStarted(); 7242 // Delay the response of keepalive events in networkAgent long enough to make sure 7243 // the follow-up network disconnection will be processed first. 7244 mWiFiAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); 7245 ka.stop(); 7246 // Call stop() twice shouldn't result in crash, b/182586681. 7247 ka.stop(); 7248 7249 // Make sure the stop has been processed. Wait for executor idle is needed to prevent 7250 // flaky since the actual stop call to the service is delegated to executor thread. 7251 waitForIdleSerialExecutor(executor, TIMEOUT_MS); 7252 waitForIdle(); 7253 7254 mWiFiAgent.disconnect(); 7255 mWiFiAgent.expectDisconnected(); 7256 callback.expectStopped(); 7257 callback.assertNoCallback(); 7258 } 7259 7260 // Reconnect. 7261 waitForIdle(); 7262 myNet = connectKeepaliveNetwork(lp); 7263 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7264 7265 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 7266 mWiFiAgent.setExpectedKeepaliveSlot(1); 7267 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7268 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7269 ka.start(validKaInterval); 7270 callback.expectStarted(); 7271 7272 // The second one gets slot 2. 7273 mWiFiAgent.setExpectedKeepaliveSlot(2); 7274 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 7275 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 7276 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 7277 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 7278 ka2.start(validKaInterval); 7279 callback2.expectStarted(); 7280 7281 ka.stop(); 7282 callback.expectStopped(); 7283 7284 ka2.stop(); 7285 callback2.expectStopped(); 7286 7287 testSocket.close(); 7288 testSocket2.close(); 7289 } 7290 } 7291 7292 // Check that there is no port leaked after all keepalives and sockets are closed. 7293 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7294 // assertFalse(isUdpPortInUse(srcPort)); 7295 // assertFalse(isUdpPortInUse(srcPort2)); 7296 7297 mWiFiAgent.disconnect(); 7298 mWiFiAgent.expectDisconnected(); 7299 mWiFiAgent = null; 7300 } 7301 7302 @Test 7303 public void testTcpSocketKeepalives() throws Exception { 7304 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 7305 } 7306 7307 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 7308 final int srcPortV4 = 12345; 7309 final int srcPortV6 = 23456; 7310 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 7311 final InetAddress myIPv6 = InetAddress.getByName("::1"); 7312 7313 final int validKaInterval = 15; 7314 7315 final LinkProperties lp = new LinkProperties(); 7316 lp.setInterfaceName("wlan12"); 7317 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7318 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7319 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7320 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 7321 7322 final Network notMyNet = new Network(61234); 7323 final Network myNet = connectKeepaliveNetwork(lp); 7324 7325 final Socket testSocketV4 = new Socket(); 7326 final Socket testSocketV6 = new Socket(); 7327 7328 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7329 7330 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 7331 // Invalid network. 7332 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7333 notMyNet, testSocketV4, executor, callback)) { 7334 ka.start(validKaInterval); 7335 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7336 } 7337 7338 // Invalid Socket (socket is not bound with IPv4 address). 7339 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7340 myNet, testSocketV4, executor, callback)) { 7341 ka.start(validKaInterval); 7342 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7343 } 7344 7345 // Invalid Socket (socket is not bound with IPv6 address). 7346 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7347 myNet, testSocketV6, executor, callback)) { 7348 ka.start(validKaInterval); 7349 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7350 } 7351 7352 // Bind the socket address 7353 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 7354 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 7355 7356 // Invalid Socket (socket is bound with IPv4 address). 7357 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7358 myNet, testSocketV4, executor, callback)) { 7359 ka.start(validKaInterval); 7360 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7361 } 7362 7363 // Invalid Socket (socket is bound with IPv6 address). 7364 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7365 myNet, testSocketV6, executor, callback)) { 7366 ka.start(validKaInterval); 7367 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7368 } 7369 7370 testSocketV4.close(); 7371 testSocketV6.close(); 7372 7373 mWiFiAgent.disconnect(); 7374 mWiFiAgent.expectDisconnected(); 7375 mWiFiAgent = null; 7376 } 7377 7378 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 7379 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 7380 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 7381 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7382 final int validKaInterval = 15; 7383 7384 // Prepare the target network. 7385 LinkProperties lp = new LinkProperties(); 7386 lp.setInterfaceName("wlan12"); 7387 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7388 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7389 Network myNet = connectKeepaliveNetwork(lp); 7390 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7391 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7392 7393 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7394 7395 // Prepare the target file descriptor, keep only one instance. 7396 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 7397 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 7398 final int srcPort = testSocket.getPort(); 7399 final ParcelFileDescriptor testPfd = 7400 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 7401 testSocket.close(); 7402 assertTrue(isUdpPortInUse(srcPort)); 7403 7404 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 7405 // block. 7406 try (SocketKeepalive ka = mCm.createNattKeepalive( 7407 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 7408 ka.start(validKaInterval); 7409 callback.expectStarted(); 7410 ka.stop(); 7411 callback.expectStopped(); 7412 } 7413 7414 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 7415 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 7416 // address. 7417 assertTrue(isUdpPortInUse(srcPort)); 7418 final InetSocketAddress sa = 7419 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 7420 assertEquals(anyIPv4, sa.getAddress()); 7421 7422 testPfd.close(); 7423 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7424 // assertFalse(isUdpPortInUse(srcPort)); 7425 7426 mWiFiAgent.disconnect(); 7427 mWiFiAgent.expectDisconnected(); 7428 mWiFiAgent = null; 7429 } 7430 7431 private static boolean isUdpPortInUse(int port) { 7432 try (DatagramSocket ignored = new DatagramSocket(port)) { 7433 return false; 7434 } catch (IOException alreadyInUse) { 7435 return true; 7436 } 7437 } 7438 7439 @Test 7440 public void testGetCaptivePortalServerUrl() throws Exception { 7441 String url = mCm.getCaptivePortalServerUrl(); 7442 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 7443 } 7444 7445 private static class TestNetworkPinner extends NetworkPinner { 7446 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 7447 synchronized(sLock) { 7448 if (sNetwork == null) { 7449 sLock.wait(timeoutMs); 7450 } 7451 return sNetwork != null; 7452 } 7453 } 7454 7455 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 7456 synchronized(sLock) { 7457 if (sNetwork != null) { 7458 sLock.wait(timeoutMs); 7459 } 7460 return sNetwork == null; 7461 } 7462 } 7463 } 7464 7465 private void assertPinnedToWifiWithCellDefault() { 7466 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7467 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7468 } 7469 7470 private void assertPinnedToWifiWithWifiDefault() { 7471 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7472 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 7473 } 7474 7475 private void assertNotPinnedToWifi() { 7476 assertNull(mCm.getBoundNetworkForProcess()); 7477 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7478 } 7479 7480 @Test 7481 public void testNetworkPinner() throws Exception { 7482 NetworkRequest wifiRequest = new NetworkRequest.Builder() 7483 .addTransportType(TRANSPORT_WIFI) 7484 .build(); 7485 assertNull(mCm.getBoundNetworkForProcess()); 7486 7487 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7488 assertNull(mCm.getBoundNetworkForProcess()); 7489 7490 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7491 mCellAgent.connect(true); 7492 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7493 mWiFiAgent.connect(false); 7494 7495 // When wi-fi connects, expect to be pinned. 7496 assertTrue(TestNetworkPinner.awaitPin(100)); 7497 assertPinnedToWifiWithCellDefault(); 7498 7499 // Disconnect and expect the pin to drop. 7500 mWiFiAgent.disconnect(); 7501 assertTrue(TestNetworkPinner.awaitUnpin(100)); 7502 assertNotPinnedToWifi(); 7503 7504 // Reconnecting does not cause the pin to come back. 7505 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7506 mWiFiAgent.connect(false); 7507 assertFalse(TestNetworkPinner.awaitPin(100)); 7508 assertNotPinnedToWifi(); 7509 7510 // Pinning while connected causes the pin to take effect immediately. 7511 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7512 assertTrue(TestNetworkPinner.awaitPin(100)); 7513 assertPinnedToWifiWithCellDefault(); 7514 7515 // Explicitly unpin and expect to use the default network again. 7516 TestNetworkPinner.unpin(); 7517 assertNotPinnedToWifi(); 7518 7519 // Disconnect cell and wifi. 7520 ExpectedBroadcast b = expectConnectivityAction(3); // cell down, wifi up, wifi down. 7521 mCellAgent.disconnect(); 7522 mWiFiAgent.disconnect(); 7523 b.expectBroadcast(); 7524 7525 // Pinning takes effect even if the pinned network is the default when the pin is set... 7526 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7527 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7528 mWiFiAgent.connect(false); 7529 assertTrue(TestNetworkPinner.awaitPin(100)); 7530 assertPinnedToWifiWithWifiDefault(); 7531 7532 // ... and is maintained even when that network is no longer the default. 7533 b = expectConnectivityAction(1); 7534 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7535 mCellAgent.connect(true); 7536 b.expectBroadcast(); 7537 assertPinnedToWifiWithCellDefault(); 7538 } 7539 7540 @Test 7541 public void testNetworkCallbackMaximum() throws Exception { 7542 final int MAX_REQUESTS = 100; 7543 final int CALLBACKS = 88; 7544 final int DIFF_INTENTS = 10; 7545 final int SAME_INTENTS = 10; 7546 final int SYSTEM_ONLY_MAX_REQUESTS = 250; 7547 // CALLBACKS + DIFF_INTENTS + 1 (same intent) 7548 // = MAX_REQUESTS - 1, since the capacity is MAX_REQUEST - 1. 7549 assertEquals(MAX_REQUESTS - 1, CALLBACKS + DIFF_INTENTS + 1); 7550 7551 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 7552 ArrayList<Object> registered = new ArrayList<>(); 7553 7554 for (int j = 0; j < CALLBACKS; j++) { 7555 final NetworkCallback cb = new NetworkCallback(); 7556 if (j < CALLBACKS / 2) { 7557 mCm.requestNetwork(networkRequest, cb); 7558 } else { 7559 mCm.registerNetworkCallback(networkRequest, cb); 7560 } 7561 registered.add(cb); 7562 } 7563 7564 // Since ConnectivityService will de-duplicate the request with the same intent, 7565 // register multiple times does not really increase multiple requests. 7566 final PendingIntent same_pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7567 new Intent("same"), FLAG_IMMUTABLE); 7568 for (int j = 0; j < SAME_INTENTS; j++) { 7569 mCm.registerNetworkCallback(networkRequest, same_pi); 7570 // Wait for the requests with the same intent to be de-duplicated. Because 7571 // ConnectivityService side incrementCountOrThrow in binder, decrementCount in handler 7572 // thread, waitForIdle is needed to ensure decrementCount being invoked for same intent 7573 // requests before doing further tests. 7574 waitForIdle(); 7575 } 7576 for (int j = 0; j < SAME_INTENTS; j++) { 7577 mCm.requestNetwork(networkRequest, same_pi); 7578 // Wait for the requests with the same intent to be de-duplicated. 7579 // Refer to the reason above. 7580 waitForIdle(); 7581 } 7582 registered.add(same_pi); 7583 7584 for (int j = 0; j < DIFF_INTENTS; j++) { 7585 if (j < DIFF_INTENTS / 2) { 7586 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7587 new Intent("a" + j), FLAG_IMMUTABLE); 7588 mCm.requestNetwork(networkRequest, pi); 7589 registered.add(pi); 7590 } else { 7591 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7592 new Intent("b" + j), FLAG_IMMUTABLE); 7593 mCm.registerNetworkCallback(networkRequest, pi); 7594 registered.add(pi); 7595 } 7596 } 7597 7598 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 7599 assertThrows(TooManyRequestsException.class, () -> 7600 mCm.requestNetwork(networkRequest, new NetworkCallback()) 7601 ); 7602 assertThrows(TooManyRequestsException.class, () -> 7603 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 7604 ); 7605 assertThrows(TooManyRequestsException.class, () -> 7606 mCm.requestNetwork(networkRequest, 7607 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7608 new Intent("c"), FLAG_IMMUTABLE)) 7609 ); 7610 assertThrows(TooManyRequestsException.class, () -> 7611 mCm.registerNetworkCallback(networkRequest, 7612 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7613 new Intent("d"), FLAG_IMMUTABLE)) 7614 ); 7615 7616 // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. 7617 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 7618 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7619 ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); 7620 for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { 7621 NetworkCallback cb = new NetworkCallback(); 7622 if (i % 2 == 0) { 7623 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); 7624 } else { 7625 mCm.registerNetworkCallback(networkRequest, cb); 7626 } 7627 systemRegistered.add(cb); 7628 } 7629 waitForIdle(); 7630 7631 assertThrows(TooManyRequestsException.class, () -> 7632 mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), 7633 handler)); 7634 assertThrows(TooManyRequestsException.class, () -> 7635 mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); 7636 7637 for (NetworkCallback callback : systemRegistered) { 7638 mCm.unregisterNetworkCallback(callback); 7639 } 7640 waitForIdle(); // Wait for requests to be unregistered before giving up the permission. 7641 }); 7642 7643 for (Object o : registered) { 7644 if (o instanceof NetworkCallback) { 7645 mCm.unregisterNetworkCallback((NetworkCallback) o); 7646 } 7647 if (o instanceof PendingIntent) { 7648 mCm.unregisterNetworkCallback((PendingIntent) o); 7649 } 7650 } 7651 waitForIdle(); 7652 7653 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 7654 for (int i = 0; i < MAX_REQUESTS; i++) { 7655 NetworkCallback networkCallback = new NetworkCallback(); 7656 mCm.requestNetwork(networkRequest, networkCallback); 7657 mCm.unregisterNetworkCallback(networkCallback); 7658 // While requestNetwork increases the count synchronously, unregister decreases it 7659 // asynchronously on a handler, so unregistering doesn't immediately free up 7660 // a slot : calling unregister-register when max requests are registered throws. 7661 // Potential fix : ConnectivityService catches TooManyRequestsException once when 7662 // creating NetworkRequestInfo and waits for handler thread (see 7663 // https://r.android.com/2707373 for impl). However, this complexity is not equal to 7664 // the issue ; the purpose of having "max requests" is only to help apps detect leaks. 7665 // Apps relying on exact enforcement or rapid request registration should reconsider. 7666 // 7667 // In this test, test thread registering all before handler thread decrements can cause 7668 // flakes. A single waitForIdle at (e.g.) MAX_REQUESTS / 2 processes decrements up to 7669 // that point, fixing the flake. 7670 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7671 } 7672 waitForIdle(); 7673 7674 for (int i = 0; i < MAX_REQUESTS; i++) { 7675 NetworkCallback networkCallback = new NetworkCallback(); 7676 mCm.registerNetworkCallback(networkRequest, networkCallback); 7677 mCm.unregisterNetworkCallback(networkCallback); 7678 // See comment above for the reasons for this wait. 7679 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7680 } 7681 waitForIdle(); 7682 7683 for (int i = 0; i < MAX_REQUESTS; i++) { 7684 NetworkCallback networkCallback = new NetworkCallback(); 7685 mCm.registerDefaultNetworkCallback(networkCallback); 7686 mCm.unregisterNetworkCallback(networkCallback); 7687 // See comment above for the reasons for this wait. 7688 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7689 } 7690 waitForIdle(); 7691 7692 for (int i = 0; i < MAX_REQUESTS; i++) { 7693 NetworkCallback networkCallback = new NetworkCallback(); 7694 mCm.registerDefaultNetworkCallback(networkCallback); 7695 mCm.unregisterNetworkCallback(networkCallback); 7696 // See comment above for the reasons for this wait. 7697 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7698 } 7699 waitForIdle(); 7700 7701 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7702 for (int i = 0; i < MAX_REQUESTS; i++) { 7703 NetworkCallback networkCallback = new NetworkCallback(); 7704 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, 7705 new Handler(ConnectivityThread.getInstanceLooper())); 7706 mCm.unregisterNetworkCallback(networkCallback); 7707 // See comment above for the reasons for this wait. 7708 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7709 } 7710 }); 7711 waitForIdle(); 7712 7713 for (int i = 0; i < MAX_REQUESTS; i++) { 7714 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7715 mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); 7716 mCm.requestNetwork(networkRequest, pendingIntent); 7717 mCm.unregisterNetworkCallback(pendingIntent); 7718 // See comment above for the reasons for this wait. 7719 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7720 } 7721 waitForIdle(); 7722 7723 for (int i = 0; i < MAX_REQUESTS; i++) { 7724 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7725 mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); 7726 mCm.registerNetworkCallback(networkRequest, pendingIntent); 7727 mCm.unregisterNetworkCallback(pendingIntent); 7728 // See comment above for the reasons for this wait. 7729 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7730 } 7731 } 7732 7733 @Test 7734 public void testNetworkInfoOfTypeNone() throws Exception { 7735 ExpectedBroadcast b = expectConnectivityAction(1); 7736 7737 verifyNoNetwork(); 7738 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 7739 assertNull(mCm.getActiveNetworkInfo()); 7740 7741 Network[] allNetworks = mCm.getAllNetworks(); 7742 assertLength(1, allNetworks); 7743 Network network = allNetworks[0]; 7744 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 7745 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 7746 7747 final NetworkRequest request = 7748 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 7749 final TestNetworkCallback callback = new TestNetworkCallback(); 7750 mCm.registerNetworkCallback(request, callback); 7751 7752 // Bring up wifi aware network. 7753 wifiAware.connect(false, false, false /* privateDnsProbeSent */); 7754 callback.expectAvailableCallbacksUnvalidated(wifiAware); 7755 7756 assertNull(mCm.getActiveNetworkInfo()); 7757 assertNull(mCm.getActiveNetwork()); 7758 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 7759 // of this test. Fix it and uncomment the assert below. 7760 //assertEmpty(mCm.getAllNetworkInfo()); 7761 7762 // Disconnect wifi aware network. 7763 wifiAware.disconnect(); 7764 callback.expect(LOST, TIMEOUT_MS); 7765 mCm.unregisterNetworkCallback(callback); 7766 7767 verifyNoNetwork(); 7768 b.expectNoBroadcast(10); 7769 } 7770 7771 @Test 7772 public void testDeprecatedAndUnsupportedOperations() throws Exception { 7773 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 7774 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 7775 assertNull(mCm.getNetworkForType(TYPE_NONE)); 7776 assertNull(mCm.getLinkProperties(TYPE_NONE)); 7777 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 7778 7779 assertThrows(IllegalArgumentException.class, 7780 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 7781 7782 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 7783 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 7784 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 7785 // TODO: let test context have configuration application target sdk version 7786 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 7787 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 7788 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 7789 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 7790 } 7791 7792 @Test 7793 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 7794 final NetworkRequest networkRequest = new NetworkRequest.Builder() 7795 .addTransportType(TRANSPORT_WIFI).build(); 7796 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 7797 mCm.registerNetworkCallback(networkRequest, networkCallback); 7798 7799 LinkProperties lp = new LinkProperties(); 7800 lp.setInterfaceName(WIFI_IFNAME); 7801 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 7802 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 7803 InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); 7804 lp.addLinkAddress(myIpv4Address); 7805 lp.addRoute(myIpv4DefaultRoute); 7806 7807 // Verify direct routes are added when network agent is first registered in 7808 // ConnectivityService. 7809 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 7810 networkAgent.connect(true); 7811 networkCallback.expect(AVAILABLE, networkAgent); 7812 networkCallback.expect(NETWORK_CAPS_UPDATED, networkAgent); 7813 CallbackEntry.LinkPropertiesChanged cbi = 7814 networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7815 networkCallback.expect(BLOCKED_STATUS, networkAgent); 7816 networkCallback.expectCaps(networkAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 7817 networkCallback.assertNoCallback(); 7818 checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address), 7819 asList(myIpv4DefaultRoute)); 7820 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 7821 asList(myIpv4Address), asList(myIpv4DefaultRoute)); 7822 7823 // Verify direct routes are added during subsequent link properties updates. 7824 LinkProperties newLp = new LinkProperties(lp); 7825 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 7826 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 7827 newLp.addLinkAddress(myIpv6Address1); 7828 newLp.addLinkAddress(myIpv6Address2); 7829 networkAgent.sendLinkProperties(newLp); 7830 cbi = networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7831 networkCallback.assertNoCallback(); 7832 checkDirectlyConnectedRoutes(cbi.getLp(), 7833 asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 7834 asList(myIpv4DefaultRoute)); 7835 mCm.unregisterNetworkCallback(networkCallback); 7836 } 7837 7838 private void expectNotifyNetworkStatus(List<Network> allNetworks, List<Network> defaultNetworks, 7839 String defaultIface, Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) 7840 throws Exception { 7841 ArgumentCaptor<List<Network>> defaultNetworksCaptor = ArgumentCaptor.forClass(List.class); 7842 ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = 7843 ArgumentCaptor.forClass(List.class); 7844 ArgumentCaptor<List<NetworkStateSnapshot>> snapshotsCaptor = 7845 ArgumentCaptor.forClass(List.class); 7846 7847 verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(defaultNetworksCaptor.capture(), 7848 snapshotsCaptor.capture(), eq(defaultIface), vpnInfosCaptor.capture()); 7849 7850 assertSameElements(defaultNetworks, defaultNetworksCaptor.getValue()); 7851 7852 List<Network> snapshotNetworks = new ArrayList<Network>(); 7853 for (NetworkStateSnapshot ns : snapshotsCaptor.getValue()) { 7854 snapshotNetworks.add(ns.getNetwork()); 7855 } 7856 assertSameElements(allNetworks, snapshotNetworks); 7857 7858 if (defaultIface != null) { 7859 assertNotNull( 7860 "Did not find interface " + defaultIface + " in call to notifyNetworkStatus", 7861 CollectionUtils.findFirst(snapshotsCaptor.getValue(), (ns) -> { 7862 final LinkProperties lp = ns.getLinkProperties(); 7863 if (lp != null && TextUtils.equals(defaultIface, lp.getInterfaceName())) { 7864 return true; 7865 } 7866 return false; 7867 })); 7868 } 7869 7870 List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue(); 7871 if (vpnUid != null) { 7872 assertEquals("Should have exactly one VPN:", 1, infos.size()); 7873 UnderlyingNetworkInfo info = infos.get(0); 7874 assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); 7875 assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); 7876 assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces()); 7877 } else { 7878 assertEquals(0, infos.size()); 7879 return; 7880 } 7881 } 7882 7883 private void expectNotifyNetworkStatus( 7884 List<Network> allNetworks, List<Network> defaultNetworks, String defaultIface) 7885 throws Exception { 7886 expectNotifyNetworkStatus(allNetworks, defaultNetworks, defaultIface, null, null, 7887 List.of()); 7888 } 7889 7890 private List<Network> onlyCell() { 7891 return List.of(mCellAgent.getNetwork()); 7892 } 7893 7894 private List<Network> onlyWifi() { 7895 return List.of(mWiFiAgent.getNetwork()); 7896 } 7897 7898 private List<Network> cellAndWifi() { 7899 return List.of(mCellAgent.getNetwork(), mWiFiAgent.getNetwork()); 7900 } 7901 7902 @Test 7903 public void testStatsIfacesChanged() throws Exception { 7904 LinkProperties cellLp = new LinkProperties(); 7905 cellLp.setInterfaceName(MOBILE_IFNAME); 7906 LinkProperties wifiLp = new LinkProperties(); 7907 wifiLp.setInterfaceName(WIFI_IFNAME); 7908 7909 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7910 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7911 7912 // Simple connection with initial LP should have updated ifaces. 7913 mCellAgent.connect(false); 7914 waitForIdle(); 7915 List<Network> allNetworks = mService.shouldCreateNetworksImmediately() 7916 ? cellAndWifi() : onlyCell(); 7917 expectNotifyNetworkStatus(allNetworks, onlyCell(), MOBILE_IFNAME); 7918 reset(mStatsManager); 7919 7920 // Verify change fields other than interfaces does not trigger a notification to NSS. 7921 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 7922 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 7923 MOBILE_IFNAME)); 7924 cellLp.setDnsServers(List.of(InetAddress.getAllByName("8.8.8.8"))); 7925 mCellAgent.sendLinkProperties(cellLp); 7926 verifyNoMoreInteractions(mStatsManager); 7927 reset(mStatsManager); 7928 7929 // Default network switch should update ifaces. 7930 mWiFiAgent.connect(false); 7931 mWiFiAgent.sendLinkProperties(wifiLp); 7932 waitForIdle(); 7933 assertEquals(wifiLp, mService.getActiveLinkProperties()); 7934 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7935 reset(mStatsManager); 7936 7937 // Disconnecting a network updates ifaces again. The soon-to-be disconnected interface is 7938 // still in the list to ensure that stats are counted on that interface. 7939 // TODO: this means that if anything else uses that interface for any other reason before 7940 // notifyNetworkStatus is called again, traffic on that interface will be accounted to the 7941 // disconnected network. This is likely a bug in ConnectivityService; it should probably 7942 // call notifyNetworkStatus again without the disconnected network. 7943 mCellAgent.disconnect(); 7944 waitForIdle(); 7945 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7946 verifyNoMoreInteractions(mStatsManager); 7947 reset(mStatsManager); 7948 7949 // Connecting a network updates ifaces even if the network doesn't become default. 7950 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7951 mCellAgent.connect(false); 7952 waitForIdle(); 7953 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7954 reset(mStatsManager); 7955 7956 // Disconnect should update ifaces. 7957 mWiFiAgent.disconnect(); 7958 waitForIdle(); 7959 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7960 reset(mStatsManager); 7961 7962 // Metered change should update ifaces 7963 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7964 waitForIdle(); 7965 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7966 reset(mStatsManager); 7967 7968 mCellAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7969 waitForIdle(); 7970 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7971 reset(mStatsManager); 7972 7973 // Temp metered change shouldn't update ifaces 7974 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 7975 waitForIdle(); 7976 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 7977 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 7978 reset(mStatsManager); 7979 7980 // Congested change shouldn't update ifaces 7981 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 7982 waitForIdle(); 7983 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 7984 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 7985 reset(mStatsManager); 7986 7987 // Roaming change should update ifaces 7988 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 7989 waitForIdle(); 7990 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7991 reset(mStatsManager); 7992 7993 // Test VPNs. 7994 final LinkProperties lp = new LinkProperties(); 7995 lp.setInterfaceName(VPN_IFNAME); 7996 7997 mMockVpn.establishForMyUid(lp); 7998 assertUidRangesUpdatedForMyUid(true); 7999 8000 final List<Network> cellAndVpn = List.of(mCellAgent.getNetwork(), mMockVpn.getNetwork()); 8001 8002 // A VPN with default (null) underlying networks sets the underlying network's interfaces... 8003 expectNotifyNetworkStatus(cellAndVpn, cellAndVpn, MOBILE_IFNAME, Process.myUid(), 8004 VPN_IFNAME, List.of(MOBILE_IFNAME)); 8005 8006 // ...and updates them as the default network switches. 8007 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8008 mWiFiAgent.connect(false); 8009 mWiFiAgent.sendLinkProperties(wifiLp); 8010 final Network[] onlyNull = new Network[]{null}; 8011 final List<Network> wifiAndVpn = List.of(mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 8012 final List<Network> cellWifiAndVpn = List.of(mCellAgent.getNetwork(), 8013 mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 8014 final Network[] cellNullAndWifi = 8015 new Network[] { mCellAgent.getNetwork(), null, mWiFiAgent.getNetwork() }; 8016 8017 waitForIdle(); 8018 assertEquals(wifiLp, mService.getActiveLinkProperties()); 8019 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), 8020 VPN_IFNAME, List.of(WIFI_IFNAME)); 8021 reset(mStatsManager); 8022 8023 // A VPN that sets its underlying networks passes the underlying interfaces, and influences 8024 // the default interface sent to NetworkStatsService by virtue of applying to the system 8025 // server UID (or, in this test, to the test's UID). This is the reason for sending 8026 // MOBILE_IFNAME even though the default network is wifi. 8027 // TODO: fix this to pass in the actual default network interface. Whether or not the VPN 8028 // applies to the system server UID should not have any bearing on network stats. 8029 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 8030 waitForIdle(); 8031 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8032 VPN_IFNAME, List.of(MOBILE_IFNAME)); 8033 reset(mStatsManager); 8034 8035 mMockVpn.setUnderlyingNetworks(cellAndWifi().toArray(new Network[0])); 8036 waitForIdle(); 8037 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8038 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8039 reset(mStatsManager); 8040 8041 // Null underlying networks are ignored. 8042 mMockVpn.setUnderlyingNetworks(cellNullAndWifi); 8043 waitForIdle(); 8044 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8045 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8046 reset(mStatsManager); 8047 8048 // If an underlying network disconnects, that interface should no longer be underlying. 8049 // This doesn't actually work because disconnectAndDestroyNetwork only notifies 8050 // NetworkStatsService before the underlying network is actually removed. So the underlying 8051 // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This 8052 // could result in incorrect data usage measurements if the interface used by the 8053 // disconnected network is reused by a system component that does not register an agent for 8054 // it (e.g., tethering). 8055 mCellAgent.disconnect(); 8056 waitForIdle(); 8057 assertNull(mService.getLinkProperties(mCellAgent.getNetwork())); 8058 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8059 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8060 8061 // Confirm that we never tell NetworkStatsService that cell is no longer the underlying 8062 // network for the VPN... 8063 verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), 8064 any(List.class), any() /* anyString() doesn't match null */, 8065 argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 8066 && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); 8067 verifyNoMoreInteractions(mStatsManager); 8068 reset(mStatsManager); 8069 8070 // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be 8071 // called again, it does. For example, connect Ethernet, but with a low score, such that it 8072 // does not become the default network. 8073 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 8074 mEthernetAgent.setScore( 8075 new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); 8076 mEthernetAgent.connect(false); 8077 waitForIdle(); 8078 verify(mStatsManager).notifyNetworkStatus(any(List.class), 8079 any(List.class), any() /* anyString() doesn't match null */, 8080 argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 8081 && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); 8082 mEthernetAgent.disconnect(); 8083 waitForIdle(); 8084 reset(mStatsManager); 8085 8086 // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo 8087 // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes 8088 // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which 8089 // is probably a performance improvement (though it's very unlikely that a VPN would declare 8090 // no underlying networks). 8091 // Also, for the same reason as above, the active interface passed in is null. 8092 mMockVpn.setUnderlyingNetworks(new Network[0]); 8093 waitForIdle(); 8094 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8095 reset(mStatsManager); 8096 8097 // Specifying only a null underlying network is the same as no networks. 8098 mMockVpn.setUnderlyingNetworks(onlyNull); 8099 waitForIdle(); 8100 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8101 reset(mStatsManager); 8102 8103 // Specifying networks that are all disconnected is the same as specifying no networks. 8104 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 8105 waitForIdle(); 8106 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8107 reset(mStatsManager); 8108 8109 // Passing in null again means follow the default network again. 8110 mMockVpn.setUnderlyingNetworks(null); 8111 waitForIdle(); 8112 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 8113 List.of(WIFI_IFNAME)); 8114 reset(mStatsManager); 8115 } 8116 8117 @Test 8118 public void testAdminUidsRedacted() throws Exception { 8119 final int[] adminUids = new int[] {Process.myUid() + 1}; 8120 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 8121 ncTemplate.setAdministratorUids(adminUids); 8122 mCellAgent = 8123 new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), ncTemplate); 8124 mCellAgent.connect(false /* validated */); 8125 8126 // Verify case where caller has permission 8127 mServiceContext.setPermission( 8128 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 8129 TestNetworkCallback callback = new TestNetworkCallback(); 8130 mCm.registerDefaultNetworkCallback(callback); 8131 callback.expect(AVAILABLE, mCellAgent); 8132 callback.expectCaps(mCellAgent, c -> Arrays.equals(adminUids, c.getAdministratorUids())); 8133 mCm.unregisterNetworkCallback(callback); 8134 8135 // Verify case where caller does NOT have permission 8136 mServiceContext.setPermission( 8137 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 8138 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 8139 callback = new TestNetworkCallback(); 8140 mCm.registerDefaultNetworkCallback(callback); 8141 callback.expect(AVAILABLE, mCellAgent); 8142 callback.expectCaps(mCellAgent, c -> c.getAdministratorUids().length == 0); 8143 } 8144 8145 @Test 8146 public void testNonVpnUnderlyingNetworks() throws Exception { 8147 // Ensure wifi and cellular are not torn down. 8148 for (int transport : new int[]{TRANSPORT_CELLULAR, TRANSPORT_WIFI}) { 8149 final NetworkRequest request = new NetworkRequest.Builder() 8150 .addTransportType(transport) 8151 .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8152 .build(); 8153 mCm.requestNetwork(request, new NetworkCallback()); 8154 } 8155 8156 // Connect a VCN-managed wifi network. 8157 final LinkProperties wifiLp = new LinkProperties(); 8158 wifiLp.setInterfaceName(WIFI_IFNAME); 8159 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 8160 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 8161 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8162 mWiFiAgent.connect(true /* validated */); 8163 8164 final List<Network> none = List.of(); 8165 expectNotifyNetworkStatus(onlyWifi(), none, null); // Wifi is not the default network 8166 8167 // Create a virtual network based on the wifi network. 8168 final int ownerUid = 10042; 8169 NetworkCapabilities nc = new NetworkCapabilities.Builder() 8170 .setOwnerUid(ownerUid) 8171 .setAdministratorUids(new int[]{ownerUid}) 8172 .build(); 8173 final String vcnIface = "ipsec42"; 8174 final LinkProperties lp = new LinkProperties(); 8175 lp.setInterfaceName(vcnIface); 8176 final TestNetworkAgentWrapper vcn = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 8177 vcn.setUnderlyingNetworks(List.of(mWiFiAgent.getNetwork())); 8178 vcn.connect(false /* validated */); 8179 8180 final TestNetworkCallback callback = new TestNetworkCallback(); 8181 mCm.registerDefaultNetworkCallback(callback); 8182 callback.expectAvailableCallbacksUnvalidated(vcn); 8183 8184 // The underlying wifi network's capabilities are not propagated to the virtual network, 8185 // but NetworkStatsService is informed of the underlying interface. 8186 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8187 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8188 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8189 final List<Network> onlyVcn = List.of(vcn.getNetwork()); 8190 final List<Network> vcnAndWifi = List.of(vcn.getNetwork(), mWiFiAgent.getNetwork()); 8191 expectNotifyNetworkStatus(vcnAndWifi, onlyVcn, vcnIface, ownerUid, vcnIface, 8192 List.of(WIFI_IFNAME)); 8193 8194 // Add NOT_METERED to the underlying network, check that it is not propagated. 8195 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8196 callback.assertNoCallback(); 8197 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8198 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8199 8200 // Switch underlying networks. 8201 final LinkProperties cellLp = new LinkProperties(); 8202 cellLp.setInterfaceName(MOBILE_IFNAME); 8203 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8204 mCellAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 8205 mCellAgent.addCapability(NET_CAPABILITY_NOT_ROAMING); 8206 mCellAgent.connect(false /* validated */); 8207 vcn.setUnderlyingNetworks(List.of(mCellAgent.getNetwork())); 8208 8209 // The underlying capability changes do not propagate to the virtual network, but 8210 // NetworkStatsService is informed of the new underlying interface. 8211 callback.assertNoCallback(); 8212 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8213 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8214 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 8215 final List<Network> vcnWifiAndCell = List.of(vcn.getNetwork(), 8216 mWiFiAgent.getNetwork(), mCellAgent.getNetwork()); 8217 expectNotifyNetworkStatus(vcnWifiAndCell, onlyVcn, vcnIface, ownerUid, vcnIface, 8218 List.of(MOBILE_IFNAME)); 8219 } 8220 8221 @Test 8222 public void testBasicDnsConfigurationPushed() throws Exception { 8223 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8224 8225 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8226 final int netId = mCellAgent.getNetwork().netId; 8227 waitForIdle(); 8228 if (mService.shouldCreateNetworksImmediately()) { 8229 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8230 } else { 8231 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8232 } 8233 8234 final LinkProperties cellLp = new LinkProperties(); 8235 cellLp.setInterfaceName(MOBILE_IFNAME); 8236 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8237 // "is-reachable" testing in order to not program netd with unreachable 8238 // nameservers that it might try repeated to validate. 8239 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8240 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8241 MOBILE_IFNAME)); 8242 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8243 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8244 MOBILE_IFNAME)); 8245 mCellAgent.sendLinkProperties(cellLp); 8246 mCellAgent.connect(false); 8247 waitForIdle(); 8248 if (!mService.shouldCreateNetworksImmediately()) { 8249 // CS tells dnsresolver about the empty DNS config for this network. 8250 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8251 } 8252 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 8253 8254 verifyNoMoreInteractions(mMockDnsResolver); 8255 reset(mMockDnsResolver); 8256 8257 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8258 mCellAgent.sendLinkProperties(cellLp); 8259 waitForIdle(); 8260 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8261 mResolverParamsParcelCaptor.capture()); 8262 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8263 assertEquals(1, resolvrParams.servers.length); 8264 assertTrue(CollectionUtils.contains(resolvrParams.servers, "2001:db8::1")); 8265 // Opportunistic mode. 8266 assertTrue(CollectionUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 8267 reset(mMockDnsResolver); 8268 8269 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8270 mCellAgent.sendLinkProperties(cellLp); 8271 waitForIdle(); 8272 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8273 mResolverParamsParcelCaptor.capture()); 8274 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8275 assertEquals(2, resolvrParams.servers.length); 8276 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8277 asList("2001:db8::1", "192.0.2.1"))); 8278 // Opportunistic mode. 8279 assertEquals(2, resolvrParams.tlsServers.length); 8280 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8281 asList("2001:db8::1", "192.0.2.1"))); 8282 reset(mMockDnsResolver); 8283 8284 final String TLS_SPECIFIER = "tls.example.com"; 8285 final String TLS_SERVER6 = "2001:db8:53::53"; 8286 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 8287 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 8288 mCellAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 8289 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 8290 8291 waitForIdle(); 8292 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8293 mResolverParamsParcelCaptor.capture()); 8294 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8295 assertEquals(2, resolvrParams.servers.length); 8296 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8297 asList("2001:db8::1", "192.0.2.1"))); 8298 reset(mMockDnsResolver); 8299 } 8300 8301 @Test 8302 public void testDnsConfigurationTransTypesPushed() throws Exception { 8303 final NetworkRequest request = new NetworkRequest.Builder() 8304 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8305 .build(); 8306 final TestNetworkCallback callback = new TestNetworkCallback(); 8307 mCm.registerNetworkCallback(request, callback); 8308 8309 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8310 mWiFiAgent.connect(false); 8311 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8312 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(mWiFiAgent.getNetwork().netId)); 8313 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 8314 mResolverParamsParcelCaptor.capture()); 8315 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 8316 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 8317 reset(mMockDnsResolver); 8318 } 8319 8320 @Test 8321 public void testPrivateDnsNotification() throws Exception { 8322 NetworkRequest request = new NetworkRequest.Builder() 8323 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8324 .build(); 8325 TestNetworkCallback callback = new TestNetworkCallback(); 8326 mCm.registerNetworkCallback(request, callback); 8327 // Bring up wifi. 8328 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8329 mWiFiAgent.connect(false); 8330 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8331 // Private DNS resolution failed, checking if the notification will be shown or not. 8332 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8333 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8334 waitForIdle(); 8335 // If network validation failed, NetworkMonitor will re-evaluate the network. 8336 // ConnectivityService should filter the redundant notification. This part is trying to 8337 // simulate that situation and check if ConnectivityService could filter that case. 8338 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8339 waitForIdle(); 8340 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), 8341 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8342 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 8343 // shown. 8344 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 8345 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8346 waitForIdle(); 8347 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), 8348 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); 8349 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 8350 // shown again. 8351 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8352 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8353 waitForIdle(); 8354 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), 8355 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8356 } 8357 8358 @Test 8359 public void testPrivateDnsSettingsChange() throws Exception { 8360 // The default on Android is opportunistic mode ("Automatic"). 8361 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8362 8363 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8364 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8365 .addTransportType(TRANSPORT_CELLULAR).build(); 8366 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8367 8368 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8369 final int netId = mCellAgent.getNetwork().netId; 8370 waitForIdle(); 8371 if (mService.shouldCreateNetworksImmediately()) { 8372 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8373 } else { 8374 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8375 } 8376 8377 final LinkProperties cellLp = new LinkProperties(); 8378 cellLp.setInterfaceName(MOBILE_IFNAME); 8379 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8380 // "is-reachable" testing in order to not program netd with unreachable 8381 // nameservers that it might try repeated to validate. 8382 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8383 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8384 MOBILE_IFNAME)); 8385 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8386 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8387 MOBILE_IFNAME)); 8388 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8389 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8390 8391 mCellAgent.sendLinkProperties(cellLp); 8392 mCellAgent.connect(false); 8393 waitForIdle(); 8394 if (!mService.shouldCreateNetworksImmediately()) { 8395 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8396 } 8397 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8398 mResolverParamsParcelCaptor.capture()); 8399 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8400 assertEquals(2, resolvrParams.tlsServers.length); 8401 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8402 asList("2001:db8::1", "192.0.2.1"))); 8403 // Opportunistic mode. 8404 assertEquals(2, resolvrParams.tlsServers.length); 8405 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8406 asList("2001:db8::1", "192.0.2.1"))); 8407 verifyNoMoreInteractions(mMockDnsResolver); 8408 reset(mMockDnsResolver); 8409 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8410 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8411 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8412 LINK_PROPERTIES_CHANGED, mCellAgent); 8413 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8414 cellNetworkCallback.assertNoCallback(); 8415 assertFalse(cbi.getLp().isPrivateDnsActive()); 8416 assertNull(cbi.getLp().getPrivateDnsServerName()); 8417 8418 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 8419 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 8420 mResolverParamsParcelCaptor.capture()); 8421 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8422 assertEquals(2, resolvrParams.servers.length); 8423 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8424 asList("2001:db8::1", "192.0.2.1"))); 8425 reset(mMockDnsResolver); 8426 cellNetworkCallback.assertNoCallback(); 8427 8428 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8429 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8430 mResolverParamsParcelCaptor.capture()); 8431 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8432 assertEquals(2, resolvrParams.servers.length); 8433 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8434 asList("2001:db8::1", "192.0.2.1"))); 8435 assertEquals(2, resolvrParams.tlsServers.length); 8436 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8437 asList("2001:db8::1", "192.0.2.1"))); 8438 reset(mMockDnsResolver); 8439 cellNetworkCallback.assertNoCallback(); 8440 8441 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 8442 // Can't test dns configuration for strict mode without properly mocking 8443 // out the DNS lookups, but can test that LinkProperties is updated. 8444 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8445 cellNetworkCallback.assertNoCallback(); 8446 assertTrue(cbi.getLp().isPrivateDnsActive()); 8447 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 8448 } 8449 8450 private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( 8451 final int netId, final String ipAddress, final String hostname, final int validation) { 8452 final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); 8453 event.netId = netId; 8454 event.ipAddress = ipAddress; 8455 event.hostname = hostname; 8456 event.validation = validation; 8457 return event; 8458 } 8459 8460 @Test 8461 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 8462 // The default on Android is opportunistic mode ("Automatic"). 8463 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8464 8465 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8466 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8467 .addTransportType(TRANSPORT_CELLULAR).build(); 8468 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8469 8470 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8471 waitForIdle(); 8472 LinkProperties lp = new LinkProperties(); 8473 mCellAgent.sendLinkProperties(lp); 8474 mCellAgent.connect(false); 8475 waitForIdle(); 8476 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8477 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8478 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8479 LINK_PROPERTIES_CHANGED, mCellAgent); 8480 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8481 cellNetworkCallback.assertNoCallback(); 8482 assertFalse(cbi.getLp().isPrivateDnsActive()); 8483 assertNull(cbi.getLp().getPrivateDnsServerName()); 8484 Set<InetAddress> dnsServers = new HashSet<>(); 8485 checkDnsServers(cbi.getLp(), dnsServers); 8486 8487 // Send a validation event for a server that is not part of the current 8488 // resolver config. The validation event should be ignored. 8489 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8490 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, "", 8491 "145.100.185.18", VALIDATION_RESULT_SUCCESS)); 8492 cellNetworkCallback.assertNoCallback(); 8493 8494 // Add a dns server to the LinkProperties. 8495 LinkProperties lp2 = new LinkProperties(lp); 8496 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 8497 mCellAgent.sendLinkProperties(lp2); 8498 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8499 cellNetworkCallback.assertNoCallback(); 8500 assertFalse(cbi.getLp().isPrivateDnsActive()); 8501 assertNull(cbi.getLp().getPrivateDnsServerName()); 8502 dnsServers.add(InetAddress.getByName("145.100.185.16")); 8503 checkDnsServers(cbi.getLp(), dnsServers); 8504 8505 // Send a validation event containing a hostname that is not part of 8506 // the current resolver config. The validation event should be ignored. 8507 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8508 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8509 "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); 8510 cellNetworkCallback.assertNoCallback(); 8511 8512 // Send a validation event where validation failed. 8513 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8514 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8515 "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 8516 cellNetworkCallback.assertNoCallback(); 8517 8518 // Send a validation event where validation succeeded for a server in 8519 // the current resolver config. A LinkProperties callback with updated 8520 // private dns fields should be sent. 8521 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8522 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8523 "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); 8524 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8525 cellNetworkCallback.assertNoCallback(); 8526 assertTrue(cbi.getLp().isPrivateDnsActive()); 8527 assertNull(cbi.getLp().getPrivateDnsServerName()); 8528 checkDnsServers(cbi.getLp(), dnsServers); 8529 8530 // The private dns fields in LinkProperties should be preserved when 8531 // the network agent sends unrelated changes. 8532 LinkProperties lp3 = new LinkProperties(lp2); 8533 lp3.setMtu(1300); 8534 mCellAgent.sendLinkProperties(lp3); 8535 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8536 cellNetworkCallback.assertNoCallback(); 8537 assertTrue(cbi.getLp().isPrivateDnsActive()); 8538 assertNull(cbi.getLp().getPrivateDnsServerName()); 8539 checkDnsServers(cbi.getLp(), dnsServers); 8540 assertEquals(1300, cbi.getLp().getMtu()); 8541 8542 // Removing the only validated server should affect the private dns 8543 // fields in LinkProperties. 8544 LinkProperties lp4 = new LinkProperties(lp3); 8545 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 8546 mCellAgent.sendLinkProperties(lp4); 8547 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8548 cellNetworkCallback.assertNoCallback(); 8549 assertFalse(cbi.getLp().isPrivateDnsActive()); 8550 assertNull(cbi.getLp().getPrivateDnsServerName()); 8551 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 8552 checkDnsServers(cbi.getLp(), dnsServers); 8553 assertEquals(1300, cbi.getLp().getMtu()); 8554 } 8555 8556 private void checkDirectlyConnectedRoutes(Object callbackObj, 8557 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 8558 assertTrue(callbackObj instanceof LinkProperties); 8559 LinkProperties lp = (LinkProperties) callbackObj; 8560 8561 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 8562 expectedRoutes.addAll(otherRoutes); 8563 for (LinkAddress address : linkAddresses) { 8564 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 8565 // Duplicates in linkAddresses are considered failures 8566 assertTrue(expectedRoutes.add(localRoute)); 8567 } 8568 List<RouteInfo> observedRoutes = lp.getRoutes(); 8569 assertEquals(expectedRoutes.size(), observedRoutes.size()); 8570 assertTrue(observedRoutes.containsAll(expectedRoutes)); 8571 } 8572 8573 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 8574 assertTrue(callbackObj instanceof LinkProperties); 8575 LinkProperties lp = (LinkProperties) callbackObj; 8576 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 8577 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 8578 } 8579 8580 @Test 8581 public void testApplyUnderlyingCapabilities() throws Exception { 8582 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8583 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8584 mCellAgent.connect(false /* validated */); 8585 mWiFiAgent.connect(false /* validated */); 8586 8587 final NetworkCapabilities cellNc = new NetworkCapabilities() 8588 .addTransportType(TRANSPORT_CELLULAR) 8589 .addCapability(NET_CAPABILITY_INTERNET) 8590 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8591 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8592 .setLinkDownstreamBandwidthKbps(10); 8593 final NetworkCapabilities wifiNc = new NetworkCapabilities() 8594 .addTransportType(TRANSPORT_WIFI) 8595 .addCapability(NET_CAPABILITY_INTERNET) 8596 .addCapability(NET_CAPABILITY_NOT_METERED) 8597 .addCapability(NET_CAPABILITY_NOT_ROAMING) 8598 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8599 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 8600 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8601 .setLinkUpstreamBandwidthKbps(20); 8602 mCellAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); 8603 mWiFiAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); 8604 waitForIdle(); 8605 8606 final Network mobile = mCellAgent.getNetwork(); 8607 final Network wifi = mWiFiAgent.getNetwork(); 8608 8609 final NetworkCapabilities initialCaps = new NetworkCapabilities(); 8610 initialCaps.addTransportType(TRANSPORT_VPN); 8611 initialCaps.addCapability(NET_CAPABILITY_INTERNET); 8612 initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); 8613 final ArrayList<Network> emptyUnderlyingNetworks = new ArrayList<Network>(); 8614 final ArrayList<Network> underlyingNetworksContainMobile = new ArrayList<Network>(); 8615 underlyingNetworksContainMobile.add(mobile); 8616 final ArrayList<Network> underlyingNetworksContainWifi = new ArrayList<Network>(); 8617 underlyingNetworksContainWifi.add(wifi); 8618 final ArrayList<Network> underlyingNetworksContainMobileAndMobile = 8619 new ArrayList<Network>(); 8620 underlyingNetworksContainMobileAndMobile.add(mobile); 8621 underlyingNetworksContainMobileAndMobile.add(wifi); 8622 8623 final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); 8624 withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); 8625 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); 8626 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); 8627 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8628 withNoUnderlying.addTransportType(TRANSPORT_VPN); 8629 withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); 8630 withNoUnderlying.setUnderlyingNetworks(emptyUnderlyingNetworks); 8631 8632 final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); 8633 withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8634 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8635 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 8636 withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8637 withMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobile); 8638 8639 final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); 8640 withWifiUnderlying.addTransportType(TRANSPORT_WIFI); 8641 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8642 withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); 8643 withWifiUnderlying.setUnderlyingNetworks(underlyingNetworksContainWifi); 8644 8645 final NetworkCapabilities withWifiAndMobileUnderlying = 8646 new NetworkCapabilities(withNoUnderlying); 8647 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8648 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); 8649 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8650 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8651 withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8652 withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); 8653 withWifiAndMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobileAndMobile); 8654 8655 final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); 8656 initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); 8657 8658 NetworkCapabilities caps = new NetworkCapabilities(initialCaps); 8659 mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); 8660 assertEquals(withNoUnderlying, caps); 8661 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8662 8663 caps = new NetworkCapabilities(initialCaps); 8664 mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); 8665 assertEquals(withNoUnderlying, caps); 8666 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8667 8668 caps = new NetworkCapabilities(initialCaps); 8669 mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); 8670 assertEquals(withMobileUnderlying, caps); 8671 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8672 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8673 8674 caps = new NetworkCapabilities(initialCaps); 8675 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); 8676 assertEquals(withWifiUnderlying, caps); 8677 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8678 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8679 8680 withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8681 caps = new NetworkCapabilities(initialCaps); 8682 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); 8683 assertEquals(withWifiUnderlying, caps); 8684 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8685 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8686 8687 caps = new NetworkCapabilities(initialCaps); 8688 mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); 8689 assertEquals(withWifiAndMobileUnderlying, caps); 8690 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8691 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8692 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8693 8694 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8695 caps = new NetworkCapabilities(initialCaps); 8696 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8697 initialCapsNotMetered, caps); 8698 assertEquals(withWifiAndMobileUnderlying, caps); 8699 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8700 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8701 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8702 8703 caps = new NetworkCapabilities(initialCaps); 8704 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8705 initialCapsNotMetered, caps); 8706 assertEquals(withWifiAndMobileUnderlying, caps); 8707 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8708 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8709 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8710 8711 caps = new NetworkCapabilities(initialCaps); 8712 mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); 8713 assertEquals(withWifiUnderlying, caps); 8714 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8715 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8716 } 8717 8718 @Test 8719 public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { 8720 final TestNetworkCallback callback = new TestNetworkCallback(); 8721 final NetworkRequest request = new NetworkRequest.Builder() 8722 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8723 8724 runAsShell(NETWORK_SETTINGS, () -> { 8725 mCm.registerNetworkCallback(request, callback); 8726 8727 // Bring up a VPN that specifies an underlying network that does not exist yet. 8728 // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist 8729 // yet, (and doing so is difficult without using reflection) but it's good to test that 8730 // the code behaves approximately correctly. 8731 mMockVpn.establishForMyUid(false, true, false); 8732 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8733 assertUidRangesUpdatedForMyUid(true); 8734 final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); 8735 mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); 8736 // onCapabilitiesChanged() should be called because 8737 // NetworkCapabilities#mUnderlyingNetworks is updated. 8738 final NetworkCapabilities vpnNc1 = callback.expectCaps(mMockVpn); 8739 // Since the wifi network hasn't brought up, 8740 // ConnectivityService#applyUnderlyingCapabilities cannot find it. Update 8741 // NetworkCapabilities#mUnderlyingNetworks to an empty array, and it will be updated to 8742 // the correct underlying networks once the wifi network brings up. But this case 8743 // shouldn't happen in reality since no one could get the network which hasn't brought 8744 // up. For the empty array of underlying networks, it should be happened for 2 cases, 8745 // the first one is that the VPN app declares an empty array for its underlying 8746 // networks, the second one is that the underlying networks are torn down. 8747 // 8748 // It shouldn't be null since the null value means the underlying networks of this 8749 // network should follow the default network. 8750 final ArrayList<Network> underlyingNetwork = new ArrayList<>(); 8751 assertEquals(underlyingNetwork, vpnNc1.getUnderlyingNetworks()); 8752 // Since the wifi network isn't exist, applyUnderlyingCapabilities() 8753 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8754 .hasTransport(TRANSPORT_VPN)); 8755 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8756 .hasTransport(TRANSPORT_WIFI)); 8757 8758 // Make that underlying network connect, and expect to see its capabilities immediately 8759 // reflected in the VPN's capabilities. 8760 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8761 assertEquals(wifiNetwork, mWiFiAgent.getNetwork()); 8762 mWiFiAgent.connect(false); 8763 // TODO: the callback for the VPN happens before any callbacks are called for the wifi 8764 // network that has just connected. There appear to be two issues here: 8765 // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() 8766 // for it returns non-null (which happens very early, during 8767 // handleRegisterNetworkAgent). 8768 // This is not correct because that that point the network is not connected and 8769 // cannot pass any traffic. 8770 // 2. When a network connects, updateNetworkInfo propagates underlying network 8771 // capabilities before rematching networks. 8772 // Given that this scenario can't really happen, this is probably fine for now. 8773 final NetworkCapabilities vpnNc2 = callback.expectCaps(mMockVpn); 8774 // The wifi network is brought up, NetworkCapabilities#mUnderlyingNetworks is updated to 8775 // it. 8776 underlyingNetwork.add(wifiNetwork); 8777 assertEquals(underlyingNetwork, vpnNc2.getUnderlyingNetworks()); 8778 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8779 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8780 .hasTransport(TRANSPORT_VPN)); 8781 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8782 .hasTransport(TRANSPORT_WIFI)); 8783 8784 // Disconnect the network, and expect to see the VPN capabilities change accordingly. 8785 mWiFiAgent.disconnect(); 8786 callback.expect(LOST, mWiFiAgent); 8787 callback.expectCaps(mMockVpn, c -> c.getTransportTypes().length == 1 8788 && c.hasTransport(TRANSPORT_VPN)); 8789 8790 mMockVpn.disconnect(); 8791 mCm.unregisterNetworkCallback(callback); 8792 }); 8793 } 8794 8795 private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { 8796 // What Chromium used to do before https://chromium-review.googlesource.com/2605304 8797 assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", 8798 expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); 8799 } 8800 8801 @Test 8802 public void testVpnUnderlyingNetworkSuspended() throws Exception { 8803 final TestNetworkCallback callback = new TestNetworkCallback(); 8804 mCm.registerDefaultNetworkCallback(callback); 8805 8806 // Connect a VPN. 8807 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 8808 false /* privateDnsProbeSent */); 8809 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8810 8811 // Connect cellular data. 8812 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8813 mCellAgent.connect(false /* validated */); 8814 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8815 && c.hasTransport(TRANSPORT_CELLULAR)); 8816 callback.assertNoCallback(); 8817 8818 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8819 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8820 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8821 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8822 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8823 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8824 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8825 8826 // Suspend the cellular network and expect the VPN to be suspended. 8827 mCellAgent.suspend(); 8828 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8829 && c.hasTransport(TRANSPORT_CELLULAR)); 8830 callback.expect(SUSPENDED, mMockVpn); 8831 callback.assertNoCallback(); 8832 8833 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8834 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8835 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8836 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8837 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8838 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8839 // VPN's main underlying network is suspended, so no connectivity. 8840 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8841 8842 // Switch to another network. The VPN should no longer be suspended. 8843 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8844 mWiFiAgent.connect(false /* validated */); 8845 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8846 && c.hasTransport(TRANSPORT_WIFI)); 8847 callback.expect(RESUMED, mMockVpn); 8848 callback.assertNoCallback(); 8849 8850 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8851 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8852 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8853 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8854 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8855 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8856 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8857 8858 // Unsuspend cellular and then switch back to it. The VPN remains not suspended. 8859 mCellAgent.resume(); 8860 callback.assertNoCallback(); 8861 mWiFiAgent.disconnect(); 8862 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8863 && c.hasTransport(TRANSPORT_CELLULAR)); 8864 // Spurious double callback? 8865 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8866 && c.hasTransport(TRANSPORT_CELLULAR)); 8867 callback.assertNoCallback(); 8868 8869 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8870 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8871 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8872 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8873 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8874 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8875 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8876 8877 // Suspend cellular and expect no connectivity. 8878 mCellAgent.suspend(); 8879 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8880 && c.hasTransport(TRANSPORT_CELLULAR)); 8881 callback.expect(SUSPENDED, mMockVpn); 8882 callback.assertNoCallback(); 8883 8884 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8885 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8886 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8887 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8888 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8889 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8890 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8891 8892 // Resume cellular and expect that connectivity comes back. 8893 mCellAgent.resume(); 8894 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8895 && c.hasTransport(TRANSPORT_CELLULAR)); 8896 callback.expect(RESUMED, mMockVpn); 8897 callback.assertNoCallback(); 8898 8899 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8900 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8901 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8902 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8903 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8904 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8905 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8906 } 8907 8908 @Test 8909 public void testVpnNetworkActive() throws Exception { 8910 final int uid = Process.myUid(); 8911 8912 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 8913 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 8914 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 8915 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8916 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8917 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 8918 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 8919 final NetworkRequest genericRequest = new NetworkRequest.Builder() 8920 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8921 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 8922 .addTransportType(TRANSPORT_WIFI).build(); 8923 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8924 .removeCapability(NET_CAPABILITY_NOT_VPN) 8925 .addTransportType(TRANSPORT_VPN).build(); 8926 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 8927 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 8928 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 8929 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8930 mCm.registerDefaultNetworkCallback(defaultCallback); 8931 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 8932 new Handler(ConnectivityThread.getInstanceLooper())); 8933 defaultCallback.assertNoCallback(); 8934 8935 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8936 mWiFiAgent.connect(false); 8937 8938 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8939 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8940 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8941 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8942 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8943 vpnNetworkCallback.assertNoCallback(); 8944 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8945 8946 final Set<UidRange> ranges = uidRangesForUids(uid); 8947 mMockVpn.registerAgent(ranges); 8948 mMockVpn.setUnderlyingNetworks(new Network[0]); 8949 8950 // VPN networks do not satisfy the default request and are automatically validated 8951 // by NetworkMonitor 8952 assertFalse(NetworkMonitorUtils.isValidationRequired( 8953 false /* isDunValidationRequired */, 8954 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 8955 .isVpnValidationRequired(), 8956 mMockVpn.getAgent().getNetworkCapabilities())); 8957 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 8958 8959 mMockVpn.connect(false); 8960 8961 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8962 genericNotVpnNetworkCallback.assertNoCallback(); 8963 wifiNetworkCallback.assertNoCallback(); 8964 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8965 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8966 systemDefaultCallback.assertNoCallback(); 8967 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8968 assertEquals(mWiFiAgent.getNetwork(), systemDefaultCallback.getLastAvailableNetwork()); 8969 8970 ranges.clear(); 8971 mMockVpn.setUids(ranges); 8972 8973 genericNetworkCallback.expect(LOST, mMockVpn); 8974 genericNotVpnNetworkCallback.assertNoCallback(); 8975 wifiNetworkCallback.assertNoCallback(); 8976 vpnNetworkCallback.expect(LOST, mMockVpn); 8977 8978 // TODO : The default network callback should actually get a LOST call here (also see the 8979 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 8980 // ranges at all when determining whether a network should be rematched. In practice, VPNs 8981 // can't currently update their UIDs without disconnecting, so this does not matter too 8982 // much, but that is the reason the test here has to check for an update to the 8983 // capabilities instead of the expected LOST then AVAILABLE. 8984 defaultCallback.expectCaps(mMockVpn); 8985 systemDefaultCallback.assertNoCallback(); 8986 8987 ranges.add(new UidRange(uid, uid)); 8988 mMockVpn.setUids(ranges); 8989 8990 genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8991 genericNotVpnNetworkCallback.assertNoCallback(); 8992 wifiNetworkCallback.assertNoCallback(); 8993 vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8994 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 8995 // happen outside of the test, ConnectivityService does not rematch callbacks. 8996 defaultCallback.expectCaps(mMockVpn); 8997 systemDefaultCallback.assertNoCallback(); 8998 8999 mWiFiAgent.disconnect(); 9000 9001 genericNetworkCallback.expect(LOST, mWiFiAgent); 9002 genericNotVpnNetworkCallback.expect(LOST, mWiFiAgent); 9003 wifiNetworkCallback.expect(LOST, mWiFiAgent); 9004 vpnNetworkCallback.assertNoCallback(); 9005 defaultCallback.assertNoCallback(); 9006 systemDefaultCallback.expect(LOST, mWiFiAgent); 9007 9008 mMockVpn.disconnect(); 9009 9010 genericNetworkCallback.expect(LOST, mMockVpn); 9011 genericNotVpnNetworkCallback.assertNoCallback(); 9012 wifiNetworkCallback.assertNoCallback(); 9013 vpnNetworkCallback.expect(LOST, mMockVpn); 9014 defaultCallback.expect(LOST, mMockVpn); 9015 systemDefaultCallback.assertNoCallback(); 9016 assertEquals(null, mCm.getActiveNetwork()); 9017 9018 mCm.unregisterNetworkCallback(genericNetworkCallback); 9019 mCm.unregisterNetworkCallback(wifiNetworkCallback); 9020 mCm.unregisterNetworkCallback(vpnNetworkCallback); 9021 mCm.unregisterNetworkCallback(defaultCallback); 9022 mCm.unregisterNetworkCallback(systemDefaultCallback); 9023 } 9024 9025 @Test 9026 public void testVpnWithoutInternet() throws Exception { 9027 final int uid = Process.myUid(); 9028 9029 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9030 mCm.registerDefaultNetworkCallback(defaultCallback); 9031 9032 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9033 mWiFiAgent.connect(true); 9034 9035 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 9036 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9037 9038 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9039 false /* privateDnsProbeSent */); 9040 assertUidRangesUpdatedForMyUid(true); 9041 9042 defaultCallback.assertNoCallback(); 9043 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9044 9045 mMockVpn.disconnect(); 9046 defaultCallback.assertNoCallback(); 9047 9048 mCm.unregisterNetworkCallback(defaultCallback); 9049 } 9050 9051 @Test 9052 public void testVpnWithInternet() throws Exception { 9053 final int uid = Process.myUid(); 9054 9055 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9056 mCm.registerDefaultNetworkCallback(defaultCallback); 9057 9058 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9059 mWiFiAgent.connect(true); 9060 9061 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 9062 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9063 9064 mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, 9065 false /* privateDnsProbeSent */); 9066 assertUidRangesUpdatedForMyUid(true); 9067 9068 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9069 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9070 9071 mMockVpn.disconnect(); 9072 defaultCallback.expect(LOST, mMockVpn); 9073 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 9074 9075 mCm.unregisterNetworkCallback(defaultCallback); 9076 } 9077 9078 @Test 9079 public void testVpnUnvalidated() throws Exception { 9080 final TestNetworkCallback callback = new TestNetworkCallback(); 9081 mCm.registerDefaultNetworkCallback(callback); 9082 9083 // Bring up Ethernet. 9084 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 9085 mEthernetAgent.connect(true); 9086 callback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 9087 callback.assertNoCallback(); 9088 9089 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 9090 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 9091 false /* privateDnsProbeSent */); 9092 assertUidRangesUpdatedForMyUid(true); 9093 9094 // Even though the VPN is unvalidated, it becomes the default network for our app. 9095 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 9096 callback.assertNoCallback(); 9097 9098 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9099 9100 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9101 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 9102 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 9103 9104 assertFalse(NetworkMonitorUtils.isValidationRequired( 9105 false /* isDunValidationRequired */, 9106 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 9107 .isVpnValidationRequired(), 9108 mMockVpn.getAgent().getNetworkCapabilities())); 9109 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 9110 mMockVpn.getAgent().getNetworkCapabilities())); 9111 9112 // Pretend that the VPN network validates. 9113 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 9114 mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); 9115 // Expect to see the validated capability, but no other changes, because the VPN is already 9116 // the default network for the app. 9117 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9118 callback.assertNoCallback(); 9119 9120 mMockVpn.disconnect(); 9121 callback.expect(LOST, mMockVpn); 9122 callback.expectAvailableCallbacksValidated(mEthernetAgent); 9123 } 9124 9125 @Test 9126 public void testVpnStartsWithUnderlyingCaps() throws Exception { 9127 final int uid = Process.myUid(); 9128 9129 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9130 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9131 .removeCapability(NET_CAPABILITY_NOT_VPN) 9132 .addTransportType(TRANSPORT_VPN) 9133 .build(); 9134 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9135 vpnNetworkCallback.assertNoCallback(); 9136 9137 // Connect cell. It will become the default network, and in the absence of setting 9138 // underlying networks explicitly it will become the sole underlying network for the vpn. 9139 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9140 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9141 mCellAgent.connect(true); 9142 9143 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9144 false /* privateDnsProbeSent */); 9145 assertUidRangesUpdatedForMyUid(true); 9146 9147 vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), 9148 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 9149 vpnNetworkCallback.expectCaps(mMockVpn.getNetwork(), TIMEOUT_MS, 9150 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9151 9152 final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9153 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9154 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 9155 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9156 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 9157 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9158 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9159 9160 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9161 } 9162 9163 private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { 9164 final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( 9165 userId, "com.android.calling.package", "com.test"); 9166 final String defaultCapsString = Arrays.toString(defaultCaps); 9167 assertEquals(defaultCapsString, defaultCaps.length, networks.length); 9168 final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); 9169 for (NetworkAgentWrapper network : networks) { 9170 final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 9171 final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); 9172 assertTrue(msg, defaultCapsSet.contains(nc)); 9173 } 9174 } 9175 9176 @Test 9177 public void testVpnSetUnderlyingNetworks() throws Exception { 9178 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9179 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9180 .removeCapability(NET_CAPABILITY_NOT_VPN) 9181 .addTransportType(TRANSPORT_VPN) 9182 .build(); 9183 NetworkCapabilities nc; 9184 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9185 vpnNetworkCallback.assertNoCallback(); 9186 9187 // Lingering timer is short and cell might be disconnected if the device is particularly 9188 // slow running the test, unless it's requested. Make sure the networks the test needs 9189 // are all requested. 9190 final NetworkCallback cellCallback = new NetworkCallback() {}; 9191 final NetworkCallback wifiCallback = new NetworkCallback() {}; 9192 mCm.requestNetwork( 9193 new NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).build(), 9194 cellCallback); 9195 mCm.requestNetwork( 9196 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 9197 wifiCallback); 9198 9199 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9200 false /* privateDnsProbeSent */); 9201 assertUidRangesUpdatedForMyUid(true); 9202 9203 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9204 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9205 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9206 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9207 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9208 // For safety reasons a VPN without underlying networks is considered metered. 9209 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9210 // A VPN without underlying networks is not suspended. 9211 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9212 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9213 9214 final int userId = UserHandle.getUserId(Process.myUid()); 9215 assertDefaultNetworkCapabilities(userId /* no networks */); 9216 9217 // Connect cell and use it as an underlying network. 9218 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9219 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9220 mCellAgent.connect(true); 9221 9222 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9223 9224 vpnNetworkCallback.expectCaps(mMockVpn, 9225 c -> c.hasTransport(TRANSPORT_VPN) 9226 && c.hasTransport(TRANSPORT_CELLULAR) 9227 && !c.hasTransport(TRANSPORT_WIFI) 9228 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9229 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9230 assertDefaultNetworkCapabilities(userId, mCellAgent); 9231 9232 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9233 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9234 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9235 mWiFiAgent.connect(true); 9236 9237 mMockVpn.setUnderlyingNetworks( 9238 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9239 9240 vpnNetworkCallback.expectCaps(mMockVpn, 9241 c -> c.hasTransport(TRANSPORT_VPN) 9242 && c.hasTransport(TRANSPORT_CELLULAR) 9243 && c.hasTransport(TRANSPORT_WIFI) 9244 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9245 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9246 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9247 9248 // Don't disconnect, but note the VPN is not using wifi any more. 9249 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9250 9251 vpnNetworkCallback.expectCaps(mMockVpn, 9252 c -> c.hasTransport(TRANSPORT_VPN) 9253 && c.hasTransport(TRANSPORT_CELLULAR) 9254 && !c.hasTransport(TRANSPORT_WIFI) 9255 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9256 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9257 // The return value of getDefaultNetworkCapabilitiesForUser always includes the default 9258 // network (wifi) as well as the underlying networks (cell). 9259 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9260 9261 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 9262 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9263 vpnNetworkCallback.expectCaps(mMockVpn, 9264 c -> c.hasTransport(TRANSPORT_VPN) 9265 && c.hasTransport(TRANSPORT_CELLULAR) 9266 && !c.hasTransport(TRANSPORT_WIFI) 9267 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9268 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9269 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9270 9271 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 9272 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9273 vpnNetworkCallback.expectCaps(mMockVpn, 9274 c -> c.hasTransport(TRANSPORT_VPN) 9275 && c.hasTransport(TRANSPORT_CELLULAR) 9276 && !c.hasTransport(TRANSPORT_WIFI) 9277 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9278 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9279 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9280 9281 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 9282 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9283 9284 vpnNetworkCallback.expectCaps(mMockVpn, 9285 c -> c.hasTransport(TRANSPORT_VPN) 9286 && !c.hasTransport(TRANSPORT_CELLULAR) 9287 && c.hasTransport(TRANSPORT_WIFI) 9288 && c.hasCapability(NET_CAPABILITY_NOT_METERED) 9289 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9290 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9291 9292 // Use both again. 9293 mMockVpn.setUnderlyingNetworks( 9294 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9295 9296 vpnNetworkCallback.expectCaps(mMockVpn, 9297 c -> c.hasTransport(TRANSPORT_VPN) 9298 && c.hasTransport(TRANSPORT_CELLULAR) 9299 && c.hasTransport(TRANSPORT_WIFI) 9300 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9301 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9302 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9303 9304 // Cell is suspended again. As WiFi is not, this should not cause a callback. 9305 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9306 vpnNetworkCallback.assertNoCallback(); 9307 9308 // Stop using WiFi. The VPN is suspended again. 9309 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9310 vpnNetworkCallback.expectCaps(mMockVpn, 9311 c -> c.hasTransport(TRANSPORT_VPN) 9312 && c.hasTransport(TRANSPORT_CELLULAR) 9313 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9314 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9315 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9316 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9317 9318 // Use both again. 9319 mMockVpn.setUnderlyingNetworks( 9320 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9321 9322 vpnNetworkCallback.expectCaps(mMockVpn, 9323 c -> c.hasTransport(TRANSPORT_VPN) 9324 && c.hasTransport(TRANSPORT_CELLULAR) 9325 && c.hasTransport(TRANSPORT_WIFI) 9326 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9327 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9328 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9329 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9330 9331 // Disconnect cell. Receive update without even removing the dead network from the 9332 // underlying networks – it's dead anyway. Not metered any more. 9333 mCellAgent.disconnect(); 9334 vpnNetworkCallback.expectCaps(mMockVpn, 9335 c -> c.hasTransport(TRANSPORT_VPN) 9336 && !c.hasTransport(TRANSPORT_CELLULAR) 9337 && c.hasTransport(TRANSPORT_WIFI) 9338 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9339 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9340 9341 // Disconnect wifi too. No underlying networks means this is now metered. 9342 mWiFiAgent.disconnect(); 9343 vpnNetworkCallback.expectCaps(mMockVpn, 9344 c -> c.hasTransport(TRANSPORT_VPN) 9345 && !c.hasTransport(TRANSPORT_CELLULAR) 9346 && !c.hasTransport(TRANSPORT_WIFI) 9347 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9348 // When a network disconnects, the callbacks are fired before all state is updated, so for a 9349 // short time, synchronous calls will behave as if the network is still connected. Wait for 9350 // things to settle. 9351 waitForIdle(); 9352 assertDefaultNetworkCapabilities(userId /* no networks */); 9353 9354 mMockVpn.disconnect(); 9355 mCm.unregisterNetworkCallback(cellCallback); 9356 mCm.unregisterNetworkCallback(wifiCallback); 9357 } 9358 9359 @Test 9360 public void testNullUnderlyingNetworks() throws Exception { 9361 final int uid = Process.myUid(); 9362 9363 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9364 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9365 .removeCapability(NET_CAPABILITY_NOT_VPN) 9366 .addTransportType(TRANSPORT_VPN) 9367 .build(); 9368 NetworkCapabilities nc; 9369 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9370 vpnNetworkCallback.assertNoCallback(); 9371 9372 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9373 false /* privateDnsProbeSent */); 9374 assertUidRangesUpdatedForMyUid(true); 9375 9376 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9377 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9378 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9379 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9380 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9381 // By default, VPN is set to track default network (i.e. its underlying networks is null). 9382 // In case of no default network, VPN is considered metered. 9383 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9384 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9385 9386 // Connect to Cell; Cell is the default network. 9387 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9388 mCellAgent.connect(true); 9389 9390 vpnNetworkCallback.expectCaps(mMockVpn, 9391 c -> c.hasTransport(TRANSPORT_VPN) 9392 && c.hasTransport(TRANSPORT_CELLULAR) 9393 && !c.hasTransport(TRANSPORT_WIFI) 9394 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9395 9396 // Connect to WiFi; WiFi is the new default. 9397 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9398 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9399 mWiFiAgent.connect(true); 9400 9401 vpnNetworkCallback.expectCaps(mMockVpn, 9402 c -> c.hasTransport(TRANSPORT_VPN) 9403 && !c.hasTransport(TRANSPORT_CELLULAR) 9404 && c.hasTransport(TRANSPORT_WIFI) 9405 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9406 9407 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 9408 // the capabilities. 9409 mCellAgent.disconnect(); 9410 9411 // Disconnect wifi too. Now we have no default network. 9412 mWiFiAgent.disconnect(); 9413 9414 vpnNetworkCallback.expectCaps(mMockVpn, 9415 c -> c.hasTransport(TRANSPORT_VPN) 9416 && !c.hasTransport(TRANSPORT_CELLULAR) 9417 && !c.hasTransport(TRANSPORT_WIFI) 9418 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9419 9420 mMockVpn.disconnect(); 9421 } 9422 9423 @Test 9424 public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { 9425 // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. 9426 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9427 9428 final NetworkRequest request = new NetworkRequest.Builder() 9429 .removeCapability(NET_CAPABILITY_NOT_VPN) 9430 .build(); 9431 final TestNetworkCallback callback = new TestNetworkCallback(); 9432 mCm.registerNetworkCallback(request, callback); 9433 9434 // File a VPN request to prevent VPN network being lingered. 9435 final NetworkRequest vpnRequest = new NetworkRequest.Builder() 9436 .addTransportType(TRANSPORT_VPN) 9437 .removeCapability(NET_CAPABILITY_NOT_VPN) 9438 .build(); 9439 final TestNetworkCallback vpnCallback = new TestNetworkCallback(); 9440 mCm.requestNetwork(vpnRequest, vpnCallback); 9441 9442 // Bring up a VPN 9443 mMockVpn.establishForMyUid(); 9444 assertUidRangesUpdatedForMyUid(true); 9445 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 9446 callback.assertNoCallback(); 9447 9448 final int uid = Process.myUid(); 9449 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9450 assertNotNull("nc=" + nc, nc.getUids()); 9451 assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); 9452 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9453 9454 // Set an underlying network and expect to see the VPN transports change. 9455 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9456 mWiFiAgent.connect(true); 9457 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9458 callback.expectCaps(mMockVpn, c -> c.hasTransport(TRANSPORT_VPN) 9459 && c.hasTransport(TRANSPORT_WIFI)); 9460 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9461 9462 // New user added, this updates the Vpn uids, coverage in VpnTest. 9463 // This is equivalent to `mMockVpn.onUserAdded(RESTRICTED_USER);` 9464 final Set<UidRange> ranges = uidRangesForUids(uid); 9465 ranges.add(RESTRICTED_USER_UIDRANGE); 9466 mMockVpn.setUids(ranges); 9467 9468 // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added 9469 // restricted user. 9470 final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 9471 final Range<Integer> restrictUidRange = new Range<>(rRange.start, rRange.stop); 9472 final Range<Integer> singleUidRange = new Range<>(uid, uid); 9473 callback.expectCaps(mMockVpn, c -> 9474 c.getUids().size() == 2 9475 && c.getUids().contains(singleUidRange) 9476 && c.getUids().contains(restrictUidRange) 9477 && c.hasTransport(TRANSPORT_VPN) 9478 && c.hasTransport(TRANSPORT_WIFI)); 9479 9480 // Change the VPN's capabilities somehow (specifically, disconnect wifi). 9481 mWiFiAgent.disconnect(); 9482 callback.expect(LOST, mWiFiAgent); 9483 callback.expectCaps(mMockVpn, c -> 9484 c.getUids().size() == 2 9485 && c.getUids().contains(singleUidRange) 9486 && c.getUids().contains(restrictUidRange) 9487 && c.hasTransport(TRANSPORT_VPN) 9488 && !c.hasTransport(TRANSPORT_WIFI)); 9489 9490 // User removed and expect to lose the UID range for the restricted user. 9491 // This updates the Vpn uids, coverage in VpnTest. 9492 // This is equivalent to `mMockVpn.onUserRemoved(RESTRICTED_USER);` 9493 mMockVpn.setUids(uidRangesForUids(uid)); 9494 9495 // Expect that the VPN gains the UID range for the restricted user, and that the capability 9496 // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. 9497 callback.expectCaps(mMockVpn, c -> 9498 c.getUids().size() == 1 9499 && c.getUids().contains(singleUidRange) 9500 && c.hasTransport(TRANSPORT_VPN) 9501 && !c.hasTransport(TRANSPORT_WIFI)); 9502 9503 mCm.unregisterNetworkCallback(callback); 9504 mCm.unregisterNetworkCallback(vpnCallback); 9505 } 9506 9507 @Test 9508 public void testLockdownVpnWithRestrictedProfiles() throws Exception { 9509 // For ConnectivityService#setAlwaysOnVpnPackage. 9510 mServiceContext.setPermission( 9511 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9512 // For call Vpn#setAlwaysOnPackage. 9513 mServiceContext.setPermission( 9514 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9515 // Necessary to see the UID ranges in NetworkCapabilities. 9516 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9517 9518 final NetworkRequest request = new NetworkRequest.Builder() 9519 .removeCapability(NET_CAPABILITY_NOT_VPN) 9520 .build(); 9521 final TestNetworkCallback callback = new TestNetworkCallback(); 9522 mCm.registerNetworkCallback(request, callback); 9523 9524 final int uid = Process.myUid(); 9525 9526 // Connect wifi and check that UIDs in the main and restricted profiles have network access. 9527 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9528 mWiFiAgent.connect(true /* validated */); 9529 final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); 9530 assertNotNull(mCm.getActiveNetworkForUid(uid)); 9531 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9532 9533 // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. 9534 // Coverage in VpnTest. 9535 final List<Integer> excludedUids = new ArrayList<>(); 9536 excludedUids.add(VPN_UID); 9537 if (mDeps.isAtLeastT()) { 9538 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9539 excludedUids.add(toSdkSandboxUid(VPN_UID)); 9540 } 9541 final List<Range<Integer>> primaryRanges = intRangesPrimaryExcludingUids(excludedUids); 9542 mCm.setRequireVpnForUids(true, primaryRanges); 9543 9544 waitForIdle(); 9545 assertNull(mCm.getActiveNetworkForUid(uid)); 9546 // This is arguably overspecified: a UID that is not running doesn't have an active network. 9547 // But it's useful to check that non-default users do not lose network access, and to prove 9548 // that the loss of connectivity below is indeed due to the restricted profile coming up. 9549 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9550 9551 // Start the restricted profile, and check that the UID within it loses network access. 9552 // TODO: check that VPN app within restricted profile still has access, etc. 9553 // Add a restricted user. 9554 // This is equivalent to `mMockVpn.onUserAdded(RESTRICTED_USER);`, coverage in VpnTest. 9555 final List<Range<Integer>> restrictedRanges = 9556 intRangesExcludingUids(RESTRICTED_USER, excludedUids); 9557 mCm.setRequireVpnForUids(true, restrictedRanges); 9558 waitForIdle(); 9559 9560 assertNull(mCm.getActiveNetworkForUid(uid)); 9561 assertNull(mCm.getActiveNetworkForUid(restrictedUid)); 9562 9563 // Stop the restricted profile, and check that the UID within it has network access again. 9564 // Remove the restricted user. 9565 // This is equivalent to `mMockVpn.onUserRemoved(RESTRICTED_USER);`, coverage in VpnTest. 9566 mCm.setRequireVpnForUids(false, restrictedRanges); 9567 waitForIdle(); 9568 9569 assertNull(mCm.getActiveNetworkForUid(uid)); 9570 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9571 9572 mCm.setRequireVpnForUids(false, primaryRanges); 9573 9574 waitForIdle(); 9575 } 9576 9577 @Test 9578 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 9579 // Returns true by default when no network is available. 9580 assertTrue(mCm.isActiveNetworkMetered()); 9581 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9582 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9583 mWiFiAgent.connect(true); 9584 waitForIdle(); 9585 9586 assertFalse(mCm.isActiveNetworkMetered()); 9587 } 9588 9589 @Test 9590 public void testIsActiveNetworkMeteredOverCell() throws Exception { 9591 // Returns true by default when no network is available. 9592 assertTrue(mCm.isActiveNetworkMetered()); 9593 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9594 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9595 mCellAgent.connect(true); 9596 waitForIdle(); 9597 9598 assertTrue(mCm.isActiveNetworkMetered()); 9599 } 9600 9601 @Test 9602 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 9603 // Returns true by default when no network is available. 9604 assertTrue(mCm.isActiveNetworkMetered()); 9605 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9606 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9607 mCellAgent.connect(true); 9608 waitForIdle(); 9609 assertTrue(mCm.isActiveNetworkMetered()); 9610 9611 // Connect VPN network. By default it is using current default network (Cell). 9612 mMockVpn.establishForMyUid(); 9613 assertUidRangesUpdatedForMyUid(true); 9614 9615 // Ensure VPN is now the active network. 9616 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9617 9618 // Expect VPN to be metered. 9619 assertTrue(mCm.isActiveNetworkMetered()); 9620 9621 // Connect WiFi. 9622 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9623 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9624 mWiFiAgent.connect(true); 9625 waitForIdle(); 9626 // VPN should still be the active network. 9627 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9628 9629 // Expect VPN to be unmetered as it should now be using WiFi (new default). 9630 assertFalse(mCm.isActiveNetworkMetered()); 9631 9632 // Disconnecting Cell should not affect VPN's meteredness. 9633 mCellAgent.disconnect(); 9634 waitForIdle(); 9635 9636 assertFalse(mCm.isActiveNetworkMetered()); 9637 9638 // Disconnect WiFi; Now there is no platform default network. 9639 mWiFiAgent.disconnect(); 9640 waitForIdle(); 9641 9642 // VPN without any underlying networks is treated as metered. 9643 assertTrue(mCm.isActiveNetworkMetered()); 9644 9645 mMockVpn.disconnect(); 9646 } 9647 9648 @Test 9649 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 9650 // Returns true by default when no network is available. 9651 assertTrue(mCm.isActiveNetworkMetered()); 9652 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9653 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9654 mCellAgent.connect(true); 9655 waitForIdle(); 9656 assertTrue(mCm.isActiveNetworkMetered()); 9657 9658 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9659 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9660 mWiFiAgent.connect(true); 9661 waitForIdle(); 9662 assertFalse(mCm.isActiveNetworkMetered()); 9663 9664 // Connect VPN network. 9665 mMockVpn.establishForMyUid(); 9666 assertUidRangesUpdatedForMyUid(true); 9667 9668 // Ensure VPN is now the active network. 9669 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9670 // VPN is using Cell 9671 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9672 waitForIdle(); 9673 9674 // Expect VPN to be metered. 9675 assertTrue(mCm.isActiveNetworkMetered()); 9676 9677 // VPN is now using WiFi 9678 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9679 waitForIdle(); 9680 9681 // Expect VPN to be unmetered 9682 assertFalse(mCm.isActiveNetworkMetered()); 9683 9684 // VPN is using Cell | WiFi. 9685 mMockVpn.setUnderlyingNetworks( 9686 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9687 waitForIdle(); 9688 9689 // Expect VPN to be metered. 9690 assertTrue(mCm.isActiveNetworkMetered()); 9691 9692 // VPN is using WiFi | Cell. 9693 mMockVpn.setUnderlyingNetworks( 9694 new Network[] { mWiFiAgent.getNetwork(), mCellAgent.getNetwork() }); 9695 waitForIdle(); 9696 9697 // Order should not matter and VPN should still be metered. 9698 assertTrue(mCm.isActiveNetworkMetered()); 9699 9700 // VPN is not using any underlying networks. 9701 mMockVpn.setUnderlyingNetworks(new Network[0]); 9702 waitForIdle(); 9703 9704 // VPN without underlying networks is treated as metered. 9705 assertTrue(mCm.isActiveNetworkMetered()); 9706 9707 mMockVpn.disconnect(); 9708 } 9709 9710 @Test 9711 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 9712 // Returns true by default when no network is available. 9713 assertTrue(mCm.isActiveNetworkMetered()); 9714 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9715 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9716 mWiFiAgent.connect(true); 9717 waitForIdle(); 9718 assertFalse(mCm.isActiveNetworkMetered()); 9719 9720 // Connect VPN network. 9721 mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), 9722 new LinkProperties()); 9723 mMockVpn.connect(true); 9724 waitForIdle(); 9725 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9726 9727 // VPN is tracking current platform default (WiFi). 9728 mMockVpn.setUnderlyingNetworks(null); 9729 waitForIdle(); 9730 9731 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 9732 assertTrue(mCm.isActiveNetworkMetered()); 9733 9734 9735 // VPN explicitly declares WiFi as its underlying network. 9736 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9737 waitForIdle(); 9738 9739 // Doesn't really matter whether VPN declares its underlying networks explicitly. 9740 assertTrue(mCm.isActiveNetworkMetered()); 9741 9742 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 9743 // anyways suppose to be metered. 9744 mWiFiAgent.disconnect(); 9745 waitForIdle(); 9746 9747 assertTrue(mCm.isActiveNetworkMetered()); 9748 9749 mMockVpn.disconnect(); 9750 } 9751 9752 private class DetailedBlockedStatusCallback extends TestNetworkCallback { 9753 public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { 9754 super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); 9755 } 9756 public void onBlockedStatusChanged(Network network, int blockedReasons) { 9757 getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); 9758 } 9759 } 9760 9761 @Test 9762 public void testNetworkBlockedStatus() throws Exception { 9763 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 9764 final NetworkRequest cellRequest = new NetworkRequest.Builder() 9765 .addTransportType(TRANSPORT_CELLULAR) 9766 .build(); 9767 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 9768 final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); 9769 mCm.registerNetworkCallback(cellRequest, detailedCallback); 9770 9771 mockUidNetworkingBlocked(); 9772 9773 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9774 mCellAgent.connect(true); 9775 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 9776 detailedCallback.expectAvailableThenValidatedCallbacks(mCellAgent, BLOCKED_REASON_NONE); 9777 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9778 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9779 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9780 assertExtraInfoFromCmPresent(mCellAgent); 9781 9782 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9783 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9784 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9785 cb -> cb.getReason() == BLOCKED_REASON_BATTERY_SAVER); 9786 assertNull(mCm.getActiveNetwork()); 9787 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9788 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9789 assertExtraInfoFromCmBlocked(mCellAgent); 9790 9791 // If blocked state does not change but blocked reason does, the boolean callback is called. 9792 // TODO: investigate de-duplicating. 9793 setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); 9794 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9795 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9796 cb -> cb.getReason() == BLOCKED_METERED_REASON_USER_RESTRICTED); 9797 9798 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9799 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9800 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9801 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9802 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9803 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9804 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9805 assertExtraInfoFromCmPresent(mCellAgent); 9806 9807 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9808 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9809 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9810 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9811 assertNull(mCm.getActiveNetwork()); 9812 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9813 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9814 assertExtraInfoFromCmBlocked(mCellAgent); 9815 9816 // Restrict the network based on UID rule and NOT_METERED capability change. 9817 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9818 cellNetworkCallback.expectCaps(mCellAgent, 9819 c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9820 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9821 detailedCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9822 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9823 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9824 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9825 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9826 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9827 assertExtraInfoFromCmPresent(mCellAgent); 9828 9829 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9830 cellNetworkCallback.expectCaps(mCellAgent, 9831 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9832 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9833 detailedCallback.expectCaps(mCellAgent, 9834 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9835 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9836 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9837 assertNull(mCm.getActiveNetwork()); 9838 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9839 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9840 assertExtraInfoFromCmBlocked(mCellAgent); 9841 9842 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9843 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9844 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9845 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9846 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9847 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9848 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9849 assertExtraInfoFromCmPresent(mCellAgent); 9850 9851 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9852 cellNetworkCallback.assertNoCallback(); 9853 detailedCallback.assertNoCallback(); 9854 9855 // Restrict background data. Networking is not blocked because the network is unmetered. 9856 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9857 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9858 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9859 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9860 assertNull(mCm.getActiveNetwork()); 9861 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9862 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9863 assertExtraInfoFromCmBlocked(mCellAgent); 9864 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9865 cellNetworkCallback.assertNoCallback(); 9866 9867 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9868 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9869 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9870 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9871 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9872 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9873 assertExtraInfoFromCmPresent(mCellAgent); 9874 9875 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9876 cellNetworkCallback.assertNoCallback(); 9877 detailedCallback.assertNoCallback(); 9878 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9879 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9880 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9881 assertExtraInfoFromCmPresent(mCellAgent); 9882 9883 // Remove PERMISSION_INTERNET and disable NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION 9884 doReturn(INetd.PERMISSION_NONE).when(mBpfNetMaps).getNetPermForUid(Process.myUid()); 9885 mDeps.setChangeIdEnabled(false, 9886 NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, Process.myUid()); 9887 9888 setBlockedReasonChanged(BLOCKED_REASON_DOZE); 9889 if (mDeps.isAtLeastV()) { 9890 // On V+, network access from app that does not have INTERNET permission is considered 9891 // not blocked if NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION is disabled. 9892 // So blocked status does not change from BLOCKED_REASON_NONE 9893 cellNetworkCallback.assertNoCallback(); 9894 detailedCallback.assertNoCallback(); 9895 } else { 9896 // On U-, onBlockedStatusChanged callback is called with blocked reasons CS receives 9897 // from NPMS callback regardless of permission app has. 9898 // Note that this cannot actually happen because on U-, NPMS will never notify any 9899 // blocked reasons for apps that don't have the INTERNET permission. 9900 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9901 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9902 cb -> cb.getReason() == BLOCKED_REASON_DOZE); 9903 } 9904 9905 mCm.unregisterNetworkCallback(cellNetworkCallback); 9906 } 9907 9908 @Test 9909 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 9910 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9911 mCm.registerDefaultNetworkCallback(defaultCallback); 9912 mockUidNetworkingBlocked(); 9913 9914 // No Networkcallbacks invoked before any network is active. 9915 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9916 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9917 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9918 defaultCallback.assertNoCallback(); 9919 9920 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9921 mCellAgent.connect(true); 9922 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 9923 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9924 9925 // Allow to use the network after switching to NOT_METERED network. 9926 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9927 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9928 mWiFiAgent.connect(true); 9929 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 9930 9931 // Switch to METERED network. Restrict the use of the network. 9932 mWiFiAgent.disconnect(); 9933 defaultCallback.expect(LOST, mWiFiAgent); 9934 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellAgent); 9935 9936 // Network becomes NOT_METERED. 9937 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9938 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9939 defaultCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9940 9941 // Verify there's no Networkcallbacks invoked after data saver on/off. 9942 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9943 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9944 defaultCallback.assertNoCallback(); 9945 9946 mCellAgent.disconnect(); 9947 defaultCallback.expect(LOST, mCellAgent); 9948 defaultCallback.assertNoCallback(); 9949 9950 mCm.unregisterNetworkCallback(defaultCallback); 9951 } 9952 9953 private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, 9954 UidRangeParcel... expected) throws Exception { 9955 inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); 9956 } 9957 9958 private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { 9959 assertNotNull(ni); 9960 assertEquals(type, ni.getType()); 9961 assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); 9962 if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { 9963 assertNotNull(ni.getExtraInfo()); 9964 } else { 9965 // Technically speaking, a network that's in CONNECTING state will generally have a 9966 // non-null extraInfo. This doesn't actually happen in this test because it never calls 9967 // a legacy API while a network is connecting. When a network is in CONNECTING state 9968 // because of legacy lockdown VPN, its extraInfo is always null. 9969 assertNull(ni.getExtraInfo()); 9970 } 9971 } 9972 9973 private void assertActiveNetworkInfo(int type, DetailedState state) { 9974 checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); 9975 } 9976 private void assertNetworkInfo(int type, DetailedState state) { 9977 checkNetworkInfo(mCm.getNetworkInfo(type), type, state); 9978 } 9979 9980 private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { 9981 final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); 9982 final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); 9983 if (present) { 9984 assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); 9985 assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); 9986 } else { 9987 assertNull(niForNetwork.getExtraInfo()); 9988 assertNull(niForType.getExtraInfo()); 9989 } 9990 } 9991 9992 private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { 9993 assertExtraInfoFromCm(network, false); 9994 } 9995 9996 private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { 9997 assertExtraInfoFromCm(network, true); 9998 } 9999 10000 // Checks that each of the |agents| receive a blocked status change callback with the specified 10001 // |blocked| value, in any order. This is needed because when an event affects multiple 10002 // networks, ConnectivityService does not guarantee the order in which callbacks are fired. 10003 private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, 10004 TestNetworkAgentWrapper... agents) { 10005 final List<Network> expectedNetworks = asList(agents).stream() 10006 .map((agent) -> agent.getNetwork()) 10007 .collect(Collectors.toList()); 10008 10009 // Expect exactly one blocked callback for each agent. 10010 for (int i = 0; i < agents.length; i++) { 10011 final CallbackEntry e = callback.expect(BLOCKED_STATUS, TIMEOUT_MS, 10012 c -> c.getBlocked() == blocked); 10013 final Network network = e.getNetwork(); 10014 assertTrue("Received unexpected blocked callback for network " + network, 10015 expectedNetworks.remove(network)); 10016 } 10017 } 10018 10019 @Test 10020 public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { 10021 mServiceContext.setPermission( 10022 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 10023 mServiceContext.setPermission( 10024 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 10025 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10026 10027 final TestNetworkCallback callback = new TestNetworkCallback(); 10028 final NetworkRequest request = new NetworkRequest.Builder() 10029 .removeCapability(NET_CAPABILITY_NOT_VPN) 10030 .build(); 10031 mCm.registerNetworkCallback(request, callback); 10032 10033 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10034 mCm.registerDefaultNetworkCallback(defaultCallback); 10035 10036 final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); 10037 final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); 10038 registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); 10039 10040 final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); 10041 registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); 10042 10043 final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); 10044 mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, 10045 new Handler(ConnectivityThread.getInstanceLooper())); 10046 10047 final int uid = Process.myUid(); 10048 10049 // Enable always-on VPN lockdown, coverage in VpnTest. 10050 final List<Integer> excludedUids = new ArrayList<Integer>(); 10051 excludedUids.add(VPN_UID); 10052 if (mDeps.isAtLeastT()) { 10053 // On T onwards, the corresponding SDK sandbox UID should also be excluded 10054 excludedUids.add(toSdkSandboxUid(VPN_UID)); 10055 } 10056 10057 final List<Range<Integer>> primaryRanges = intRangesPrimaryExcludingUids(excludedUids); 10058 mCm.setRequireVpnForUids(true, primaryRanges); 10059 waitForIdle(); 10060 10061 final UidRangeParcel[] uidRangeParcels = intToUidRangeStableParcels(primaryRanges); 10062 InOrder inOrder = inOrder(mMockNetd); 10063 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 10064 10065 // Connect a network when lockdown is active, expect to see it blocked. 10066 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10067 mWiFiAgent.connect(false /* validated */); 10068 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10069 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10070 vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10071 vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10072 vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10073 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10074 assertNull(mCm.getActiveNetwork()); 10075 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10076 // Mobile is BLOCKED even though it's not actually connected. 10077 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10078 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10079 10080 // Disable lockdown, expect to see the network unblocked. 10081 mCm.setRequireVpnForUids(false, primaryRanges); 10082 waitForIdle(); 10083 callback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10084 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10085 vpnUidCallback.assertNoCallback(); 10086 vpnUidDefaultCallback.assertNoCallback(); 10087 vpnDefaultCallbackAsUid.assertNoCallback(); 10088 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcels); 10089 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10090 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10091 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10092 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10093 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10094 10095 // Add our UID to the allowlist, expect network is not blocked. Coverage in VpnTest. 10096 excludedUids.add(uid); 10097 if (mDeps.isAtLeastT()) { 10098 // On T onwards, the corresponding SDK sandbox UID should also be excluded 10099 excludedUids.add(toSdkSandboxUid(uid)); 10100 } 10101 final List<Range<Integer>> primaryRangesExcludingUid = 10102 intRangesPrimaryExcludingUids(excludedUids); 10103 mCm.setRequireVpnForUids(true, primaryRangesExcludingUid); 10104 waitForIdle(); 10105 10106 callback.assertNoCallback(); 10107 defaultCallback.assertNoCallback(); 10108 vpnUidCallback.assertNoCallback(); 10109 vpnUidDefaultCallback.assertNoCallback(); 10110 vpnDefaultCallbackAsUid.assertNoCallback(); 10111 10112 final UidRangeParcel[] uidRangeParcelsAlsoExcludingUs = 10113 intToUidRangeStableParcels(primaryRangesExcludingUid); 10114 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcelsAlsoExcludingUs); 10115 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10116 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10117 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10118 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10119 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10120 10121 // Connect a new network, expect it to be unblocked. 10122 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10123 mCellAgent.connect(false /* validated */); 10124 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 10125 defaultCallback.assertNoCallback(); 10126 vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 10127 vpnUidDefaultCallback.assertNoCallback(); 10128 vpnDefaultCallbackAsUid.assertNoCallback(); 10129 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10130 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10131 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10132 // Cellular is DISCONNECTED because it's not the default and there are no requests for it. 10133 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10134 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10135 10136 // Disable lockdown 10137 mCm.setRequireVpnForUids(false, primaryRangesExcludingUid); 10138 waitForIdle(); 10139 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcelsAlsoExcludingUs); 10140 // Remove our UID from the allowlist, and re-enable lockdown. 10141 mCm.setRequireVpnForUids(true, primaryRanges); 10142 waitForIdle(); 10143 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 10144 // Everything should now be blocked. 10145 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 10146 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 10147 vpnUidCallback.assertNoCallback(); 10148 vpnUidDefaultCallback.assertNoCallback(); 10149 vpnDefaultCallbackAsUid.assertNoCallback(); 10150 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10151 assertNull(mCm.getActiveNetwork()); 10152 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10153 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10154 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10155 10156 // Disable lockdown. Everything is unblocked. 10157 mCm.setRequireVpnForUids(false, primaryRanges); 10158 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10159 assertBlockedCallbackInAnyOrder(callback, false, mWiFiAgent, mCellAgent); 10160 vpnUidCallback.assertNoCallback(); 10161 vpnUidDefaultCallback.assertNoCallback(); 10162 vpnDefaultCallbackAsUid.assertNoCallback(); 10163 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10164 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10165 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10166 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10167 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10168 10169 // Enable lockdown and connect a VPN. The VPN is not blocked. 10170 mCm.setRequireVpnForUids(true, primaryRanges); 10171 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 10172 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 10173 vpnUidCallback.assertNoCallback(); 10174 vpnUidDefaultCallback.assertNoCallback(); 10175 vpnDefaultCallbackAsUid.assertNoCallback(); 10176 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10177 assertNull(mCm.getActiveNetwork()); 10178 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10179 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10180 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10181 10182 mMockVpn.establishForMyUid(); 10183 assertUidRangesUpdatedForMyUid(true); 10184 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10185 vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. 10186 vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID 10187 vpnDefaultCallbackAsUid.assertNoCallback(); 10188 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 10189 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10190 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10191 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10192 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10193 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10194 10195 mMockVpn.disconnect(); 10196 defaultCallback.expect(LOST, mMockVpn); 10197 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10198 vpnUidCallback.assertNoCallback(); 10199 vpnUidDefaultCallback.assertNoCallback(); 10200 vpnDefaultCallbackAsUid.assertNoCallback(); 10201 assertNull(mCm.getActiveNetwork()); 10202 10203 mCm.unregisterNetworkCallback(callback); 10204 mCm.unregisterNetworkCallback(defaultCallback); 10205 mCm.unregisterNetworkCallback(vpnUidCallback); 10206 mCm.unregisterNetworkCallback(vpnUidDefaultCallback); 10207 mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); 10208 } 10209 10210 @Test 10211 public void testVpnExcludesOwnUid() throws Exception { 10212 // required for registerDefaultNetworkCallbackForUid. 10213 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10214 10215 // Connect Wi-Fi. 10216 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10217 mWiFiAgent.connect(true /* validated */); 10218 10219 // Connect a VPN that excludes its UID from its UID ranges. 10220 final LinkProperties lp = new LinkProperties(); 10221 lp.setInterfaceName(VPN_IFNAME); 10222 final int myUid = Process.myUid(); 10223 final Set<UidRange> ranges = new ArraySet<>(); 10224 ranges.add(new UidRange(0, myUid - 1)); 10225 ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1)); 10226 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 10227 mMockVpn.establish(lp, myUid, ranges); 10228 10229 // Wait for validation before registering callbacks. 10230 waitForIdle(); 10231 10232 final int otherUid = myUid + 1; 10233 final Handler h = new Handler(ConnectivityThread.getInstanceLooper()); 10234 final TestNetworkCallback otherUidCb = new TestNetworkCallback(); 10235 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 10236 final TestNetworkCallback perUidCb = new TestNetworkCallback(); 10237 registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid); 10238 mCm.registerDefaultNetworkCallback(defaultCb, h); 10239 doAsUid(Process.SYSTEM_UID, 10240 () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h)); 10241 10242 otherUidCb.expectAvailableCallbacksValidated(mMockVpn); 10243 // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN. 10244 defaultCb.expectAvailableCallbacksValidated(mMockVpn); 10245 perUidCb.expectAvailableCallbacksValidated(mMockVpn); 10246 // getActiveNetwork is not affected by this bug. 10247 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1)); 10248 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10249 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid)); 10250 10251 doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb)); 10252 mCm.unregisterNetworkCallback(defaultCb); 10253 doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb)); 10254 } 10255 10256 private void establishLegacyLockdownVpn(Network underlying) throws Exception { 10257 // The legacy lockdown VPN only supports userId 0, and must have an underlying network. 10258 assertNotNull(underlying); 10259 mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); 10260 // The legacy lockdown VPN only supports userId 0. 10261 final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); 10262 mMockVpn.registerAgent(ranges); 10263 mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); 10264 mMockVpn.connect(true); 10265 } 10266 10267 private void doTestLockdownVpn(boolean isIkev2Vpn) 10268 throws Exception { 10269 mServiceContext.setPermission( 10270 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 10271 10272 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 10273 final TestNetworkCallback callback = new TestNetworkCallback(); 10274 mCm.registerNetworkCallback(request, callback); 10275 10276 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10277 mCm.registerDefaultNetworkCallback(defaultCallback); 10278 10279 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 10280 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 10281 new Handler(ConnectivityThread.getInstanceLooper())); 10282 10283 // Init lockdown state to simulate LockdownVpnTracker behavior. 10284 mCm.setLegacyLockdownVpnEnabled(true); 10285 final List<Range<Integer>> ranges = 10286 intRangesPrimaryExcludingUids(Collections.EMPTY_LIST /* excludedeUids */); 10287 mCm.setRequireVpnForUids(true /* requireVpn */, ranges); 10288 10289 // Bring up a network. 10290 final LinkProperties cellLp = new LinkProperties(); 10291 cellLp.setInterfaceName("rmnet0"); 10292 cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); 10293 cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); 10294 // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten 10295 // with the state of the VPN network. So expect a CONNECTING broadcast. 10296 final ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); 10297 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10298 mCellAgent.connect(false /* validated */); 10299 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10300 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10301 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10302 b.expectBroadcast(); 10303 // Simulate LockdownVpnTracker attempting to start the VPN since it received the 10304 // systemDefault callback. 10305 mMockVpn.startLegacyVpnPrivileged(isIkev2Vpn); 10306 if (isIkev2Vpn) { 10307 // setVpnDefaultForUids() releases the original network request and creates a VPN 10308 // request so LOST callback is received. 10309 defaultCallback.expect(LOST, mCellAgent); 10310 // Due to the VPN default request, getActiveNetworkInfo() gets the mNoServiceNetwork 10311 // as the network satisfier. 10312 assertNull(mCm.getActiveNetworkInfo()); 10313 } else { 10314 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10315 } 10316 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10317 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10318 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10319 assertExtraInfoFromCmBlocked(mCellAgent); 10320 10321 final ExpectedBroadcast b2 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10322 final ExpectedBroadcast b3 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 10323 establishLegacyLockdownVpn(mCellAgent.getNetwork()); 10324 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10325 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10326 systemDefaultCallback.assertNoCallback(); 10327 final NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10328 b2.expectBroadcast(); 10329 b3.expectBroadcast(); 10330 if (isIkev2Vpn) { 10331 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10332 // network satisfier which has TYPE_VPN. 10333 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10334 } else { 10335 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10336 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10337 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10338 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10339 } 10340 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10341 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 10342 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10343 assertExtraInfoFromCmPresent(mCellAgent); 10344 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 10345 assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 10346 assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); 10347 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 10348 assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); 10349 10350 // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. 10351 final LinkProperties wifiLp = new LinkProperties(); 10352 wifiLp.setInterfaceName("wlan0"); 10353 wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); 10354 wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); 10355 final NetworkCapabilities wifiNc = new NetworkCapabilities(); 10356 wifiNc.addTransportType(TRANSPORT_WIFI); 10357 wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); 10358 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); 10359 10360 final ExpectedBroadcast b4 = 10361 expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 10362 // Wifi is CONNECTING because the VPN isn't up yet. 10363 final ExpectedBroadcast b5 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); 10364 mWiFiAgent.connect(false /* validated */); 10365 // Wifi is not blocked since VPN network is still connected. 10366 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10367 defaultCallback.assertNoCallback(); 10368 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10369 b4.expectBroadcast(); 10370 b5.expectBroadcast(); 10371 10372 // Simulate LockdownVpnTracker restarting the VPN since it received the systemDefault 10373 // callback with different network. 10374 final ExpectedBroadcast b6 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10375 mMockVpn.stopVpnRunnerPrivileged(); 10376 10377 mMockVpn.startLegacyVpnPrivileged(isIkev2Vpn); 10378 // VPN network is disconnected (to restart) 10379 callback.expect(LOST, mMockVpn); 10380 defaultCallback.expect(LOST, mMockVpn); 10381 // The network preference is cleared when VPN is disconnected so it receives callbacks for 10382 // the system-wide default. 10383 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10384 if (isIkev2Vpn) { 10385 // setVpnDefaultForUids() releases the original network request and creates a VPN 10386 // request so LOST callback is received. 10387 defaultCallback.expect(LOST, mWiFiAgent); 10388 } 10389 systemDefaultCallback.assertNoCallback(); 10390 b6.expectBroadcast(); 10391 10392 // While the VPN is reconnecting on the new network, everything is blocked. 10393 if (isIkev2Vpn) { 10394 // Due to the VPN default request, getActiveNetworkInfo() gets the mNoServiceNetwork 10395 // as the network satisfier. 10396 assertNull(mCm.getActiveNetworkInfo()); 10397 } else { 10398 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10399 } 10400 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10401 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10402 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10403 assertExtraInfoFromCmBlocked(mWiFiAgent); 10404 10405 // The VPN comes up again on wifi. 10406 final ExpectedBroadcast b7 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10407 final ExpectedBroadcast b8 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 10408 establishLegacyLockdownVpn(mWiFiAgent.getNetwork()); 10409 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10410 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10411 systemDefaultCallback.assertNoCallback(); 10412 b7.expectBroadcast(); 10413 b8.expectBroadcast(); 10414 if (isIkev2Vpn) { 10415 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10416 // network satisfier which has TYPE_VPN. 10417 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10418 } else { 10419 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10420 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10421 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10422 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10423 } 10424 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10425 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10426 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10427 assertExtraInfoFromCmPresent(mWiFiAgent); 10428 final NetworkCapabilities vpnNc2 = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10429 assertTrue(vpnNc2.hasTransport(TRANSPORT_VPN)); 10430 assertTrue(vpnNc2.hasTransport(TRANSPORT_WIFI)); 10431 assertFalse(vpnNc2.hasTransport(TRANSPORT_CELLULAR)); 10432 assertTrue(vpnNc2.hasCapability(NET_CAPABILITY_NOT_METERED)); 10433 10434 // Disconnect cell. Nothing much happens since it's not the default network. 10435 mCellAgent.disconnect(); 10436 callback.expect(LOST, mCellAgent); 10437 defaultCallback.assertNoCallback(); 10438 systemDefaultCallback.assertNoCallback(); 10439 10440 if (isIkev2Vpn) { 10441 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10442 // network satisfier which has TYPE_VPN. 10443 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10444 } else { 10445 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10446 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10447 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10448 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10449 } 10450 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10451 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10452 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10453 assertExtraInfoFromCmPresent(mWiFiAgent); 10454 10455 final ExpectedBroadcast b9 = 10456 expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 10457 final ExpectedBroadcast b10 = 10458 expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10459 mWiFiAgent.disconnect(); 10460 callback.expect(LOST, mWiFiAgent); 10461 callback.expectCaps(mMockVpn, c -> !c.hasTransport(TRANSPORT_WIFI)); 10462 defaultCallback.expectCaps(mMockVpn, c -> !c.hasTransport(TRANSPORT_WIFI)); 10463 systemDefaultCallback.expect(LOST, mWiFiAgent); 10464 // TODO: There should only be one LOST callback. Since the WIFI network is underlying a VPN 10465 // network, ConnectivityService#propagateUnderlyingNetworkCapabilities() causes a rematch to 10466 // occur. Notably, this happens before setting the satisfiers of its network requests to 10467 // null. Since the satisfiers are set to null in the rematch, an extra LOST callback is 10468 // called. 10469 systemDefaultCallback.expect(LOST, mWiFiAgent); 10470 b9.expectBroadcast(); 10471 mMockVpn.stopVpnRunnerPrivileged(); 10472 callback.expect(LOST, mMockVpn); 10473 defaultCallback.expect(LOST, mMockVpn); 10474 b10.expectBroadcast(); 10475 10476 assertNoCallbacks(callback, defaultCallback, systemDefaultCallback); 10477 } 10478 10479 @Test 10480 public void testLockdownVpn_LegacyVpnRunner() throws Exception { 10481 doTestLockdownVpn(false /* isIkev2Vpn */); 10482 } 10483 10484 @Test 10485 public void testLockdownVpn_Ikev2VpnRunner() throws Exception { 10486 doTestLockdownVpn(true /* isIkev2Vpn */); 10487 } 10488 10489 @Test @IgnoreUpTo(Build.VERSION_CODES.S_V2) 10490 public void testLockdownSetFirewallUidRule() throws Exception { 10491 final List<Range<Integer>> lockdownRange = 10492 intRangesPrimaryExcludingUids(Collections.EMPTY_LIST /* excludedeUids */); 10493 // Enable Lockdown 10494 mCm.setRequireVpnForUids(true /* requireVpn */, lockdownRange); 10495 waitForIdle(); 10496 10497 // Lockdown rule is set to apps uids 10498 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(true) /* add */); 10499 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, true /* add */); 10500 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, true /* add */); 10501 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, true /* add */); 10502 10503 reset(mBpfNetMaps); 10504 10505 // Disable lockdown 10506 mCm.setRequireVpnForUids(false /* requireVPN */, lockdownRange); 10507 waitForIdle(); 10508 10509 // Lockdown rule is removed from apps uids 10510 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(false) /* add */); 10511 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, false /* add */); 10512 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, false /* add */); 10513 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, false /* add */); 10514 10515 // Interface rules are not changed by Lockdown mode enable/disable 10516 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 10517 verify(mBpfNetMaps, never()).removeUidInterfaceRules(any()); 10518 } 10519 10520 private void doTestSetUidFirewallRule(final int chain, final int defaultRule) { 10521 final int uid = 1001; 10522 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 10523 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_ALLOW); 10524 reset(mBpfNetMaps); 10525 10526 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DENY); 10527 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_DENY); 10528 reset(mBpfNetMaps); 10529 10530 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 10531 verify(mBpfNetMaps).setUidRule(chain, uid, defaultRule); 10532 reset(mBpfNetMaps); 10533 } 10534 10535 @Test @IgnoreUpTo(SC_V2) 10536 public void testSetUidFirewallRule() throws Exception { 10537 doTestSetUidFirewallRule(FIREWALL_CHAIN_DOZABLE, FIREWALL_RULE_DENY); 10538 doTestSetUidFirewallRule(FIREWALL_CHAIN_STANDBY, FIREWALL_RULE_ALLOW); 10539 doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); 10540 doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); 10541 doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); 10542 if (SdkLevel.isAtLeastV()) { 10543 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10544 doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY); 10545 } 10546 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); 10547 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); 10548 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); 10549 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, FIREWALL_RULE_DENY); 10550 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, FIREWALL_RULE_ALLOW); 10551 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, FIREWALL_RULE_ALLOW); 10552 } 10553 10554 @Test @IgnoreUpTo(SC_V2) 10555 public void testSetFirewallChainEnabled() throws Exception { 10556 final List<Integer> firewallChains = new ArrayList<>(Arrays.asList( 10557 FIREWALL_CHAIN_DOZABLE, 10558 FIREWALL_CHAIN_STANDBY, 10559 FIREWALL_CHAIN_POWERSAVE, 10560 FIREWALL_CHAIN_RESTRICTED, 10561 FIREWALL_CHAIN_LOW_POWER_STANDBY, 10562 FIREWALL_CHAIN_OEM_DENY_1, 10563 FIREWALL_CHAIN_OEM_DENY_2, 10564 FIREWALL_CHAIN_OEM_DENY_3)); 10565 if (SdkLevel.isAtLeastV()) { 10566 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10567 firewallChains.add(FIREWALL_CHAIN_BACKGROUND); 10568 } 10569 for (final int chain: firewallChains) { 10570 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10571 verify(mBpfNetMaps).setChildChain(chain, true /* enable */); 10572 reset(mBpfNetMaps); 10573 10574 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10575 verify(mBpfNetMaps).setChildChain(chain, false /* enable */); 10576 reset(mBpfNetMaps); 10577 } 10578 } 10579 10580 private void doTestSetFirewallChainEnabledCloseSocket(final int chain, 10581 final boolean isAllowList) throws Exception { 10582 reset(mDestroySocketsWrapper); 10583 10584 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10585 final Set<Integer> uids = 10586 new ArraySet<>(List.of(TEST_PACKAGE_UID, TEST_PACKAGE_UID2)); 10587 if (isAllowList) { 10588 final Set<Range<Integer>> range = new ArraySet<>( 10589 List.of(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE))); 10590 verify(mDestroySocketsWrapper).destroyLiveTcpSockets(range, uids); 10591 } else { 10592 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids(uids); 10593 } 10594 10595 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10596 verifyNoMoreInteractions(mDestroySocketsWrapper); 10597 } 10598 10599 @Test @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 10600 public void testSetFirewallChainEnabledCloseSocket() throws Exception { 10601 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10602 .when(mBpfNetMaps) 10603 .getUidsWithDenyRuleOnDenyListChain(anyInt()); 10604 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10605 .when(mBpfNetMaps) 10606 .getUidsWithAllowRuleOnAllowListChain(anyInt()); 10607 10608 final boolean allowlist = true; 10609 final boolean denylist = false; 10610 10611 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_DOZABLE, allowlist); 10612 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist); 10613 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist); 10614 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist); 10615 if (SdkLevel.isAtLeastV()) { 10616 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10617 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist); 10618 } 10619 10620 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist); 10621 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist); 10622 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_2, denylist); 10623 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_3, denylist); 10624 } 10625 10626 private void doTestReplaceFirewallChain(final int chain) { 10627 final int[] uids = new int[] {1001, 1002}; 10628 mCm.replaceFirewallChain(chain, uids); 10629 verify(mBpfNetMaps).replaceUidChain(chain, uids); 10630 reset(mBpfNetMaps); 10631 } 10632 10633 @Test @IgnoreUpTo(SC_V2) 10634 public void testReplaceFirewallChain() { 10635 doTestReplaceFirewallChain(FIREWALL_CHAIN_DOZABLE); 10636 doTestReplaceFirewallChain(FIREWALL_CHAIN_STANDBY); 10637 doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE); 10638 doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED); 10639 doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); 10640 if (SdkLevel.isAtLeastV()) { 10641 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10642 doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND); 10643 } 10644 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1); 10645 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2); 10646 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3); 10647 } 10648 10649 @Test @IgnoreUpTo(SC_V2) 10650 public void testInvalidFirewallChain() throws Exception { 10651 final int uid = 1001; 10652 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10653 assertThrows(expected, 10654 () -> mCm.setUidFirewallRule(-1 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10655 assertThrows(expected, 10656 () -> mCm.setUidFirewallRule(100 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10657 } 10658 10659 @Test @IgnoreUpTo(SC_V2) 10660 public void testInvalidFirewallRule() throws Exception { 10661 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10662 assertThrows(expected, 10663 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10664 1001 /* uid */, -1 /* rule */)); 10665 assertThrows(expected, 10666 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10667 1001 /* uid */, 100 /* rule */)); 10668 } 10669 10670 /** 10671 * Test mutable and requestable network capabilities such as 10672 * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and 10673 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the 10674 * {@code ConnectivityService} re-assign the networks accordingly. 10675 */ 10676 @Test 10677 public final void testLoseMutableAndRequestableCaps() throws Exception { 10678 final int[] testCaps = new int [] { 10679 NET_CAPABILITY_TRUSTED, 10680 NET_CAPABILITY_NOT_VCN_MANAGED 10681 }; 10682 for (final int testCap : testCaps) { 10683 // Create requests with and without the testing capability. 10684 final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); 10685 final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); 10686 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), 10687 callbackWithCap); 10688 mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), 10689 callbackWithoutCap); 10690 10691 // Setup networks with testing capability and verify the default network changes. 10692 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10693 mCellAgent.addCapability(testCap); 10694 mCellAgent.connect(true); 10695 callbackWithCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10696 callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10697 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10698 reset(mMockNetd); 10699 10700 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10701 mWiFiAgent.addCapability(testCap); 10702 mWiFiAgent.connect(true); 10703 callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10704 callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10705 verify(mMockNetd).networkSetDefault(eq(mWiFiAgent.getNetwork().netId)); 10706 reset(mMockNetd); 10707 10708 // Remove the testing capability on wifi, verify the callback and default network 10709 // changes back to cellular. 10710 mWiFiAgent.removeCapability(testCap); 10711 callbackWithCap.expectAvailableCallbacksValidated(mCellAgent); 10712 callbackWithoutCap.expectCaps(mWiFiAgent, c -> !c.hasCapability(testCap)); 10713 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10714 reset(mMockNetd); 10715 10716 mCellAgent.removeCapability(testCap); 10717 callbackWithCap.expect(LOST, mCellAgent); 10718 callbackWithoutCap.assertNoCallback(); 10719 verify(mMockNetd).networkClearDefault(); 10720 10721 mCm.unregisterNetworkCallback(callbackWithCap); 10722 mCm.unregisterNetworkCallback(callbackWithoutCap); 10723 } 10724 } 10725 10726 @Test 10727 public final void testBatteryStatsNetworkType() throws Exception { 10728 final LinkProperties cellLp = new LinkProperties(); 10729 cellLp.setInterfaceName("cell0"); 10730 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10731 mCellAgent.connect(true); 10732 waitForIdle(); 10733 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10734 mDeps.mReportedInterfaceHistory.newReadHead(); 10735 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10736 cellLp.getInterfaceName(), 10737 new int[] { TRANSPORT_CELLULAR }))); 10738 10739 final LinkProperties wifiLp = new LinkProperties(); 10740 wifiLp.setInterfaceName("wifi0"); 10741 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 10742 mWiFiAgent.connect(true); 10743 waitForIdle(); 10744 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10745 wifiLp.getInterfaceName(), 10746 new int[] { TRANSPORT_WIFI }))); 10747 10748 mCellAgent.disconnect(); 10749 mWiFiAgent.disconnect(); 10750 10751 cellLp.setInterfaceName("wifi0"); 10752 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10753 mCellAgent.connect(true); 10754 waitForIdle(); 10755 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10756 cellLp.getInterfaceName(), 10757 new int[] { TRANSPORT_CELLULAR }))); 10758 mCellAgent.disconnect(); 10759 } 10760 10761 /** 10762 * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. 10763 */ 10764 private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { 10765 final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); 10766 cfg.hwAddr = "11:22:33:44:55:66"; 10767 cfg.ipv4Addr = la.getAddress().getHostAddress(); 10768 cfg.prefixLength = la.getPrefixLength(); 10769 return cfg; 10770 } 10771 10772 /** 10773 * Make expected stack link properties, copied from Nat464Xlat. 10774 */ 10775 private LinkProperties makeClatLinkProperties(LinkAddress la) { 10776 LinkAddress clatAddress = la; 10777 LinkProperties stacked = new LinkProperties(); 10778 stacked.setInterfaceName(CLAT_MOBILE_IFNAME); 10779 RouteInfo ipv4Default = new RouteInfo( 10780 new LinkAddress(Inet4Address.ANY, 0), 10781 clatAddress.getAddress(), CLAT_MOBILE_IFNAME); 10782 stacked.addRoute(ipv4Default); 10783 stacked.addLinkAddress(clatAddress); 10784 return stacked; 10785 } 10786 10787 private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, 10788 final String prefixAddress, final int prefixLength) { 10789 final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); 10790 event.netId = netId; 10791 event.prefixOperation = prefixOperation; 10792 event.prefixAddress = prefixAddress; 10793 event.prefixLength = prefixLength; 10794 return event; 10795 } 10796 10797 private void verifyWakeupModifyInterface(String iface, boolean add) throws RemoteException { 10798 if (add) { 10799 verify(mMockNetd).wakeupAddInterface(eq(iface), anyString(), anyInt(), 10800 anyInt()); 10801 } else { 10802 verify(mMockNetd).wakeupDelInterface(eq(iface), anyString(), anyInt(), 10803 anyInt()); 10804 } 10805 } 10806 10807 private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10808 if (inOrder != null) { 10809 return inOrder.verify(t); 10810 } else { 10811 // times(1) for consistency with the above. InOrder#verify always implies times(1). 10812 return verify(t, times(1)); 10813 } 10814 } 10815 10816 private <T> T verifyNeverWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10817 if (inOrder != null) { 10818 return inOrder.verify(t, never()); 10819 } else { 10820 return verify(t, never()); 10821 } 10822 } 10823 10824 private void verifyClatdStart(@Nullable InOrder inOrder, @NonNull String iface, int netId, 10825 @NonNull String nat64Prefix) throws Exception { 10826 if (mDeps.isAtLeastT()) { 10827 verifyWithOrder(inOrder, mClatCoordinator) 10828 .clatStart(eq(iface), eq(netId), eq(new IpPrefix(nat64Prefix))); 10829 } else { 10830 verifyWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), eq(nat64Prefix)); 10831 } 10832 } 10833 10834 private void verifyNeverClatdStart(@Nullable InOrder inOrder, @NonNull String iface) 10835 throws Exception { 10836 if (mDeps.isAtLeastT()) { 10837 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStart(eq(iface), anyInt(), any()); 10838 } else { 10839 verifyNeverWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), anyString()); 10840 } 10841 } 10842 10843 private void verifyClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10844 throws Exception { 10845 if (mDeps.isAtLeastT()) { 10846 verifyWithOrder(inOrder, mClatCoordinator).clatStop(); 10847 } else { 10848 verifyWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10849 } 10850 } 10851 10852 private void verifyNeverClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10853 throws Exception { 10854 if (mDeps.isAtLeastT()) { 10855 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStop(); 10856 } else { 10857 verifyNeverWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10858 } 10859 } 10860 10861 private void expectNativeNetworkCreated(int netId, int permission, String iface, 10862 InOrder inOrder) throws Exception { 10863 verifyWithOrder(inOrder, mMockNetd).networkCreate(nativeNetworkConfigPhysical(netId, 10864 permission)); 10865 verifyWithOrder(inOrder, mMockDnsResolver).createNetworkCache(eq(netId)); 10866 if (iface != null) { 10867 verifyWithOrder(inOrder, mMockNetd).networkAddInterface(netId, iface); 10868 } 10869 } 10870 10871 private void expectNativeNetworkCreated(int netId, int permission, String iface) 10872 throws Exception { 10873 expectNativeNetworkCreated(netId, permission, iface, null /* inOrder */); 10874 } 10875 10876 private int getIdleTimerLabel(int netId, int transportType) { 10877 return ConnectivityService.LegacyNetworkActivityTracker.getIdleTimerLabel( 10878 mDeps.isAtLeastV(), netId, transportType); 10879 } 10880 10881 @Test 10882 public void testStackedLinkProperties() throws Exception { 10883 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 10884 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 10885 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 10886 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 10887 final String kOtherNat64PrefixString = "64:ff9b::"; 10888 final IpPrefix kOtherNat64Prefix = new IpPrefix( 10889 InetAddress.getByName(kOtherNat64PrefixString), 96); 10890 final RouteInfo ipv6Default = 10891 new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME); 10892 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 10893 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 10894 final RouteInfo stackedDefault = 10895 new RouteInfo((IpPrefix) null, myIpv4.getAddress(), CLAT_MOBILE_IFNAME); 10896 final BaseNetdUnsolicitedEventListener netdUnsolicitedListener = 10897 getRegisteredNetdUnsolicitedEventListener(); 10898 10899 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10900 .addTransportType(TRANSPORT_CELLULAR) 10901 .addCapability(NET_CAPABILITY_INTERNET) 10902 .build(); 10903 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10904 mCm.registerNetworkCallback(networkRequest, networkCallback); 10905 10906 // Prepare ipv6 only link properties. 10907 final LinkProperties cellLp = new LinkProperties(); 10908 cellLp.setInterfaceName(MOBILE_IFNAME); 10909 cellLp.addLinkAddress(myIpv6); 10910 cellLp.addRoute(ipv6Default); 10911 cellLp.addRoute(ipv6Subnet); 10912 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10913 reset(mClatCoordinator); 10914 10915 // Connect with ipv6 link properties. Expect prefix discovery to be started. 10916 mCellAgent.connect(true); 10917 int cellNetId = mCellAgent.getNetwork().netId; 10918 waitForIdle(); 10919 10920 expectNativeNetworkCreated(cellNetId, INetd.PERMISSION_NONE, MOBILE_IFNAME); 10921 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 10922 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10923 mDeps.mReportedInterfaceHistory.newReadHead(); 10924 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10925 cellLp.getInterfaceName(), 10926 new int[] { TRANSPORT_CELLULAR }))); 10927 10928 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 10929 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10930 10931 // Switching default network updates TCP buffer sizes. 10932 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 10933 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 10934 // the NAT64 prefix was removed because one was never discovered. 10935 cellLp.addLinkAddress(myIpv4); 10936 mCellAgent.sendLinkProperties(cellLp); 10937 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10938 assertRoutesAdded(cellNetId, ipv4Subnet); 10939 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 10940 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 10941 10942 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 10943 // come online yet. 10944 waitForIdle(); 10945 assertNull(readHead.poll(0 /* timeout */, ri -> mServiceContext.equals(ri.context) 10946 && ri.iface != null && ri.iface.startsWith("v4-"))); 10947 10948 verifyNoMoreInteractions(mMockNetd); 10949 verifyNoMoreInteractions(mClatCoordinator); 10950 verifyNoMoreInteractions(mMockDnsResolver); 10951 reset(mMockNetd); 10952 reset(mClatCoordinator); 10953 reset(mMockDnsResolver); 10954 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10955 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10956 10957 // Remove IPv4 address. Expect prefix discovery to be started again. 10958 cellLp.removeLinkAddress(myIpv4); 10959 mCellAgent.sendLinkProperties(cellLp); 10960 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10961 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10962 assertRoutesRemoved(cellNetId, ipv4Subnet); 10963 10964 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 10965 assertNull(mCm.getLinkProperties(mCellAgent.getNetwork()).getNat64Prefix()); 10966 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10967 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 10968 LinkProperties lpBeforeClat = networkCallback.expect( 10969 LINK_PROPERTIES_CHANGED, mCellAgent).getLp(); 10970 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 10971 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 10972 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10973 10974 // Clat iface comes up. Expect stacked link to be added. 10975 netdUnsolicitedListener.onInterfaceLinkStateChanged( 10976 CLAT_MOBILE_IFNAME, true); 10977 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10978 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellAgent.getNetwork()) 10979 .getStackedLinks(); 10980 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 10981 assertRoutesAdded(cellNetId, stackedDefault); 10982 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10983 // Change trivial linkproperties and see if stacked link is preserved. 10984 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 10985 mCellAgent.sendLinkProperties(cellLp); 10986 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10987 10988 List<LinkProperties> stackedLpsAfterChange = 10989 mCm.getLinkProperties(mCellAgent.getNetwork()).getStackedLinks(); 10990 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 10991 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 10992 10993 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 10994 mResolverParamsParcelCaptor.capture()); 10995 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 10996 assertEquals(1, resolvrParams.servers.length); 10997 assertTrue(CollectionUtils.contains(resolvrParams.servers, "8.8.8.8")); 10998 10999 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 11000 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 11001 stackedLp.getInterfaceName(), 11002 new int[] { TRANSPORT_CELLULAR }))); 11003 } 11004 reset(mMockNetd); 11005 reset(mClatCoordinator); 11006 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11007 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11008 // Change the NAT64 prefix without first removing it. 11009 // Expect clatd to be stopped and started with the new prefix. 11010 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11011 cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); 11012 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11013 cb -> cb.getLp().getStackedLinks().size() == 0); 11014 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11015 assertRoutesRemoved(cellNetId, stackedDefault); 11016 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11017 11018 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, 11019 kOtherNat64Prefix.toString()); 11020 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11021 cb -> cb.getLp().getNat64Prefix().equals(kOtherNat64Prefix)); 11022 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 11023 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11024 cb -> cb.getLp().getStackedLinks().size() == 1); 11025 assertRoutesAdded(cellNetId, stackedDefault); 11026 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11027 reset(mMockNetd); 11028 reset(mClatCoordinator); 11029 11030 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 11031 // linkproperties are cleaned up. 11032 cellLp.addLinkAddress(myIpv4); 11033 cellLp.addRoute(ipv4Subnet); 11034 mCellAgent.sendLinkProperties(cellLp); 11035 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11036 assertRoutesAdded(cellNetId, ipv4Subnet); 11037 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11038 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 11039 11040 // As soon as stop is called, the linkproperties lose the stacked interface. 11041 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11042 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellAgent.getNetwork()); 11043 LinkProperties expected = new LinkProperties(cellLp); 11044 expected.setNat64Prefix(kOtherNat64Prefix); 11045 assertEquals(expected, actualLpAfterIpv4); 11046 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 11047 assertRoutesRemoved(cellNetId, stackedDefault); 11048 11049 // The interface removed callback happens but has no effect after stop is called. 11050 netdUnsolicitedListener.onInterfaceRemoved(CLAT_MOBILE_IFNAME); 11051 networkCallback.assertNoCallback(); 11052 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11053 11054 if (mDeps.isAtLeastU()) { 11055 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11056 } 11057 11058 verifyNoMoreInteractions(mMockNetd); 11059 verifyNoMoreInteractions(mClatCoordinator); 11060 verifyNoMoreInteractions(mMockDnsResolver); 11061 reset(mMockNetd); 11062 reset(mClatCoordinator); 11063 reset(mMockDnsResolver); 11064 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11065 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11066 11067 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 11068 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11069 cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); 11070 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11071 cb -> cb.getLp().getNat64Prefix() == null); 11072 11073 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 11074 cellLp.removeLinkAddress(myIpv4); 11075 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 11076 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 11077 mCellAgent.sendLinkProperties(cellLp); 11078 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11079 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 11080 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 11081 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11082 cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 11083 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11084 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 11085 11086 // Clat iface comes up. Expect stacked link to be added. 11087 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 11088 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11089 cb -> cb.getLp().getStackedLinks().size() == 1 11090 && cb.getLp().getNat64Prefix() != null); 11091 assertRoutesAdded(cellNetId, stackedDefault); 11092 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11093 11094 if (mDeps.isAtLeastU()) { 11095 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, true); 11096 } 11097 11098 // NAT64 prefix is removed. Expect that clat is stopped. 11099 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11100 cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); 11101 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11102 cb -> cb.getLp().getStackedLinks().size() == 0 11103 && cb.getLp().getNat64Prefix() == null); 11104 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 11105 11106 // Stop has no effect because clat is already stopped. 11107 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11108 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11109 cb -> cb.getLp().getStackedLinks().size() == 0); 11110 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11111 verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME); 11112 11113 if (mDeps.isAtLeastU()) { 11114 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11115 } 11116 11117 // Clean up. 11118 mCellAgent.disconnect(); 11119 networkCallback.expect(LOST, mCellAgent); 11120 networkCallback.assertNoCallback(); 11121 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11122 eq(Integer.toString(getIdleTimerLabel(cellNetId, TRANSPORT_CELLULAR)))); 11123 verify(mMockNetd).networkDestroy(cellNetId); 11124 if (mDeps.isAtLeastU()) { 11125 verify(mMockNetd).setNetworkAllowlist(any()); 11126 } else { 11127 verify(mMockNetd, never()).setNetworkAllowlist(any()); 11128 } 11129 11130 if (mDeps.isAtLeastU()) { 11131 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 11132 } 11133 11134 verifyNoMoreInteractions(mMockNetd); 11135 verifyNoMoreInteractions(mClatCoordinator); 11136 reset(mMockNetd); 11137 reset(mClatCoordinator); 11138 11139 // Test disconnecting a network that is running 464xlat. 11140 11141 // Connect a network with a NAT64 prefix. 11142 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11143 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11144 cellLp.setNat64Prefix(kNat64Prefix); 11145 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 11146 mCellAgent.connect(false /* validated */); 11147 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 11148 cellNetId = mCellAgent.getNetwork().netId; 11149 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 11150 INetd.PERMISSION_NONE)); 11151 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 11152 11153 // Clatd is started and clat iface comes up. Expect stacked link to be added. 11154 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 11155 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true /* up */); 11156 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11157 cb -> cb.getLp().getStackedLinks().size() == 1 11158 && cb.getLp().getNat64Prefix().equals(kNat64Prefix)); 11159 verify(mMockNetd).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11160 // assertRoutesAdded sees all calls since last mMockNetd reset, so expect IPv6 routes again. 11161 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default, stackedDefault); 11162 11163 if (mDeps.isAtLeastU()) { 11164 verifyWakeupModifyInterface(MOBILE_IFNAME, true); 11165 } 11166 11167 reset(mMockNetd); 11168 reset(mClatCoordinator); 11169 11170 // Disconnect the network. clat is stopped and the network is destroyed. 11171 mCellAgent.disconnect(); 11172 networkCallback.expect(LOST, mCellAgent); 11173 networkCallback.assertNoCallback(); 11174 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11175 11176 if (mDeps.isAtLeastU()) { 11177 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11178 } 11179 11180 verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11181 eq(Integer.toString(getIdleTimerLabel(cellNetId, TRANSPORT_CELLULAR)))); 11182 verify(mMockNetd).networkDestroy(cellNetId); 11183 if (mDeps.isAtLeastU()) { 11184 verify(mMockNetd).setNetworkAllowlist(any()); 11185 } else { 11186 verify(mMockNetd, never()).setNetworkAllowlist(any()); 11187 } 11188 11189 if (mDeps.isAtLeastU()) { 11190 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 11191 } 11192 11193 verifyNoMoreInteractions(mMockNetd); 11194 verifyNoMoreInteractions(mClatCoordinator); 11195 11196 mCm.unregisterNetworkCallback(networkCallback); 11197 } 11198 11199 private void expectNat64PrefixChange(TestNetworkCallback callback, 11200 TestNetworkAgentWrapper agent, IpPrefix prefix) { 11201 callback.expect(LINK_PROPERTIES_CHANGED, agent, 11202 x -> Objects.equals(x.getLp().getNat64Prefix(), prefix)); 11203 } 11204 11205 @Test 11206 public void testNat64PrefixMultipleSources() throws Exception { 11207 final String iface = "wlan0"; 11208 final String pref64FromRaStr = "64:ff9b::"; 11209 final String pref64FromDnsStr = "2001:db8:64::"; 11210 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 11211 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 11212 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 11213 11214 final NetworkRequest request = new NetworkRequest.Builder() 11215 .addCapability(NET_CAPABILITY_INTERNET) 11216 .build(); 11217 final TestNetworkCallback callback = new TestNetworkCallback(); 11218 mCm.registerNetworkCallback(request, callback); 11219 11220 final LinkProperties baseLp = new LinkProperties(); 11221 baseLp.setInterfaceName(iface); 11222 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11223 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 11224 11225 reset(mMockNetd, mMockDnsResolver); 11226 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver, mClatCoordinator); 11227 11228 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 11229 // prefix discovery is never started. 11230 LinkProperties lp = new LinkProperties(baseLp); 11231 lp.setNat64Prefix(pref64FromRa); 11232 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 11233 mWiFiAgent.connect(false); 11234 final Network network = mWiFiAgent.getNetwork(); 11235 int netId = network.getNetId(); 11236 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11237 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11238 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11239 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11240 callback.assertNoCallback(); 11241 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11242 11243 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 11244 lp.setNat64Prefix(null); 11245 mWiFiAgent.sendLinkProperties(lp); 11246 expectNat64PrefixChange(callback, mWiFiAgent, null); 11247 verifyClatdStop(inOrder, iface); 11248 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11249 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11250 11251 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 11252 // clatd is started with the prefix from the RA. 11253 lp.setNat64Prefix(pref64FromRa); 11254 mWiFiAgent.sendLinkProperties(lp); 11255 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11256 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11257 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11258 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11259 11260 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 11261 // discovery has succeeded. 11262 lp.setNat64Prefix(null); 11263 mWiFiAgent.sendLinkProperties(lp); 11264 expectNat64PrefixChange(callback, mWiFiAgent, null); 11265 verifyClatdStop(inOrder, iface); 11266 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11267 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11268 11269 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11270 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11271 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11272 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11273 11274 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 11275 // discovery is not stopped, and there are no callbacks. 11276 lp.setNat64Prefix(pref64FromDns); 11277 mWiFiAgent.sendLinkProperties(lp); 11278 callback.assertNoCallback(); 11279 verifyNeverClatdStop(inOrder, iface); 11280 verifyNeverClatdStart(inOrder, iface); 11281 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11282 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11283 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11284 11285 // If the RA is later withdrawn, nothing happens again. 11286 lp.setNat64Prefix(null); 11287 mWiFiAgent.sendLinkProperties(lp); 11288 callback.assertNoCallback(); 11289 verifyNeverClatdStop(inOrder, iface); 11290 verifyNeverClatdStart(inOrder, iface); 11291 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11292 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11293 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11294 11295 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 11296 lp.setNat64Prefix(pref64FromRa); 11297 mWiFiAgent.sendLinkProperties(lp); 11298 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11299 verifyClatdStop(inOrder, iface); 11300 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11301 11302 // Stopping prefix discovery results in a prefix removed notification. 11303 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11304 makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); 11305 11306 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11307 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11308 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11309 11310 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 11311 lp.setNat64Prefix(newPref64FromRa); 11312 mWiFiAgent.sendLinkProperties(lp); 11313 expectNat64PrefixChange(callback, mWiFiAgent, newPref64FromRa); 11314 verifyClatdStop(inOrder, iface); 11315 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11316 verifyClatdStart(inOrder, iface, netId, newPref64FromRa.toString()); 11317 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 11318 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11319 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11320 11321 // If the RA prefix changes to the same value, nothing happens. 11322 lp.setNat64Prefix(newPref64FromRa); 11323 mWiFiAgent.sendLinkProperties(lp); 11324 callback.assertNoCallback(); 11325 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11326 verifyNeverClatdStop(inOrder, iface); 11327 verifyNeverClatdStart(inOrder, iface); 11328 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11329 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11330 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11331 11332 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 11333 11334 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 11335 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 11336 lp.setNat64Prefix(null); 11337 mWiFiAgent.sendLinkProperties(lp); 11338 expectNat64PrefixChange(callback, mWiFiAgent, null); 11339 verifyClatdStop(inOrder, iface); 11340 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11341 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11342 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11343 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11344 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11345 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11346 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 11347 11348 lp.setNat64Prefix(pref64FromDns); 11349 mWiFiAgent.sendLinkProperties(lp); 11350 callback.assertNoCallback(); 11351 verifyNeverClatdStop(inOrder, iface); 11352 verifyNeverClatdStart(inOrder, iface); 11353 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11354 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11355 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11356 11357 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 11358 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 11359 // clat has been stopped, or the test will be flaky. 11360 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11361 mWiFiAgent.disconnect(); 11362 callback.expect(LOST, mWiFiAgent); 11363 b.expectBroadcast(); 11364 11365 verifyClatdStop(inOrder, iface); 11366 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11367 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11368 11369 mCm.unregisterNetworkCallback(callback); 11370 } 11371 11372 @Test 11373 public void testWith464XlatDisable() throws Exception { 11374 mDeps.setCellular464XlatEnabled(false); 11375 11376 final TestNetworkCallback callback = new TestNetworkCallback(); 11377 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 11378 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11379 .addCapability(NET_CAPABILITY_INTERNET) 11380 .build(); 11381 mCm.registerNetworkCallback(networkRequest, callback); 11382 mCm.registerDefaultNetworkCallback(defaultCallback); 11383 11384 // Bring up validated cell. 11385 final LinkProperties cellLp = new LinkProperties(); 11386 cellLp.setInterfaceName(MOBILE_IFNAME); 11387 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11388 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); 11389 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11390 11391 mCellAgent.sendLinkProperties(cellLp); 11392 mCellAgent.connect(true); 11393 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 11394 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11395 final int cellNetId = mCellAgent.getNetwork().netId; 11396 waitForIdle(); 11397 11398 verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); 11399 Nat464Xlat clat = getNat464Xlat(mCellAgent); 11400 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11401 11402 // This cannot happen because prefix discovery cannot succeed if it is never started. 11403 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11404 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); 11405 11406 // ... but still, check that even if it did, clatd would not be started. 11407 verify(mMockNetd, never()).clatdStart(anyString(), anyString()); 11408 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11409 } 11410 11411 final String transportToTestIfaceName(int transport) { 11412 switch (transport) { 11413 case TRANSPORT_WIFI: 11414 return WIFI_IFNAME; 11415 case TRANSPORT_CELLULAR: 11416 return MOBILE_IFNAME; 11417 case TRANSPORT_ETHERNET: 11418 return ETHERNET_IFNAME; 11419 default: 11420 throw new AssertionError("Unsupported transport type"); 11421 } 11422 } 11423 11424 private void doTestInterfaceClassActivityChanged(final int transportType) throws Exception { 11425 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 11426 getRegisteredNetdUnsolicitedEventListener(); 11427 11428 final int legacyType = transportToLegacyType(transportType); 11429 final LinkProperties lp = new LinkProperties(); 11430 lp.setInterfaceName(transportToTestIfaceName(transportType)); 11431 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 11432 11433 final ConditionVariable onNetworkActiveCv = new ConditionVariable(); 11434 final ConnectivityManager.OnNetworkActiveListener listener = onNetworkActiveCv::open; 11435 11436 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 11437 11438 testAndCleanup(() -> { 11439 mCm.registerDefaultNetworkCallback(defaultCallback); 11440 agent.connect(true); 11441 defaultCallback.expectAvailableThenValidatedCallbacks(agent); 11442 if (transportType == TRANSPORT_CELLULAR) { 11443 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_HIGH), 11444 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11445 } else if (transportType == TRANSPORT_WIFI) { 11446 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_HIGH), 11447 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11448 } 11449 clearInvocations(mIBatteryStats); 11450 final int idleTimerLabel = getIdleTimerLabel(agent.getNetwork().netId, transportType); 11451 11452 // Network is considered active when the network becomes the default network. 11453 assertTrue(mCm.isDefaultNetworkActive()); 11454 11455 mCm.addDefaultNetworkActiveListener(listener); 11456 11457 // Interface goes to inactive state 11458 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 11459 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 11460 mServiceContext.expectDataActivityBroadcast(legacyType, false /* isActive */, 11461 TIMESTAMP); 11462 assertFalse(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11463 assertFalse(mCm.isDefaultNetworkActive()); 11464 if (mDeps.isAtLeastV()) { 11465 if (transportType == TRANSPORT_CELLULAR) { 11466 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_LOW), 11467 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11468 } else if (transportType == TRANSPORT_WIFI) { 11469 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_LOW), 11470 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11471 } 11472 } else { 11473 // If TrackMultiNetworks is disabled, LegacyNetworkActivityTracker does not call 11474 // BatteryStats API by the netd activity change callback since BatteryStatsService 11475 // listen to netd callback via NetworkManagementService and update battery stats by 11476 // itself. 11477 verify(mIBatteryStats, never()) 11478 .noteMobileRadioPowerState(anyInt(), anyLong(), anyInt()); 11479 verify(mIBatteryStats, never()) 11480 .noteWifiRadioPowerState(anyInt(), anyLong(), anyInt()); 11481 } 11482 11483 // Interface goes to active state 11484 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(true /* isActive */, 11485 idleTimerLabel, TIMESTAMP, TEST_PACKAGE_UID); 11486 mServiceContext.expectDataActivityBroadcast(legacyType, true /* isActive */, TIMESTAMP); 11487 assertTrue(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11488 assertTrue(mCm.isDefaultNetworkActive()); 11489 if (mDeps.isAtLeastV()) { 11490 if (transportType == TRANSPORT_CELLULAR) { 11491 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_HIGH), 11492 anyLong() /* timestampNs */, eq(TEST_PACKAGE_UID)); 11493 } else if (transportType == TRANSPORT_WIFI) { 11494 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_HIGH), 11495 anyLong() /* timestampNs */, eq(TEST_PACKAGE_UID)); 11496 } 11497 } else { 11498 // If TrackMultiNetworks is disabled, LegacyNetworkActivityTracker does not call 11499 // BatteryStats API by the netd activity change callback since BatteryStatsService 11500 // listen to netd callback via NetworkManagementService and update battery stats by 11501 // itself. 11502 verify(mIBatteryStats, never()) 11503 .noteMobileRadioPowerState(anyInt(), anyLong(), anyInt()); 11504 verify(mIBatteryStats, never()) 11505 .noteWifiRadioPowerState(anyInt(), anyLong(), anyInt()); 11506 } 11507 }, () -> { // Cleanup 11508 mCm.unregisterNetworkCallback(defaultCallback); 11509 }, () -> { // Cleanup 11510 mCm.removeDefaultNetworkActiveListener(listener); 11511 }, () -> { // Cleanup 11512 agent.disconnect(); 11513 }); 11514 } 11515 11516 @Test 11517 public void testInterfaceClassActivityChangedWifi() throws Exception { 11518 doTestInterfaceClassActivityChanged(TRANSPORT_WIFI); 11519 } 11520 11521 @Test 11522 public void testInterfaceClassActivityChangedCellular() throws Exception { 11523 doTestInterfaceClassActivityChanged(TRANSPORT_CELLULAR); 11524 } 11525 11526 private void doTestOnNetworkActive_NewNetworkConnects(int transportType, boolean expectCapChanged) 11527 throws Exception { 11528 final ConditionVariable onNetworkActiveCv = new ConditionVariable(); 11529 final ConnectivityManager.OnNetworkActiveListener listener = onNetworkActiveCv::open; 11530 11531 final LinkProperties lp = new LinkProperties(); 11532 lp.setInterfaceName(transportToTestIfaceName(transportType)); 11533 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 11534 11535 testAndCleanup(() -> { 11536 mCm.addDefaultNetworkActiveListener(listener); 11537 agent.connect(true); 11538 if (expectCapChanged) { 11539 assertTrue(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11540 } else { 11541 assertFalse(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11542 } 11543 assertTrue(mCm.isDefaultNetworkActive()); 11544 }, () -> { // Cleanup 11545 mCm.removeDefaultNetworkActiveListener(listener); 11546 }, () -> { // Cleanup 11547 agent.disconnect(); 11548 }); 11549 } 11550 11551 @Test 11552 public void testOnNetworkActive_NewCellConnects_CallbackCalled() throws Exception { 11553 doTestOnNetworkActive_NewNetworkConnects(TRANSPORT_CELLULAR, true /* expectCapChanged */); 11554 } 11555 11556 @Test 11557 public void testOnNetworkActive_NewEthernetConnects_Callback() throws Exception { 11558 // On pre-V devices, LegacyNetworkActivityTracker calls onNetworkActive callback only for 11559 // networks that tracker adds the idle timer to. And the tracker does not set the idle timer 11560 // for the ethernet network. 11561 // So onNetworkActive is not called when the ethernet becomes the default network 11562 final boolean expectCapChanged = mDeps.isAtLeastV(); 11563 doTestOnNetworkActive_NewNetworkConnects(TRANSPORT_ETHERNET, expectCapChanged); 11564 } 11565 11566 @Test 11567 public void testIsDefaultNetworkActiveNoDefaultNetwork() throws Exception { 11568 // isDefaultNetworkActive returns true if there is no default network, which is known issue. 11569 assertTrue(mCm.isDefaultNetworkActive()); 11570 11571 final LinkProperties cellLp = new LinkProperties(); 11572 cellLp.setInterfaceName(MOBILE_IFNAME); 11573 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 11574 mCellAgent.connect(true); 11575 // Network is considered active when the network becomes the default network. 11576 assertTrue(mCm.isDefaultNetworkActive()); 11577 11578 mCellAgent.disconnect(); 11579 waitForIdle(); 11580 11581 assertTrue(mCm.isDefaultNetworkActive()); 11582 } 11583 11584 @Test 11585 public void testDataActivityTracking() throws Exception { 11586 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11587 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11588 .addCapability(NET_CAPABILITY_INTERNET) 11589 .build(); 11590 mCm.registerNetworkCallback(networkRequest, networkCallback); 11591 11592 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11593 final String cellIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11594 mCellAgent.getNetwork().netId, TRANSPORT_CELLULAR)); 11595 final LinkProperties cellLp = new LinkProperties(); 11596 cellLp.setInterfaceName(MOBILE_IFNAME); 11597 mCellAgent.sendLinkProperties(cellLp); 11598 mCellAgent.connect(true); 11599 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11600 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11601 eq(cellIdleTimerLabel)); 11602 11603 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11604 String wifiIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11605 mWiFiAgent.getNetwork().netId, TRANSPORT_WIFI)); 11606 final LinkProperties wifiLp = new LinkProperties(); 11607 wifiLp.setInterfaceName(WIFI_IFNAME); 11608 mWiFiAgent.sendLinkProperties(wifiLp); 11609 11610 // Network switch 11611 mWiFiAgent.connect(true); 11612 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11613 networkCallback.expectLosing(mCellAgent); 11614 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11615 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11616 eq(wifiIdleTimerLabel)); 11617 if (mDeps.isAtLeastV()) { 11618 // V+ devices add idleTimer when the network is first connected and remove when the 11619 // network is disconnected. 11620 verify(mMockNetd, never()).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11621 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11622 } else { 11623 // pre V devices add idleTimer when the network becomes the default network and remove 11624 // when the network becomes no longer the default network. 11625 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11626 eq(Integer.toString(TRANSPORT_CELLULAR))); 11627 } 11628 11629 // Disconnect wifi and switch back to cell 11630 reset(mMockNetd); 11631 mWiFiAgent.disconnect(); 11632 networkCallback.expect(LOST, mWiFiAgent); 11633 assertNoCallbacks(networkCallback); 11634 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11635 eq(wifiIdleTimerLabel)); 11636 if (mDeps.isAtLeastV()) { 11637 verify(mMockNetd, never()).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11638 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11639 } else { 11640 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11641 eq(Integer.toString(TRANSPORT_CELLULAR))); 11642 } 11643 11644 // reconnect wifi 11645 reset(mMockNetd); 11646 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11647 wifiIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11648 mWiFiAgent.getNetwork().netId, TRANSPORT_WIFI)); 11649 wifiLp.setInterfaceName(WIFI_IFNAME); 11650 mWiFiAgent.sendLinkProperties(wifiLp); 11651 mWiFiAgent.connect(true); 11652 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11653 networkCallback.expectLosing(mCellAgent); 11654 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11655 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11656 eq(wifiIdleTimerLabel)); 11657 if (mDeps.isAtLeastV()) { 11658 verify(mMockNetd, never()).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11659 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11660 } else { 11661 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11662 eq(Integer.toString(TRANSPORT_CELLULAR))); 11663 } 11664 11665 // Disconnect cell 11666 reset(mMockNetd); 11667 mCellAgent.disconnect(); 11668 networkCallback.expect(LOST, mCellAgent); 11669 waitForIdle(); 11670 if (mDeps.isAtLeastV()) { 11671 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11672 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11673 } else { 11674 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 11675 // sent as network being switched. Ensure rule removal for cell will not be triggered 11676 // unexpectedly before network being removed. 11677 verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11678 eq(Integer.toString(TRANSPORT_CELLULAR))); 11679 } 11680 verify(mMockNetd, times(1)).networkDestroy(eq(mCellAgent.getNetwork().netId)); 11681 verify(mMockDnsResolver, times(1)).destroyNetworkCache(eq(mCellAgent.getNetwork().netId)); 11682 11683 // Disconnect wifi 11684 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11685 mWiFiAgent.disconnect(); 11686 b.expectBroadcast(); 11687 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11688 eq(wifiIdleTimerLabel)); 11689 11690 // Clean up 11691 mCm.unregisterNetworkCallback(networkCallback); 11692 } 11693 11694 @Test 11695 public void testDataActivityTracking_VpnNetwork() throws Exception { 11696 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11697 mWiFiAgent.connect(true /* validated */); 11698 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 11699 11700 final LinkProperties lp = new LinkProperties(); 11701 lp.setInterfaceName(VPN_IFNAME); 11702 mMockVpn.establishForMyUid(lp); 11703 11704 // NetworkActivityTracker should not track the VPN network since VPN can change the 11705 // underlying network without disconnect. 11706 verify(mMockNetd, never()).idletimerAddInterface(eq(VPN_IFNAME), anyInt(), any()); 11707 } 11708 11709 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 11710 String[] values = tcpBufferSizes.split(","); 11711 String rmemValues = String.join(" ", values[0], values[1], values[2]); 11712 String wmemValues = String.join(" ", values[3], values[4], values[5]); 11713 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 11714 reset(mMockNetd); 11715 } 11716 11717 @Test 11718 public void testTcpBufferReset() throws Exception { 11719 final String testTcpBufferSizes = "1,2,3,4,5,6"; 11720 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11721 .addTransportType(TRANSPORT_CELLULAR) 11722 .addCapability(NET_CAPABILITY_INTERNET) 11723 .build(); 11724 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11725 mCm.registerNetworkCallback(networkRequest, networkCallback); 11726 11727 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11728 reset(mMockNetd); 11729 // Switching default network updates TCP buffer sizes. 11730 mCellAgent.connect(false); 11731 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 11732 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 11733 // Change link Properties should have updated tcp buffer size. 11734 LinkProperties lp = new LinkProperties(); 11735 lp.setTcpBufferSizes(testTcpBufferSizes); 11736 mCellAgent.sendLinkProperties(lp); 11737 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11738 verifyTcpBufferSizeChange(testTcpBufferSizes); 11739 // Clean up. 11740 mCellAgent.disconnect(); 11741 networkCallback.expect(LOST, mCellAgent); 11742 networkCallback.assertNoCallback(); 11743 mCm.unregisterNetworkCallback(networkCallback); 11744 } 11745 11746 @Test 11747 public void testGetGlobalProxyForNetwork() throws Exception { 11748 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11749 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11750 final Network wifiNetwork = mWiFiAgent.getNetwork(); 11751 mProxyTracker.setGlobalProxy(testProxyInfo); 11752 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 11753 } 11754 11755 @Test 11756 public void testGetProxyForActiveNetwork() throws Exception { 11757 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11758 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11759 mWiFiAgent.connect(true); 11760 waitForIdle(); 11761 assertNull(mService.getProxyForNetwork(null)); 11762 11763 final LinkProperties testLinkProperties = new LinkProperties(); 11764 testLinkProperties.setHttpProxy(testProxyInfo); 11765 11766 mWiFiAgent.sendLinkProperties(testLinkProperties); 11767 waitForIdle(); 11768 11769 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 11770 } 11771 11772 /* 11773 * Note for maintainers about how PAC proxies are implemented in Android. 11774 * 11775 * Generally, a proxy is just a hostname and a port to which requests are sent, instead of 11776 * sending them directly. Most HTTP libraries know to use this protocol, and the Java 11777 * language has properties to help handling these : 11778 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11779 * Unfortunately these properties are very old and do not take multi-networking into account. 11780 * 11781 * A PAC proxy consists of a javascript file stored on a server, and the client is expected to 11782 * download the file and interpret the javascript for each HTTP request to know where to direct 11783 * it. The device must therefore run code (namely, a javascript interpreter) to interpret the 11784 * PAC file correctly. Most HTTP libraries do not know how to do this, since they do not 11785 * embark a javascript interpreter (and it would be generally unreasonable for them to do 11786 * so). Some apps, notably browsers, do know how to do this, but they are the exception rather 11787 * than the rule. 11788 * So to support most apps, Android embarks the javascript interpreter. When a network is 11789 * configured to have a PAC proxy, Android will first set the ProxyInfo object to an object 11790 * that contains the PAC URL (to communicate that to apps that know how to use it), then 11791 * download the PAC file and start a native process which will open a server on localhost, 11792 * and uses the interpreter inside WebView to interpret the PAC file. This server takes 11793 * a little bit of time to start and will listen on a random port. When the port is known, 11794 * the framework receives a notification and it updates the ProxyInfo in LinkProperties 11795 * as well as send a broadcast to inform apps. This new ProxyInfo still contains the PAC URL, 11796 * but it also contains "localhost" as the host and the port that the server listens to as 11797 * the port. This will let HTTP libraries that don't have a javascript interpreter work, 11798 * because they'll send the requests to this server running on localhost on the correct port, 11799 * and this server will do what is appropriate with each request according to the PAC file. 11800 * 11801 * Note that at the time of this writing, Android does not support starting multiple local 11802 * PAC servers, though this would be possible in theory by just starting multiple instances 11803 * of this process running their server on different ports. As a stopgap measure, Android 11804 * keeps one local server which is always the one for the default network. If a non-default 11805 * network has a PAC proxy, it will have a LinkProperties with a port of -1, which means it 11806 * could still be used by apps that know how to use the PAC URL directly, but not by HTTP 11807 * libs that don't know how to do that. When a network with a PAC proxy becomes the default, 11808 * the local server is started. When a network without a PAC proxy becomes the default, the 11809 * local server is stopped if it is running (and the LP for the old default network should 11810 * be reset to have a port of -1). 11811 * 11812 * In principle, each network can be configured with a different proxy (typically in the 11813 * network settings for a Wi-Fi network). These end up exposed in the LinkProperties of the 11814 * relevant network. 11815 * Android also exposes ConnectivityManager#getDefaultProxy, which is simply the proxy for 11816 * the default network. This was retrofitted from a time where Android did not support multiple 11817 * concurrent networks, hence the difficult architecture. 11818 * Note that there is also a "global" proxy that can be set by the DPM. When this is set, 11819 * it overrides the proxy settings for every single network at the same time – that is, the 11820 * system behaves as if the global proxy is the configured proxy for each network. 11821 * 11822 * Generally there are four ways for apps to look up the proxy. 11823 * - Looking up the ProxyInfo in the LinkProperties for a network. 11824 * - Listening to the PROXY_CHANGED_ACTION broadcast 11825 * - Calling ConnectivityManager#getDefaultProxy, or ConnectivityManager#getProxyForNetwork 11826 * which can be used to retrieve the proxy for any given network or the default network by 11827 * passing null. 11828 * - Reading the standard JVM properties (http{s,}.proxy{Host,Port}). See the Java 11829 * distribution documentation for details on how these are supposed to work : 11830 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11831 * In Android, these are set by ActivityThread in each process in response to the broadcast. 11832 * Many apps actually use these, and it's important they work because it's part of the 11833 * Java standard, meaning they need to be set for existing Java libs to work on Android. 11834 */ 11835 @Test 11836 public void testPacProxy() throws Exception { 11837 final Uri pacUrl = Uri.parse("https://pac-url"); 11838 11839 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 11840 final NetworkRequest cellRequest = new NetworkRequest.Builder() 11841 .addTransportType(TRANSPORT_CELLULAR).build(); 11842 // Request cell to make sure it doesn't disconnect at an arbitrary point in the test, 11843 // which would make testing the callbacks on it difficult. 11844 mCm.requestNetwork(cellRequest, cellCallback); 11845 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11846 mCellAgent.connect(true); 11847 cellCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11848 11849 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 11850 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11851 .addTransportType(TRANSPORT_WIFI).build(); 11852 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 11853 11854 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11855 mWiFiAgent.connect(true); 11856 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 11857 cellCallback.assertNoCallback(); 11858 11859 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 11860 final LinkProperties testLinkProperties = new LinkProperties(); 11861 testLinkProperties.setHttpProxy(initialProxyInfo); 11862 mWiFiAgent.sendLinkProperties(testLinkProperties); 11863 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11864 cellCallback.assertNoCallback(); 11865 11866 // At first the local PAC proxy server is unstarted (see the description of what the local 11867 // server is in the comment at the top of this method). It will contain the PAC URL and a 11868 // port of -1 because it is unstarted. Check that all ways of getting that proxy info 11869 // returns the same object that was initially created. 11870 final ProxyInfo unstartedDefaultProxyInfo = mService.getProxyForNetwork(null); 11871 final ProxyInfo unstartedWifiProxyInfo = mService.getProxyForNetwork( 11872 mWiFiAgent.getNetwork()); 11873 final LinkProperties unstartedLp = 11874 mService.getLinkProperties(mWiFiAgent.getNetwork()); 11875 11876 assertEquals(initialProxyInfo, unstartedDefaultProxyInfo); 11877 assertEquals(initialProxyInfo, unstartedWifiProxyInfo); 11878 assertEquals(initialProxyInfo, unstartedLp.getHttpProxy()); 11879 11880 // Make sure the cell network is unaffected. The LP are per-network and each network has 11881 // its own configuration. The default proxy and broadcast are system-wide, and the JVM 11882 // properties are per-process, and therefore can have only one value at any given time, 11883 // so the code sets them to the proxy of the default network (TODO : really, since the 11884 // default process is per-network, the JVM properties (http.proxyHost family – see 11885 // the comment at the top of the method for details about these) also should be per-network 11886 // and even the broadcast contents should be but none of this is implemented). The LP are 11887 // still per-network, and a process that wants to use a non-default network is supposed to 11888 // look up the proxy in its LP and it has to be correct. 11889 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11890 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11891 11892 // Simulate PacManager sending the notification that the local server has started 11893 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 11894 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 11895 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11896 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11897 cellCallback.assertNoCallback(); 11898 servingProxyBroadcast.expectBroadcast(); 11899 11900 final ProxyInfo startedDefaultProxyInfo = mService.getProxyForNetwork(null); 11901 final ProxyInfo startedWifiProxyInfo = mService.getProxyForNetwork( 11902 mWiFiAgent.getNetwork()); 11903 final LinkProperties startedLp = mService.getLinkProperties(mWiFiAgent.getNetwork()); 11904 assertEquals(servingProxyInfo, startedDefaultProxyInfo); 11905 assertEquals(servingProxyInfo, startedWifiProxyInfo); 11906 assertEquals(servingProxyInfo, startedLp.getHttpProxy()); 11907 // Make sure the cell network is still unaffected 11908 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11909 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11910 11911 // Start an ethernet network which will become the default, in order to test what happens 11912 // to the proxy of wifi while manipulating the proxy of ethernet. 11913 final Uri ethPacUrl = Uri.parse("https://ethernet-pac-url"); 11914 final TestableNetworkCallback ethernetCallback = new TestableNetworkCallback(); 11915 final NetworkRequest ethernetRequest = new NetworkRequest.Builder() 11916 .addTransportType(TRANSPORT_ETHERNET).build(); 11917 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 11918 mCm.registerNetworkCallback(ethernetRequest, ethernetCallback); 11919 mEthernetAgent.connect(true); 11920 ethernetCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 11921 11922 // Wifi is no longer the default, so it should get a callback to LP changed with a PAC 11923 // proxy but a port of -1 (since the local proxy doesn't serve wifi now) 11924 wifiCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 11925 lp -> lp.getLp().getHttpProxy().getPort() == -1 11926 && lp.getLp().getHttpProxy().isPacProxy()); 11927 // Wifi is lingered as it was the default but is no longer serving any request. 11928 wifiCallback.expect(CallbackEntry.LOSING, mWiFiAgent); 11929 11930 // Now arrange for Ethernet to have a PAC proxy. 11931 final ProxyInfo ethProxy = ProxyInfo.buildPacProxy(ethPacUrl); 11932 final LinkProperties ethLinkProperties = new LinkProperties(); 11933 ethLinkProperties.setHttpProxy(ethProxy); 11934 mEthernetAgent.sendLinkProperties(ethLinkProperties); 11935 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 11936 // Default network is Ethernet 11937 assertEquals(ethProxy, mService.getProxyForNetwork(null)); 11938 assertEquals(ethProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 11939 // Proxy info for WiFi ideally should be the old one with the old server still running, 11940 // but as the PAC code only handles one server at any given time, this can't work. Wifi 11941 // having null as a proxy also won't work (apps using WiFi will try to access the network 11942 // without proxy) but is not as bad as having the new proxy (that would send requests 11943 // over the default network). 11944 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11945 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11946 11947 // Expect the local PAC proxy server starts to serve the proxy on Ethernet. Use 11948 // simulateUpdateProxyInfo to simulate this, and check that the callback is called to 11949 // inform apps of the port and that the various networks have the expected proxies in 11950 // their link properties. 11951 final ProxyInfo servingEthProxy = new ProxyInfo(ethPacUrl, 2099); 11952 final ExpectedBroadcast servingEthProxyBroadcast = expectProxyChangeAction(servingEthProxy); 11953 final ExpectedBroadcast servingProxyBroadcast2 = expectProxyChangeAction(servingProxyInfo); 11954 mService.simulateUpdateProxyInfo(mEthernetAgent.getNetwork(), servingEthProxy); 11955 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 11956 assertEquals(servingEthProxy, mService.getProxyForNetwork(null)); 11957 assertEquals(servingEthProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 11958 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11959 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11960 servingEthProxyBroadcast.expectBroadcast(); 11961 11962 // Ethernet disconnects, back to WiFi 11963 mEthernetAgent.disconnect(); 11964 ethernetCallback.expect(CallbackEntry.LOST, mEthernetAgent); 11965 11966 // WiFi is now the default network again. However, the local proxy server does not serve 11967 // WiFi at this time, so at this time a proxy with port -1 is still the correct value. 11968 // In time, the local proxy server for ethernet will be downed and the local proxy server 11969 // for WiFi will be restarted, and WiFi will see an update to its LP with the new port, 11970 // but in this test this won't happen until the test simulates the local proxy starting 11971 // up for WiFi (which is done just a few lines below). This is therefore the perfect place 11972 // to check that WiFi is unaffected until the new local proxy starts up. 11973 wifiCallback.assertNoCallback(); 11974 assertEquals(initialProxyInfo, mService.getProxyForNetwork(null)); 11975 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11976 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11977 // Note : strictly speaking, for correctness here apps should expect a broadcast with a 11978 // port of -1, since that's the current default proxy. The code does not send this 11979 // broadcast. In practice though, not sending it is more useful since the new proxy will 11980 // start momentarily, so broadcasting and getting all apps to update and retry once now 11981 // and again in 250ms is kind of counter-productive, so don't fix this bug. 11982 11983 // After a while the PAC file for wifi is resolved again and the local proxy server 11984 // starts up. This should cause a LP event to inform clients of the port to access the 11985 // proxy server for wifi. 11986 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11987 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11988 assertEquals(servingProxyInfo, mService.getProxyForNetwork(null)); 11989 assertEquals(servingProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11990 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11991 servingProxyBroadcast2.expectBroadcast(); 11992 11993 // Expect a broadcast for an empty proxy after wifi disconnected, because cell is now 11994 // the default network and it doesn't have a proxy. Whether "no proxy" is a null pointer 11995 // or a ProxyInfo with an empty host doesn't matter because both are correct, so this test 11996 // accepts both. 11997 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 11998 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 11999 mWiFiAgent.disconnect(); 12000 emptyProxyBroadcast.expectBroadcast(); 12001 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 12002 assertNull(mService.getProxyForNetwork(null)); 12003 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 12004 assertNull(mService.getGlobalProxy()); 12005 12006 mCm.unregisterNetworkCallback(cellCallback); 12007 } 12008 12009 @Test 12010 public void testPacProxy_NetworkDisconnects_BroadcastSent() throws Exception { 12011 // Make a WiFi network with a PAC URI. 12012 final Uri pacUrl = Uri.parse("https://pac-url"); 12013 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 12014 final LinkProperties testLinkProperties = new LinkProperties(); 12015 testLinkProperties.setHttpProxy(initialProxyInfo); 12016 12017 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 12018 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12019 .addTransportType(TRANSPORT_WIFI).build(); 12020 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 12021 12022 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, testLinkProperties); 12023 mWiFiAgent.connect(true); 12024 // Wifi is up, but the local proxy server hasn't started yet. 12025 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 12026 12027 // Simulate PacManager sending the notification that the local server has started 12028 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 12029 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 12030 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 12031 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 12032 servingProxyBroadcast.expectBroadcast(); 12033 12034 // Now disconnect Wi-Fi and make sure there is a broadcast for some empty proxy. Whether 12035 // the "empty" proxy is a null pointer or a ProxyInfo with an empty host doesn't matter 12036 // because both are correct, so this test accepts both. 12037 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 12038 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 12039 mWiFiAgent.disconnect(); 12040 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 12041 emptyProxyBroadcast.expectBroadcast(); 12042 } 12043 12044 @Test 12045 public void testGetProxyForVPN() throws Exception { 12046 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 12047 12048 // Set up a WiFi network with no proxy 12049 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12050 mWiFiAgent.connect(true); 12051 waitForIdle(); 12052 assertNull(mService.getProxyForNetwork(null)); 12053 12054 // Connect a VPN network with a proxy. 12055 LinkProperties testLinkProperties = new LinkProperties(); 12056 testLinkProperties.setHttpProxy(testProxyInfo); 12057 mMockVpn.establishForMyUid(testLinkProperties); 12058 assertUidRangesUpdatedForMyUid(true); 12059 12060 // Test that the VPN network returns a proxy, and the WiFi does not. 12061 assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); 12062 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 12063 assertNull(mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12064 12065 // Test that the VPN network returns no proxy when it is set to null. 12066 testLinkProperties.setHttpProxy(null); 12067 mMockVpn.sendLinkProperties(testLinkProperties); 12068 waitForIdle(); 12069 assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); 12070 assertNull(mService.getProxyForNetwork(null)); 12071 12072 // Set WiFi proxy and check that the vpn proxy is still null. 12073 testLinkProperties.setHttpProxy(testProxyInfo); 12074 mWiFiAgent.sendLinkProperties(testLinkProperties); 12075 waitForIdle(); 12076 assertNull(mService.getProxyForNetwork(null)); 12077 12078 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 12079 // correct proxy setting. 12080 mMockVpn.disconnect(); 12081 waitForIdle(); 12082 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 12083 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12084 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 12085 } 12086 12087 @Test 12088 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 12089 LinkProperties lp = new LinkProperties(); 12090 lp.setInterfaceName("tun0"); 12091 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12092 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 12093 // The uid range needs to cover the test app so the network is visible to it. 12094 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12095 mMockVpn.establish(lp, VPN_UID, vpnRange); 12096 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 12097 12098 // A connected VPN should have interface rules set up. There are two expected invocations, 12099 // one during the VPN initial connection, one during the VPN LinkProperties update. 12100 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12101 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12102 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12103 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12104 12105 mMockVpn.disconnect(); 12106 waitForIdle(); 12107 12108 // Disconnected VPN should have interface rules removed 12109 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12110 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12111 } 12112 12113 private void checkInterfaceFilteringRuleWithNullInterface(final LinkProperties lp, 12114 final int uid) throws Exception { 12115 // The uid range needs to cover the test app so the network is visible to it. 12116 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12117 mMockVpn.establish(lp, uid, vpnRange); 12118 assertVpnUidRangesUpdated(true, vpnRange, uid); 12119 12120 if (mDeps.isAtLeastT()) { 12121 // On T and above, VPN should have rules for null interface. Null Interface is a 12122 // wildcard and this accepts traffic from all the interfaces. 12123 // There are two expected invocations, one during the VPN initial 12124 // connection, one during the VPN LinkProperties update. 12125 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12126 verify(mBpfNetMaps, times(2)).addUidInterfaceRules( 12127 eq(null) /* iface */, uidCaptor.capture()); 12128 if (uid == VPN_UID) { 12129 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12130 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12131 } else { 12132 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID, VPN_UID); 12133 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID, VPN_UID); 12134 } 12135 12136 mMockVpn.disconnect(); 12137 waitForIdle(); 12138 12139 // Disconnected VPN should have interface rules removed 12140 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12141 if (uid == VPN_UID) { 12142 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12143 } else { 12144 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID, VPN_UID); 12145 } 12146 } else { 12147 // Before T, rules are not configured for null interface. 12148 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 12149 } 12150 } 12151 12152 @Test 12153 public void testLegacyVpnInterfaceFilteringRule() throws Exception { 12154 LinkProperties lp = new LinkProperties(); 12155 lp.setInterfaceName("tun0"); 12156 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12157 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12158 // Legacy VPN should have interface filtering with null interface. 12159 checkInterfaceFilteringRuleWithNullInterface(lp, Process.SYSTEM_UID); 12160 } 12161 12162 @Test 12163 public void testLocalIpv4OnlyVpnInterfaceFilteringRule() throws Exception { 12164 LinkProperties lp = new LinkProperties(); 12165 lp.setInterfaceName("tun0"); 12166 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 12167 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 12168 // VPN that does not provide a default route should have interface filtering with null 12169 // interface. 12170 checkInterfaceFilteringRuleWithNullInterface(lp, VPN_UID); 12171 } 12172 12173 @Test 12174 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 12175 LinkProperties lp = new LinkProperties(); 12176 lp.setInterfaceName("tun0"); 12177 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12178 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12179 // The uid range needs to cover the test app so the network is visible to it. 12180 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12181 mMockVpn.establish(lp, VPN_UID, vpnRange); 12182 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 12183 12184 // Connected VPN should have interface rules set up. There are two expected invocations, 12185 // one during VPN uid update, one during VPN LinkProperties update 12186 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12187 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12188 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12189 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12190 12191 reset(mBpfNetMaps); 12192 InOrder inOrder = inOrder(mBpfNetMaps); 12193 lp.setInterfaceName("tun1"); 12194 mMockVpn.sendLinkProperties(lp); 12195 waitForIdle(); 12196 // VPN handover (switch to a new interface) should result in rules being updated (old rules 12197 // removed first, then new rules added) 12198 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12199 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12200 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 12201 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12202 12203 reset(mBpfNetMaps); 12204 lp = new LinkProperties(); 12205 lp.setInterfaceName("tun1"); 12206 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 12207 mMockVpn.sendLinkProperties(lp); 12208 waitForIdle(); 12209 // VPN not routing everything should no longer have interface filtering rules 12210 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12211 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12212 12213 reset(mBpfNetMaps); 12214 lp = new LinkProperties(); 12215 lp.setInterfaceName("tun1"); 12216 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 12217 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12218 mMockVpn.sendLinkProperties(lp); 12219 waitForIdle(); 12220 // Back to routing all IPv6 traffic should have filtering rules 12221 verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 12222 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12223 } 12224 12225 @Test 12226 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 12227 LinkProperties lp = new LinkProperties(); 12228 lp.setInterfaceName("tun0"); 12229 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 12230 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12231 // The uid range needs to cover the test app so the network is visible to it. 12232 final UidRange vpnRange = PRIMARY_UIDRANGE; 12233 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 12234 mMockVpn.establish(lp, VPN_UID, vpnRanges); 12235 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 12236 12237 reset(mBpfNetMaps); 12238 InOrder inOrder = inOrder(mBpfNetMaps); 12239 12240 // Update to new range which is old range minus APP1, i.e. only APP2 12241 final Set<UidRange> newRanges = new HashSet<>(asList( 12242 new UidRange(vpnRange.start, APP1_UID - 1), 12243 new UidRange(APP1_UID + 1, vpnRange.stop))); 12244 mMockVpn.setUids(newRanges); 12245 waitForIdle(); 12246 12247 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12248 // Verify old rules are removed before new rules are added 12249 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12250 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12251 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12252 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 12253 } 12254 12255 @Test 12256 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 12257 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12258 12259 LinkProperties wifiLp = new LinkProperties(); 12260 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 12261 wifiLp.setWakeOnLanSupported(false); 12262 12263 // Default network switch should update ifaces. 12264 mWiFiAgent.connect(false); 12265 mWiFiAgent.sendLinkProperties(wifiLp); 12266 waitForIdle(); 12267 12268 // ConnectivityService should have changed the WakeOnLanSupported to true 12269 wifiLp.setWakeOnLanSupported(true); 12270 assertEquals(wifiLp, mService.getActiveLinkProperties()); 12271 } 12272 12273 @Test 12274 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 12275 class TestNetworkAgent extends NetworkAgent { 12276 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 12277 super(context, looper, "MockAgent", new NetworkCapabilities(), 12278 new LinkProperties(), 40 , config, null /* provider */); 12279 } 12280 } 12281 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 12282 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 12283 naNoExtraInfo.register(); 12284 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); 12285 naNoExtraInfo.unregister(); 12286 12287 reset(mNetworkStack); 12288 final NetworkAgentConfig config = 12289 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 12290 final NetworkAgent naExtraInfo = new TestNetworkAgent( 12291 mServiceContext, mCsHandlerThread.getLooper(), config); 12292 naExtraInfo.register(); 12293 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 12294 naExtraInfo.unregister(); 12295 } 12296 12297 // To avoid granting location permission bypass. 12298 private void denyAllLocationPrivilegedPermissions() { 12299 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 12300 PERMISSION_DENIED); 12301 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 12302 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12303 mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, 12304 PERMISSION_DENIED); 12305 } 12306 12307 private void setupLocationPermissions( 12308 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 12309 denyAllLocationPrivilegedPermissions(); 12310 12311 final ApplicationInfo applicationInfo = new ApplicationInfo(); 12312 applicationInfo.targetSdkVersion = targetSdk; 12313 doReturn(applicationInfo).when(mPackageManager) 12314 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 12315 doReturn(targetSdk).when(mPackageManager).getTargetSdkVersion(any()); 12316 12317 doReturn(locationToggle).when(mLocationManager).isLocationEnabledForUser(any()); 12318 12319 if (op != null) { 12320 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp( 12321 eq(op), eq(Process.myUid()), eq(mContext.getPackageName()), 12322 eq(getAttributionTag()), anyString()); 12323 } 12324 12325 if (perm != null) { 12326 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 12327 } 12328 } 12329 12330 private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, 12331 boolean includeLocationSensitiveInfo) { 12332 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 12333 12334 return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12335 netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, 12336 mContext.getPackageName(), getAttributionTag()) 12337 .getOwnerUid(); 12338 } 12339 12340 private void verifyTransportInfoCopyNetCapsPermission( 12341 int callerUid, boolean includeLocationSensitiveInfo, 12342 boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 12343 final TransportInfo transportInfo = mock(TransportInfo.class); 12344 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION).when(transportInfo).getApplicableRedactions(); 12345 final NetworkCapabilities netCap = 12346 new NetworkCapabilities().setTransportInfo(transportInfo); 12347 12348 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12349 netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, 12350 mContext.getPackageName(), getAttributionTag()); 12351 if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 12352 verify(transportInfo).makeCopy(REDACT_NONE); 12353 } else { 12354 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12355 } 12356 } 12357 12358 private void verifyOwnerUidAndTransportInfoNetCapsPermission( 12359 boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, 12360 boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, 12361 boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, 12362 boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { 12363 final int myUid = Process.myUid(); 12364 12365 final int expectedOwnerUidWithoutIncludeFlag = 12366 shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag 12367 ? myUid : INVALID_UID; 12368 assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( 12369 myUid, myUid, false /* includeLocationSensitiveInfo */)); 12370 12371 final int expectedOwnerUidWithIncludeFlag = 12372 shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; 12373 assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( 12374 myUid, myUid, true /* includeLocationSensitiveInfo */)); 12375 12376 verifyTransportInfoCopyNetCapsPermission(myUid, 12377 false, /* includeLocationSensitiveInfo */ 12378 shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); 12379 12380 verifyTransportInfoCopyNetCapsPermission(myUid, 12381 true, /* includeLocationSensitiveInfo */ 12382 shouldInclLocationSensitiveTransportInfoWithIncludeFlag); 12383 12384 } 12385 12386 private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { 12387 verifyOwnerUidAndTransportInfoNetCapsPermission( 12388 // Ensure that owner uid is included even if the request asks to remove it (which is 12389 // the default) since the app has necessary permissions and targetSdk < S. 12390 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12391 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12392 // Ensure that location info is removed if the request asks to remove it even if the 12393 // app has necessary permissions. 12394 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12395 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12396 ); 12397 } 12398 12399 @Test 12400 public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() 12401 throws Exception { 12402 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12403 Manifest.permission.ACCESS_FINE_LOCATION); 12404 12405 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12406 } 12407 12408 @Test 12409 public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() 12410 throws Exception { 12411 setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, 12412 Manifest.permission.ACCESS_FINE_LOCATION); 12413 12414 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12415 } 12416 12417 @Test 12418 public void 12419 testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() 12420 throws Exception { 12421 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12422 Manifest.permission.ACCESS_FINE_LOCATION); 12423 12424 verifyOwnerUidAndTransportInfoNetCapsPermission( 12425 // Ensure that the owner UID is removed if the request asks us to remove it even 12426 // if the app has necessary permissions since targetSdk >= S. 12427 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12428 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12429 // Ensure that location info is removed if the request asks to remove it even if the 12430 // app has necessary permissions. 12431 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12432 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12433 ); 12434 } 12435 12436 @Test 12437 public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() 12438 throws Exception { 12439 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12440 Manifest.permission.ACCESS_COARSE_LOCATION); 12441 12442 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12443 } 12444 12445 private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { 12446 verifyOwnerUidAndTransportInfoNetCapsPermission( 12447 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12448 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12449 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12450 false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12451 ); 12452 } 12453 12454 @Test 12455 public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { 12456 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 12457 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 12458 Manifest.permission.ACCESS_FINE_LOCATION); 12459 12460 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12461 } 12462 12463 @Test 12464 public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { 12465 // Test that even with fine location permission, not being the owner leads to sanitization. 12466 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12467 Manifest.permission.ACCESS_FINE_LOCATION); 12468 12469 final int myUid = Process.myUid(); 12470 assertEquals(Process.INVALID_UID, 12471 getOwnerUidNetCapsPermission(myUid + 1, myUid, 12472 true /* includeLocationSensitiveInfo */)); 12473 } 12474 12475 @Test 12476 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() 12477 throws Exception { 12478 // Test that not having fine location permission leads to sanitization. 12479 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12480 Manifest.permission.ACCESS_COARSE_LOCATION); 12481 12482 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12483 } 12484 12485 @Test 12486 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() 12487 throws Exception { 12488 // Test that not having fine location permission leads to sanitization. 12489 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12490 Manifest.permission.ACCESS_COARSE_LOCATION); 12491 12492 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12493 } 12494 12495 @Test 12496 public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() 12497 throws Exception { 12498 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); 12499 12500 final TransportInfo transportInfo = mock(TransportInfo.class); 12501 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12502 .when(transportInfo).getApplicableRedactions(); 12503 final NetworkCapabilities netCap = 12504 new NetworkCapabilities().setTransportInfo(transportInfo); 12505 12506 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12507 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12508 Process.myPid(), Process.myUid(), 12509 mContext.getPackageName(), getAttributionTag()); 12510 // don't redact MAC_ADDRESS fields, only location sensitive fields. 12511 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12512 } 12513 12514 @Test 12515 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() 12516 throws Exception { 12517 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12518 12519 final TransportInfo transportInfo = mock(TransportInfo.class); 12520 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12521 .when(transportInfo).getApplicableRedactions(); 12522 final NetworkCapabilities netCap = 12523 new NetworkCapabilities().setTransportInfo(transportInfo); 12524 12525 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12526 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12527 Process.myPid(), Process.myUid(), 12528 mContext.getPackageName(), getAttributionTag()); 12529 // redact both MAC_ADDRESS & location sensitive fields. 12530 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION 12531 | REDACT_FOR_LOCAL_MAC_ADDRESS); 12532 } 12533 12534 @Test 12535 public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() 12536 throws Exception { 12537 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 12538 12539 final TransportInfo transportInfo = mock(TransportInfo.class); 12540 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12541 .when(transportInfo).getApplicableRedactions(); 12542 final NetworkCapabilities netCap = 12543 new NetworkCapabilities().setTransportInfo(transportInfo); 12544 12545 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12546 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12547 Process.myPid(), Process.myUid(), 12548 mContext.getPackageName(), getAttributionTag()); 12549 // don't redact NETWORK_SETTINGS fields, only location sensitive fields. 12550 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12551 } 12552 12553 @Test 12554 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() 12555 throws Exception { 12556 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12557 12558 final TransportInfo transportInfo = mock(TransportInfo.class); 12559 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12560 .when(transportInfo).getApplicableRedactions(); 12561 final NetworkCapabilities netCap = 12562 new NetworkCapabilities().setTransportInfo(transportInfo); 12563 12564 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12565 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12566 Process.myPid(), Process.myUid(), 12567 mContext.getPackageName(), getAttributionTag()); 12568 // redact both NETWORK_SETTINGS & location sensitive fields. 12569 verify(transportInfo).makeCopy( 12570 REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 12571 } 12572 12573 /** 12574 * Test TransportInfo to verify redaction mechanism. 12575 */ 12576 private static class TestTransportInfo implements TransportInfo { 12577 public final boolean locationRedacted; 12578 public final boolean localMacAddressRedacted; 12579 public final boolean settingsRedacted; 12580 12581 TestTransportInfo() { 12582 locationRedacted = false; 12583 localMacAddressRedacted = false; 12584 settingsRedacted = false; 12585 } 12586 12587 TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, 12588 boolean settingsRedacted) { 12589 this.locationRedacted = locationRedacted; 12590 this.localMacAddressRedacted = 12591 localMacAddressRedacted; 12592 this.settingsRedacted = settingsRedacted; 12593 } 12594 12595 @Override 12596 public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { 12597 return new TestTransportInfo( 12598 locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, 12599 localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, 12600 settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 12601 ); 12602 } 12603 12604 @Override 12605 public @NetworkCapabilities.RedactionType long getApplicableRedactions() { 12606 return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS 12607 | REDACT_FOR_NETWORK_SETTINGS; 12608 } 12609 12610 @Override 12611 public boolean equals(Object other) { 12612 if (!(other instanceof TestTransportInfo)) return false; 12613 TestTransportInfo that = (TestTransportInfo) other; 12614 return that.locationRedacted == this.locationRedacted 12615 && that.localMacAddressRedacted == this.localMacAddressRedacted 12616 && that.settingsRedacted == this.settingsRedacted; 12617 } 12618 12619 @Override 12620 public int hashCode() { 12621 return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); 12622 } 12623 12624 @Override 12625 public String toString() { 12626 return String.format( 12627 "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", 12628 locationRedacted, localMacAddressRedacted, settingsRedacted); 12629 } 12630 } 12631 12632 private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { 12633 return (TestTransportInfo) nc.getTransportInfo(); 12634 } 12635 12636 private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { 12637 final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); 12638 assertNotNull(nc); 12639 return getTestTransportInfo(nc); 12640 } 12641 12642 12643 private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12644 @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, 12645 @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, 12646 @NonNull TransportInfo expectedTransportInfo) throws Exception { 12647 doReturn(Build.VERSION_CODES.S).when(mPackageManager).getTargetSdkVersion(anyString()); 12648 final NetworkCapabilities ncTemplate = 12649 new NetworkCapabilities() 12650 .addTransportType(TRANSPORT_WIFI) 12651 .setOwnerUid(actualOwnerUid); 12652 12653 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12654 .addTransportType(TRANSPORT_WIFI).build(); 12655 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 12656 12657 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 12658 ncTemplate); 12659 mWiFiAgent.connect(false); 12660 12661 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 12662 12663 // Send network capabilities update with TransportInfo to trigger capabilities changed 12664 // callback. 12665 mWiFiAgent.setNetworkCapabilities(ncTemplate.setTransportInfo(actualTransportInfo), true); 12666 12667 wifiNetworkCallback.expectCaps(mWiFiAgent, 12668 c -> Objects.equals(expectedOwnerUid, c.getOwnerUid()) 12669 && Objects.equals(expectedTransportInfo, c.getTransportInfo())); 12670 } 12671 12672 @Test 12673 public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { 12674 final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); 12675 final int ownerUid = Process.myUid(); 12676 final TransportInfo transportInfo = new TestTransportInfo(); 12677 // Even though the test uid holds privileged permissions, mask location fields since 12678 // the callback did not explicitly opt-in to get location data. 12679 final TransportInfo sanitizedTransportInfo = new TestTransportInfo( 12680 true, /* locationRedacted */ 12681 true, /* localMacAddressRedacted */ 12682 true /* settingsRedacted */ 12683 ); 12684 // Should not expect location data since the callback does not set the flag for including 12685 // location data. 12686 verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12687 wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); 12688 } 12689 12690 @Test 12691 public void testTransportInfoRedactionInSynchronousCalls() throws Exception { 12692 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 12693 .addTransportType(TRANSPORT_WIFI) 12694 .setTransportInfo(new TestTransportInfo()); 12695 12696 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 12697 mWiFiAgent.connect(true /* validated; waits for callback */); 12698 12699 // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission 12700 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12701 withPermission(NETWORK_SETTINGS, () -> { 12702 assertFalse(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12703 }); 12704 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12705 12706 // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission 12707 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12708 withPermission(LOCAL_MAC_ADDRESS, () -> { 12709 assertFalse(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12710 }); 12711 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12712 12713 // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive 12714 // information. 12715 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12716 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12717 Manifest.permission.ACCESS_FINE_LOCATION); 12718 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12719 denyAllLocationPrivilegedPermissions(); 12720 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12721 } 12722 12723 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12724 throws Exception { 12725 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12726 mMockVpn.setVpnType(vpnType); 12727 mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); 12728 assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); 12729 12730 mDeps.setConnectionOwnerUid(42); 12731 } 12732 12733 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12734 throws Exception { 12735 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 12736 12737 // Test as VPN app 12738 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12739 mServiceContext.setPermission( 12740 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 12741 } 12742 12743 private ConnectionInfo getTestConnectionInfo() throws Exception { 12744 return new ConnectionInfo( 12745 IPPROTO_TCP, 12746 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 12747 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 12748 } 12749 12750 @Test 12751 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 12752 final int myUid = Process.myUid(); 12753 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 12754 12755 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12756 } 12757 12758 @Test 12759 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 12760 final int myUid = Process.myUid(); 12761 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 12762 12763 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12764 } 12765 12766 @Test 12767 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 12768 final int myUid = Process.myUid(); 12769 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 12770 12771 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12772 } 12773 12774 @Test 12775 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 12776 final int myUid = Process.myUid(); 12777 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12778 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12779 12780 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12781 } 12782 12783 @Test 12784 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 12785 throws Exception { 12786 final int myUid = Process.myUid(); 12787 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12788 mServiceContext.setPermission( 12789 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 12790 12791 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12792 } 12793 12794 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 12795 final PackageInfo packageInfo = new PackageInfo(); 12796 if (hasSystemPermission) { 12797 packageInfo.requestedPermissions = new String[] { 12798 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 12799 packageInfo.requestedPermissionsFlags = new int[] { 12800 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 12801 } else { 12802 packageInfo.requestedPermissions = new String[0]; 12803 } 12804 packageInfo.applicationInfo = new ApplicationInfo(); 12805 packageInfo.applicationInfo.privateFlags = 0; 12806 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 12807 UserHandle.getAppId(uid)); 12808 return packageInfo; 12809 } 12810 12811 @Test 12812 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 12813 final NetworkRequest request = 12814 new NetworkRequest( 12815 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 12816 try { 12817 mService.registerConnectivityDiagnosticsCallback( 12818 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 12819 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 12820 } catch (IllegalArgumentException expected) { 12821 } 12822 } 12823 12824 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 12825 assertEquals(route.getDestination().toString(), parcel.destination); 12826 assertEquals(route.getInterface(), parcel.ifName); 12827 assertEquals(route.getMtu(), parcel.mtu); 12828 12829 switch (route.getType()) { 12830 case RouteInfo.RTN_UNICAST: 12831 if (route.hasGateway()) { 12832 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 12833 } else { 12834 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12835 } 12836 break; 12837 case RouteInfo.RTN_UNREACHABLE: 12838 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 12839 break; 12840 case RouteInfo.RTN_THROW: 12841 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 12842 break; 12843 default: 12844 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12845 break; 12846 } 12847 } 12848 12849 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 12850 // TODO: add @JavaDerive(equals=true) to RouteInfoParcel, use eq() directly, and delete 12851 // assertRouteInfoParcelMatches above. 12852 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12853 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 12854 for (int i = 0; i < routes.length; i++) { 12855 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12856 } 12857 } 12858 12859 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 12860 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12861 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 12862 captor.capture()); 12863 for (int i = 0; i < routes.length; i++) { 12864 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12865 } 12866 } 12867 12868 @Test 12869 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 12870 final NetworkRequest wifiRequest = 12871 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12872 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12873 12874 mService.registerConnectivityDiagnosticsCallback( 12875 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12876 12877 // Block until all other events are done processing. 12878 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12879 12880 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12881 verify(mConnectivityDiagnosticsCallback).asBinder(); 12882 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12883 12884 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 12885 verify(mIBinder, timeout(TIMEOUT_MS)) 12886 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12887 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12888 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 12889 } 12890 12891 @Test 12892 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 12893 final NetworkRequest wifiRequest = 12894 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12895 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12896 12897 mService.registerConnectivityDiagnosticsCallback( 12898 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12899 12900 // Block until all other events are done processing. 12901 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12902 12903 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12904 verify(mConnectivityDiagnosticsCallback).asBinder(); 12905 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12906 12907 // Register the same callback again 12908 mService.registerConnectivityDiagnosticsCallback( 12909 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12910 12911 // Block until all other events are done processing. 12912 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12913 12914 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12915 } 12916 12917 @Test(expected = NullPointerException.class) 12918 public void testRegisterConnectivityDiagnosticsCallbackNullCallback() { 12919 mService.registerConnectivityDiagnosticsCallback( 12920 null /* callback */, 12921 new NetworkRequest.Builder().build(), 12922 mContext.getPackageName()); 12923 } 12924 12925 @Test(expected = NullPointerException.class) 12926 public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() { 12927 mService.registerConnectivityDiagnosticsCallback( 12928 mConnectivityDiagnosticsCallback, 12929 null /* request */, 12930 mContext.getPackageName()); 12931 } 12932 12933 @Test(expected = NullPointerException.class) 12934 public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() { 12935 mService.registerConnectivityDiagnosticsCallback( 12936 mConnectivityDiagnosticsCallback, 12937 new NetworkRequest.Builder().build(), 12938 null /* callingPackageName */); 12939 } 12940 12941 @Test(expected = NullPointerException.class) 12942 public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() { 12943 mService.unregisterConnectivityDiagnosticsCallback(null /* callback */); 12944 } 12945 12946 public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { 12947 final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc) 12948 .addTransportType(TRANSPORT_CELLULAR).build(); 12949 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 12950 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 12951 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 12952 return fakeNai(cellNc, info); 12953 } 12954 12955 private NetworkAgentInfo fakeWifiNai(NetworkCapabilities nc) { 12956 final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder(nc) 12957 .addTransportType(TRANSPORT_WIFI).build(); 12958 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0 /* subtype */, 12959 ConnectivityManager.getNetworkTypeName(TYPE_WIFI), "" /* subtypeName */); 12960 return fakeNai(wifiNc, info); 12961 } 12962 12963 private NetworkAgentInfo fakeVpnNai(NetworkCapabilities nc) { 12964 final NetworkCapabilities vpnNc = new NetworkCapabilities.Builder(nc) 12965 .addTransportType(TRANSPORT_VPN).build(); 12966 final NetworkInfo info = new NetworkInfo(TYPE_VPN, 0 /* subtype */, 12967 ConnectivityManager.getNetworkTypeName(TYPE_VPN), "" /* subtypeName */); 12968 return fakeNai(vpnNc, info); 12969 } 12970 12971 private NetworkAgentInfo fakeNai(NetworkCapabilities nc, NetworkInfo networkInfo) { 12972 return new NetworkAgentInfo(null, new Network(NET_ID), networkInfo, new LinkProperties(), 12973 nc, null /* localNetworkConfig */, 12974 new NetworkScore.Builder().setLegacyInt(0).build(), 12975 mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, 12976 INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, 12977 new ConnectivityService.Dependencies()); 12978 } 12979 12980 @Test 12981 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 12982 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 12983 12984 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12985 assertTrue( 12986 "NetworkStack permission not applied", 12987 mService.hasConnectivityDiagnosticsPermissions( 12988 Process.myPid(), Process.myUid(), naiWithoutUid, 12989 mContext.getOpPackageName())); 12990 } 12991 12992 @Test 12993 public void testCheckConnectivityDiagnosticsPermissionsSysUi() throws Exception { 12994 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 12995 12996 mServiceContext.setPermission(STATUS_BAR_SERVICE, PERMISSION_GRANTED); 12997 assertTrue( 12998 "SysUi permission (STATUS_BAR_SERVICE) not applied", 12999 mService.hasConnectivityDiagnosticsPermissions( 13000 Process.myPid(), Process.myUid(), naiWithoutUid, 13001 mContext.getOpPackageName())); 13002 } 13003 13004 @Test 13005 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 13006 final int wrongUid = Process.myUid() + 1; 13007 13008 final NetworkCapabilities nc = new NetworkCapabilities(); 13009 nc.setAdministratorUids(new int[] {wrongUid}); 13010 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 13011 13012 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13013 13014 assertFalse( 13015 "Mismatched uid/package name should not pass the location permission check", 13016 mService.hasConnectivityDiagnosticsPermissions( 13017 Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName())); 13018 } 13019 13020 private void verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo( 13021 NetworkAgentInfo info, boolean expectPermission) { 13022 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13023 13024 assertEquals( 13025 "Unexpected ConnDiags permission", 13026 expectPermission, 13027 mService.hasConnectivityDiagnosticsPermissions( 13028 Process.myPid(), Process.myUid(), info, mContext.getOpPackageName())); 13029 } 13030 13031 @Test 13032 public void testCheckConnectivityDiagnosticsPermissionsCellularNoLocationPermission() 13033 throws Exception { 13034 final NetworkCapabilities nc = new NetworkCapabilities(); 13035 nc.setAdministratorUids(new int[] {Process.myUid()}); 13036 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13037 13038 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 13039 true /* expectPermission */); 13040 } 13041 13042 @Test 13043 public void testCheckConnectivityDiagnosticsPermissionsWifiNoLocationPermission() 13044 throws Exception { 13045 final NetworkCapabilities nc = new NetworkCapabilities(); 13046 nc.setAdministratorUids(new int[] {Process.myUid()}); 13047 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 13048 13049 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 13050 false /* expectPermission */); 13051 } 13052 13053 @Test 13054 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 13055 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 13056 13057 mMockVpn.establishForMyUid(); 13058 assertUidRangesUpdatedForMyUid(true); 13059 13060 // Wait for networks to connect and broadcasts to be sent before removing permissions. 13061 waitForIdle(); 13062 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13063 Manifest.permission.ACCESS_FINE_LOCATION); 13064 13065 assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); 13066 waitForIdle(); 13067 assertTrue( 13068 "Active VPN permission not applied", 13069 mService.hasConnectivityDiagnosticsPermissions( 13070 Process.myPid(), Process.myUid(), naiWithoutUid, 13071 mContext.getOpPackageName())); 13072 13073 assertTrue(mMockVpn.setUnderlyingNetworks(null)); 13074 waitForIdle(); 13075 assertFalse( 13076 "VPN shouldn't receive callback on non-underlying network", 13077 mService.hasConnectivityDiagnosticsPermissions( 13078 Process.myPid(), Process.myUid(), naiWithoutUid, 13079 mContext.getOpPackageName())); 13080 } 13081 13082 @Test 13083 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 13084 final NetworkCapabilities nc = new NetworkCapabilities(); 13085 nc.setAdministratorUids(new int[] {Process.myUid()}); 13086 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13087 13088 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13089 Manifest.permission.ACCESS_FINE_LOCATION); 13090 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13091 13092 assertTrue( 13093 "NetworkCapabilities administrator uid permission not applied", 13094 mService.hasConnectivityDiagnosticsPermissions( 13095 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 13096 } 13097 13098 @Test 13099 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 13100 final NetworkCapabilities nc = new NetworkCapabilities(); 13101 nc.setOwnerUid(Process.myUid()); 13102 nc.setAdministratorUids(new int[] {Process.myUid()}); 13103 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13104 13105 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13106 Manifest.permission.ACCESS_FINE_LOCATION); 13107 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13108 13109 // Use wrong pid and uid 13110 assertFalse( 13111 "Permissions allowed when they shouldn't be granted", 13112 mService.hasConnectivityDiagnosticsPermissions( 13113 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 13114 mContext.getOpPackageName())); 13115 } 13116 13117 @Test 13118 public void testUnderlyingNetworksWillBeSetInNetworkAgentInfoConstructor() throws Exception { 13119 assumeTrue(mDeps.isAtLeastT()); 13120 final Network network1 = new Network(100); 13121 final Network network2 = new Network(101); 13122 final List<Network> underlyingNetworks = new ArrayList<>(); 13123 final NetworkCapabilities ncWithEmptyUnderlyingNetworks = new NetworkCapabilities.Builder() 13124 .setUnderlyingNetworks(underlyingNetworks) 13125 .build(); 13126 final NetworkAgentInfo vpnNaiWithEmptyUnderlyingNetworks = 13127 fakeVpnNai(ncWithEmptyUnderlyingNetworks); 13128 assertEquals(underlyingNetworks, 13129 Arrays.asList(vpnNaiWithEmptyUnderlyingNetworks.declaredUnderlyingNetworks)); 13130 13131 underlyingNetworks.add(network1); 13132 underlyingNetworks.add(network2); 13133 final NetworkCapabilities ncWithUnderlyingNetworks = new NetworkCapabilities.Builder() 13134 .setUnderlyingNetworks(underlyingNetworks) 13135 .build(); 13136 final NetworkAgentInfo vpnNaiWithUnderlyingNetwokrs = fakeVpnNai(ncWithUnderlyingNetworks); 13137 assertEquals(underlyingNetworks, 13138 Arrays.asList(vpnNaiWithUnderlyingNetwokrs.declaredUnderlyingNetworks)); 13139 13140 final NetworkCapabilities ncWithoutUnderlyingNetworks = new NetworkCapabilities.Builder() 13141 .build(); 13142 final NetworkAgentInfo vpnNaiWithoutUnderlyingNetwokrs = 13143 fakeVpnNai(ncWithoutUnderlyingNetworks); 13144 assertNull(vpnNaiWithoutUnderlyingNetwokrs.declaredUnderlyingNetworks); 13145 } 13146 13147 @Test 13148 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 13149 throws Exception { 13150 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 13151 final TestNetworkCallback callback = new TestNetworkCallback(); 13152 mCm.registerDefaultNetworkCallback(callback); 13153 final LinkProperties linkProperties = new LinkProperties(); 13154 linkProperties.setInterfaceName(INTERFACE_NAME); 13155 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 13156 mCellAgent.connect(true); 13157 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 13158 callback.assertNoCallback(); 13159 13160 final NetworkRequest request = new NetworkRequest.Builder().build(); 13161 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 13162 13163 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 13164 13165 mService.registerConnectivityDiagnosticsCallback( 13166 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 13167 13168 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13169 .onConnectivityReportAvailable(argThat(report -> { 13170 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 13171 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 13172 })); 13173 } 13174 13175 private void setUpConnectivityDiagnosticsCallback() throws Exception { 13176 final NetworkRequest request = new NetworkRequest.Builder().build(); 13177 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 13178 13179 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 13180 13181 mService.registerConnectivityDiagnosticsCallback( 13182 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 13183 13184 // Block until all other events are done processing. 13185 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 13186 13187 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 13188 final TestNetworkCallback callback = new TestNetworkCallback(); 13189 mCm.registerDefaultNetworkCallback(callback); 13190 13191 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 13192 .addTransportType(TRANSPORT_CELLULAR) 13193 .setTransportInfo(new TestTransportInfo()); 13194 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), 13195 ncTemplate); 13196 mCellAgent.connect(true); 13197 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 13198 callback.assertNoCallback(); 13199 13200 // Make sure a report is sent and that the caps are suitably redacted. 13201 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13202 .onConnectivityReportAvailable(argThat(report -> 13203 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13204 reset(mConnectivityDiagnosticsCallback); 13205 } 13206 13207 private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { 13208 TestTransportInfo ti = getTestTransportInfo(nc); 13209 return nc.getUids() == null 13210 && nc.getAdministratorUids().length == 0 13211 && nc.getOwnerUid() == Process.INVALID_UID 13212 && ti.locationRedacted 13213 && ti.localMacAddressRedacted 13214 && ti.settingsRedacted; 13215 } 13216 13217 @Test 13218 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 13219 setUpConnectivityDiagnosticsCallback(); 13220 13221 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 13222 // cellular network agent 13223 mCellAgent.notifyDataStallSuspected(); 13224 13225 // Verify onDataStallSuspected fired 13226 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)).onDataStallSuspected( 13227 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13228 } 13229 13230 @Test 13231 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 13232 setUpConnectivityDiagnosticsCallback(); 13233 13234 final Network n = mCellAgent.getNetwork(); 13235 final boolean hasConnectivity = true; 13236 mService.reportNetworkConnectivity(n, hasConnectivity); 13237 13238 // Verify onNetworkConnectivityReported fired 13239 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13240 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 13241 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13242 .onConnectivityReportAvailable( 13243 argThat(report -> 13244 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13245 13246 final boolean noConnectivity = false; 13247 mService.reportNetworkConnectivity(n, noConnectivity); 13248 13249 // Wait for onNetworkConnectivityReported to fire 13250 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13251 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 13252 13253 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 13254 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS).times(2)) 13255 .onConnectivityReportAvailable( 13256 argThat(report -> 13257 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13258 } 13259 13260 @Test 13261 public void testConnectivityDiagnosticsCallbackOnConnectivityReportedSeparateUid() 13262 throws Exception { 13263 setUpConnectivityDiagnosticsCallback(); 13264 13265 // report known Connectivity from a different uid. Verify that network is not re-validated 13266 // and this callback is not notified. 13267 final Network n = mCellAgent.getNetwork(); 13268 final boolean hasConnectivity = true; 13269 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, hasConnectivity)); 13270 13271 // Block until all other events are done processing. 13272 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 13273 13274 // Verify onNetworkConnectivityReported did not fire 13275 verify(mConnectivityDiagnosticsCallback, never()) 13276 .onNetworkConnectivityReported(any(), anyBoolean()); 13277 verify(mConnectivityDiagnosticsCallback, never()) 13278 .onConnectivityReportAvailable(any()); 13279 13280 // report different Connectivity from a different uid. Verify that network is re-validated 13281 // and that this callback is notified. 13282 final boolean noConnectivity = false; 13283 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, noConnectivity)); 13284 13285 // Wait for onNetworkConnectivityReported to fire 13286 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13287 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 13288 13289 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 13290 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13291 .onConnectivityReportAvailable( 13292 argThat(report -> 13293 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13294 } 13295 13296 @Test(expected = NullPointerException.class) 13297 public void testSimulateDataStallNullNetwork() { 13298 mService.simulateDataStall( 13299 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 13300 0L /* timestampMillis */, 13301 null /* network */, 13302 new PersistableBundle()); 13303 } 13304 13305 @Test(expected = NullPointerException.class) 13306 public void testSimulateDataStallNullPersistableBundle() { 13307 mService.simulateDataStall( 13308 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 13309 0L /* timestampMillis */, 13310 mock(Network.class), 13311 null /* extras */); 13312 } 13313 13314 @Test 13315 public void testRouteAddDeleteUpdate() throws Exception { 13316 final NetworkRequest request = new NetworkRequest.Builder().build(); 13317 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 13318 mCm.registerNetworkCallback(request, networkCallback); 13319 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13320 reset(mMockNetd); 13321 mCellAgent.connect(false); 13322 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 13323 final int netId = mCellAgent.getNetwork().netId; 13324 13325 final String iface = "rmnet_data0"; 13326 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 13327 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 13328 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 13329 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 13330 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 13331 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 13332 1280 /* mtu */); 13333 13334 // Send LinkProperties and check that we ask netd to add routes. 13335 LinkProperties lp = new LinkProperties(); 13336 lp.setInterfaceName(iface); 13337 lp.addRoute(direct); 13338 lp.addRoute(rio1); 13339 lp.addRoute(defaultRoute); 13340 mCellAgent.sendLinkProperties(lp); 13341 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 13342 x -> x.getLp().getRoutes().size() == 3); 13343 13344 assertRoutesAdded(netId, direct, rio1, defaultRoute); 13345 reset(mMockNetd); 13346 13347 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 13348 assertTrue(lp.getRoutes().contains(defaultRoute)); 13349 lp.removeRoute(rio1); 13350 lp.addRoute(rio2); 13351 lp.addRoute(defaultWithMtu); 13352 // Ensure adding the same route with a different MTU replaces the previous route. 13353 assertFalse(lp.getRoutes().contains(defaultRoute)); 13354 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 13355 13356 mCellAgent.sendLinkProperties(lp); 13357 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 13358 x -> x.getLp().getRoutes().contains(rio2)); 13359 13360 assertRoutesRemoved(netId, rio1); 13361 assertRoutesAdded(netId, rio2); 13362 13363 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 13364 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 13365 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 13366 13367 13368 mCm.unregisterNetworkCallback(networkCallback); 13369 } 13370 13371 private void verifyDump(String[] args) { 13372 final StringWriter stringWriter = new StringWriter(); 13373 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), args); 13374 assertFalse(stringWriter.toString().isEmpty()); 13375 } 13376 13377 @Test 13378 public void testDumpDoesNotCrash() throws Exception { 13379 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 13380 // Filing a couple requests prior to testing the dump. 13381 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 13382 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 13383 final NetworkRequest genericRequest = new NetworkRequest.Builder() 13384 .clearCapabilities().build(); 13385 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 13386 .addTransportType(TRANSPORT_WIFI).build(); 13387 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 13388 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 13389 13390 // NetworkProvider 13391 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 13392 mCsHandlerThread.getLooper(), "Wifi provider"); 13393 mCm.registerNetworkProvider(wifiProvider); 13394 13395 // NetworkAgent 13396 final LinkProperties wifiLp = new LinkProperties(); 13397 wifiLp.setInterfaceName(WIFI_IFNAME); 13398 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 13399 mWiFiAgent.connect(true); 13400 13401 // NetworkOffer 13402 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 13403 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 13404 .addTransportType(TRANSPORT_WIFI) 13405 .addCapability(NET_CAPABILITY_INTERNET) 13406 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 13407 .build(); 13408 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 13409 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 13410 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 13411 13412 // Profile preferences 13413 final UserHandle testHandle = setupEnterpriseNetwork(); 13414 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13415 workAgent.connect(true); 13416 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13417 null /* executor */, null /* listener */); 13418 13419 // OEM preferences 13420 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13421 OEM_NETWORK_PREFERENCE_OEM_PAID; 13422 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13423 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME); 13424 13425 // Mobile data preferred UIDs 13426 setAndUpdateMobileDataPreferredUids(Set.of(TEST_PACKAGE_UID)); 13427 13428 verifyDump(new String[0]); 13429 13430 // Verify dump with arguments. 13431 final String dumpPrio = "--dump-priority"; 13432 final String[] dumpArgs = {dumpPrio}; 13433 verifyDump(dumpArgs); 13434 13435 final String[] highDumpArgs = {dumpPrio, "HIGH"}; 13436 verifyDump(highDumpArgs); 13437 13438 final String[] normalDumpArgs = {dumpPrio, "NORMAL"}; 13439 verifyDump(normalDumpArgs); 13440 13441 // Invalid args should do dumpNormal w/o exception 13442 final String[] unknownDumpArgs = {dumpPrio, "UNKNOWN"}; 13443 verifyDump(unknownDumpArgs); 13444 13445 final String[] invalidDumpArgs = {"UNKNOWN"}; 13446 verifyDump(invalidDumpArgs); 13447 } 13448 13449 @Test 13450 public void testRequestsSortedByIdSortsCorrectly() { 13451 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 13452 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 13453 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 13454 final NetworkRequest genericRequest = new NetworkRequest.Builder() 13455 .clearCapabilities().build(); 13456 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 13457 .addTransportType(TRANSPORT_WIFI).build(); 13458 final NetworkRequest cellRequest = new NetworkRequest.Builder() 13459 .addTransportType(TRANSPORT_CELLULAR).build(); 13460 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 13461 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 13462 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 13463 waitForIdle(); 13464 13465 final NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); 13466 13467 assertTrue(nriOutput.length > 1); 13468 for (int i = 0; i < nriOutput.length - 1; i++) { 13469 final boolean isRequestIdInOrder = 13470 nriOutput[i].mRequests.get(0).requestId 13471 < nriOutput[i + 1].mRequests.get(0).requestId; 13472 assertTrue(isRequestIdInOrder); 13473 } 13474 } 13475 13476 private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { 13477 final int uid = Process.myUid(); 13478 assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); 13479 } 13480 13481 private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) 13482 throws Exception { 13483 InOrder inOrder = inOrder(mMockNetd, mDestroySocketsWrapper); 13484 final Set<Integer> exemptUidSet = new ArraySet<>(List.of(exemptUid, Process.VPN_UID)); 13485 ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); 13486 13487 if (mDeps.isAtLeastU()) { 13488 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13489 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13490 } else { 13491 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13492 exemptUidCaptor.capture()); 13493 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13494 } 13495 13496 if (add) { 13497 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel( 13498 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13499 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13500 } else { 13501 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel( 13502 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13503 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13504 } 13505 13506 if (mDeps.isAtLeastU()) { 13507 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13508 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13509 } else { 13510 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13511 exemptUidCaptor.capture()); 13512 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13513 } 13514 } 13515 13516 @Test 13517 public void testVpnUidRangesUpdate() throws Exception { 13518 // Set up a WiFi network without proxy. 13519 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13520 mWiFiAgent.connect(true); 13521 assertNull(mService.getProxyForNetwork(null)); 13522 assertNull(mCm.getDefaultProxy()); 13523 13524 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13525 final LinkProperties lp = new LinkProperties(); 13526 lp.setInterfaceName("tun0"); 13527 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13528 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13529 final UidRange vpnRange = PRIMARY_UIDRANGE; 13530 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13531 mMockVpn.establish(lp, VPN_UID, vpnRanges); 13532 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13533 // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. 13534 b1.expectNoBroadcast(500); 13535 13536 // Update to new range which is old range minus APP1, i.e. only APP2 13537 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13538 final Set<UidRange> newRanges = new HashSet<>(asList( 13539 new UidRange(vpnRange.start, APP1_UID - 1), 13540 new UidRange(APP1_UID + 1, vpnRange.stop))); 13541 mMockVpn.setUids(newRanges); 13542 waitForIdle(); 13543 13544 assertVpnUidRangesUpdated(true, newRanges, VPN_UID); 13545 assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); 13546 13547 // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. 13548 b2.expectNoBroadcast(500); 13549 13550 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13551 final ExpectedBroadcast b3 = expectProxyChangeAction(); 13552 lp.setHttpProxy(testProxyInfo); 13553 mMockVpn.sendLinkProperties(lp); 13554 waitForIdle(); 13555 // Proxy is set, so send a proxy broadcast. 13556 b3.expectBroadcast(); 13557 13558 final ExpectedBroadcast b4 = expectProxyChangeAction(); 13559 mMockVpn.setUids(vpnRanges); 13560 waitForIdle(); 13561 // Uid has changed and proxy is already set, so send a proxy broadcast. 13562 b4.expectBroadcast(); 13563 13564 final ExpectedBroadcast b5 = expectProxyChangeAction(); 13565 // Proxy is removed, send a proxy broadcast. 13566 lp.setHttpProxy(null); 13567 mMockVpn.sendLinkProperties(lp); 13568 waitForIdle(); 13569 b5.expectBroadcast(); 13570 13571 // Proxy is added in WiFi(default network), setDefaultProxy will be called. 13572 final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 13573 assertNotNull(wifiLp); 13574 final ExpectedBroadcast b6 = expectProxyChangeAction(testProxyInfo); 13575 wifiLp.setHttpProxy(testProxyInfo); 13576 mWiFiAgent.sendLinkProperties(wifiLp); 13577 waitForIdle(); 13578 b6.expectBroadcast(); 13579 } 13580 13581 @Test 13582 public void testProxyBroadcastWillBeSentWhenVpnHasProxyAndConnects() throws Exception { 13583 // Set up a WiFi network without proxy. 13584 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13585 mWiFiAgent.connect(true); 13586 assertNull(mService.getProxyForNetwork(null)); 13587 assertNull(mCm.getDefaultProxy()); 13588 13589 final LinkProperties lp = new LinkProperties(); 13590 lp.setInterfaceName("tun0"); 13591 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13592 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13593 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13594 lp.setHttpProxy(testProxyInfo); 13595 final UidRange vpnRange = PRIMARY_UIDRANGE; 13596 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13597 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13598 mMockVpn.setOwnerAndAdminUid(VPN_UID); 13599 mMockVpn.registerAgent(false, vpnRanges, lp); 13600 // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. 13601 // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the 13602 // proxy broadcast will get null. 13603 b1.expectNoBroadcast(500); 13604 13605 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13606 mMockVpn.connect(true /* validated */, true /* hasInternet */, 13607 false /* privateDnsProbeSent */); 13608 waitForIdle(); 13609 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13610 // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to 13611 // update their proxy data. 13612 b2.expectBroadcast(); 13613 } 13614 13615 @Test 13616 public void testProxyBroadcastWillBeSentWhenTheProxyOfNonDefaultNetworkHasChanged() 13617 throws Exception { 13618 // Set up a CELLULAR network without proxy. 13619 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13620 mCellAgent.connect(true); 13621 assertNull(mService.getProxyForNetwork(null)); 13622 assertNull(mCm.getDefaultProxy()); 13623 // CELLULAR network should be the default network. 13624 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13625 13626 // Set up a WiFi network without proxy. 13627 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13628 mWiFiAgent.connect(true); 13629 assertNull(mService.getProxyForNetwork(null)); 13630 assertNull(mCm.getDefaultProxy()); 13631 // WiFi network should be the default network. 13632 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 13633 // CELLULAR network is not the default network. 13634 assertNotEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13635 13636 // CELLULAR network is not the system default network, but it might be a per-app default 13637 // network. The proxy broadcast should be sent once its proxy has changed. 13638 final LinkProperties cellularLp = new LinkProperties(); 13639 cellularLp.setInterfaceName(MOBILE_IFNAME); 13640 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13641 final ExpectedBroadcast b = expectProxyChangeAction(); 13642 cellularLp.setHttpProxy(testProxyInfo); 13643 mCellAgent.sendLinkProperties(cellularLp); 13644 b.expectBroadcast(); 13645 } 13646 13647 @Test 13648 public void testInvalidRequestTypes() { 13649 final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), 13650 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; 13651 final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); 13652 13653 for (int reqTypeInt : invalidReqTypeInts) { 13654 assertThrows("Expect throws for invalid request type " + reqTypeInt, 13655 IllegalArgumentException.class, 13656 () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, 13657 null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, 13658 mContext.getPackageName(), getAttributionTag()) 13659 ); 13660 } 13661 } 13662 13663 @Test 13664 public void testKeepConnected() throws Exception { 13665 setAlwaysOnNetworks(false); 13666 registerDefaultNetworkCallbacks(); 13667 final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); 13668 final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() 13669 .build(); 13670 mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); 13671 13672 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13673 mCellAgent.connect(true /* validated */); 13674 13675 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 13676 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13677 13678 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13679 mWiFiAgent.connect(true /* validated */); 13680 13681 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13682 // While the default callback doesn't see the network before it's validated, the listen 13683 // sees the network come up and validate later 13684 allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 13685 allNetworksCb.expectLosing(mCellAgent); 13686 allNetworksCb.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 13687 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13688 13689 // The cell network has disconnected (see LOST above) because it was outscored and 13690 // had no requests (see setAlwaysOnNetworks(false) above) 13691 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13692 final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); 13693 mCellAgent.setScore(score); 13694 mCellAgent.connect(false /* validated */); 13695 13696 // The cell network gets torn down right away. 13697 allNetworksCb.expectAvailableCallbacksUnvalidated(mCellAgent); 13698 allNetworksCb.expect(LOST, mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13699 allNetworksCb.assertNoCallback(); 13700 13701 // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's 13702 // not disconnected immediately when outscored. 13703 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13704 final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) 13705 .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); 13706 mCellAgent.setScore(scoreKeepup); 13707 mCellAgent.connect(true /* validated */); 13708 13709 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13710 mDefaultNetworkCallback.assertNoCallback(); 13711 13712 mWiFiAgent.disconnect(); 13713 13714 allNetworksCb.expect(LOST, mWiFiAgent); 13715 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 13716 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 13717 13718 // Reconnect a WiFi network and make sure the cell network is still not torn down. 13719 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13720 mWiFiAgent.connect(true /* validated */); 13721 13722 allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiAgent); 13723 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13724 13725 // Now remove the reason to keep connected and make sure the network lingers and is 13726 // torn down. 13727 mCellAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); 13728 allNetworksCb.expectLosing(mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13729 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13730 mDefaultNetworkCallback.assertNoCallback(); 13731 13732 mCm.unregisterNetworkCallback(allNetworksCb); 13733 // mDefaultNetworkCallback will be unregistered by tearDown() 13734 } 13735 13736 private class QosCallbackMockHelper { 13737 @NonNull public final QosFilter mFilter; 13738 @NonNull public final IQosCallback mCallback; 13739 @NonNull public final TestNetworkAgentWrapper mAgentWrapper; 13740 @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); 13741 13742 QosCallbackMockHelper() throws Exception { 13743 Log.d(TAG, "QosCallbackMockHelper: "); 13744 mFilter = mock(QosFilter.class); 13745 13746 // Ensure the network is disconnected before anything else occurs 13747 assertNull(mCellAgent); 13748 13749 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13750 mCellAgent.connect(true); 13751 13752 verifyActiveNetwork(TRANSPORT_CELLULAR); 13753 waitForIdle(); 13754 final Network network = mCellAgent.getNetwork(); 13755 13756 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 13757 mCallback = pair.first; 13758 13759 doReturn(network).when(mFilter).getNetwork(); 13760 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE).when(mFilter).validate(); 13761 mAgentWrapper = mCellAgent; 13762 } 13763 13764 void registerQosCallback(@NonNull final QosFilter filter, 13765 @NonNull final IQosCallback callback) { 13766 mCallbacks.add(callback); 13767 final NetworkAgentInfo nai = 13768 mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); 13769 mService.registerQosCallbackInternal(filter, callback, nai); 13770 } 13771 13772 void tearDown() { 13773 for (int i = 0; i < mCallbacks.size(); i++) { 13774 mService.unregisterQosCallback(mCallbacks.get(i)); 13775 } 13776 } 13777 } 13778 13779 private Pair<IQosCallback, IBinder> createQosCallback() { 13780 final IQosCallback callback = mock(IQosCallback.class); 13781 final IBinder binder = mock(Binder.class); 13782 doReturn(binder).when(callback).asBinder(); 13783 doReturn(true).when(binder).isBinderAlive(); 13784 return new Pair<>(callback, binder); 13785 } 13786 13787 13788 @Test 13789 public void testQosCallbackRegistration() throws Exception { 13790 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13791 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13792 13793 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13794 .when(mQosCallbackMockHelper.mFilter).validate(); 13795 mQosCallbackMockHelper.registerQosCallback( 13796 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13797 13798 final OnQosCallbackRegister cbRegister1 = 13799 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13800 assertNotNull(cbRegister1); 13801 13802 final int registerCallbackId = cbRegister1.mQosCallbackId; 13803 mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); 13804 final OnQosCallbackUnregister cbUnregister = 13805 (OnQosCallbackUnregister) wrapper.getCallbackHistory().poll(1000, x -> true); 13806 assertNotNull(cbUnregister); 13807 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13808 assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); 13809 } 13810 13811 @Test 13812 public void testQosCallbackNoRegistrationOnValidationError() throws Exception { 13813 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13814 13815 doReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED) 13816 .when(mQosCallbackMockHelper.mFilter).validate(); 13817 mQosCallbackMockHelper.registerQosCallback( 13818 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13819 waitForIdle(); 13820 verify(mQosCallbackMockHelper.mCallback) 13821 .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); 13822 } 13823 13824 @Test 13825 public void testQosCallbackAvailableAndLost() throws Exception { 13826 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13827 final int sessionId = 10; 13828 final int qosCallbackId = 1; 13829 13830 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13831 .when(mQosCallbackMockHelper.mFilter).validate(); 13832 mQosCallbackMockHelper.registerQosCallback( 13833 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13834 waitForIdle(); 13835 13836 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13837 1, 2, 3, 4, 5, new ArrayList<>()); 13838 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13839 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13840 waitForIdle(); 13841 13842 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 13843 session.getSessionId() == sessionId 13844 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 13845 13846 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13847 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 13848 waitForIdle(); 13849 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13850 session.getSessionId() == sessionId 13851 && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); 13852 } 13853 13854 @Test 13855 public void testNrQosCallbackAvailableAndLost() throws Exception { 13856 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13857 final int sessionId = 10; 13858 final int qosCallbackId = 1; 13859 13860 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13861 .when(mQosCallbackMockHelper.mFilter).validate(); 13862 mQosCallbackMockHelper.registerQosCallback( 13863 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13864 waitForIdle(); 13865 13866 final NrQosSessionAttributes attributes = new NrQosSessionAttributes( 13867 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); 13868 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13869 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13870 waitForIdle(); 13871 13872 verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> 13873 session.getSessionId() == sessionId 13874 && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); 13875 13876 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13877 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); 13878 waitForIdle(); 13879 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13880 session.getSessionId() == sessionId 13881 && session.getSessionType() == QosSession.TYPE_NR_BEARER)); 13882 } 13883 13884 @Test @IgnoreUpTo(SC_V2) 13885 public void testQosCallbackAvailableOnValidationError() throws Exception { 13886 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13887 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13888 final int sessionId = 10; 13889 final int qosCallbackId = 1; 13890 13891 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13892 .when(mQosCallbackMockHelper.mFilter).validate(); 13893 mQosCallbackMockHelper.registerQosCallback( 13894 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13895 OnQosCallbackRegister cbRegister1 = 13896 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13897 assertNotNull(cbRegister1); 13898 final int registerCallbackId = cbRegister1.mQosCallbackId; 13899 13900 waitForIdle(); 13901 13902 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 13903 .when(mQosCallbackMockHelper.mFilter).validate(); 13904 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13905 1, 2, 3, 4, 5, new ArrayList<>()); 13906 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13907 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13908 waitForIdle(); 13909 13910 final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; 13911 cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) 13912 wrapper.getCallbackHistory().poll(1000, x -> true); 13913 assertNotNull(cbUnregister); 13914 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13915 waitForIdle(); 13916 verify(mQosCallbackMockHelper.mCallback) 13917 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 13918 } 13919 13920 @Test @IgnoreUpTo(SC_V2) 13921 public void testQosCallbackLostOnValidationError() throws Exception { 13922 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13923 final int sessionId = 10; 13924 final int qosCallbackId = 1; 13925 13926 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13927 .when(mQosCallbackMockHelper.mFilter).validate(); 13928 mQosCallbackMockHelper.registerQosCallback( 13929 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13930 waitForIdle(); 13931 EpsBearerQosSessionAttributes attributes = 13932 sendQosSessionEvent(qosCallbackId, sessionId, true); 13933 waitForIdle(); 13934 13935 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 13936 session.getSessionId() == sessionId 13937 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 13938 13939 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 13940 .when(mQosCallbackMockHelper.mFilter).validate(); 13941 13942 sendQosSessionEvent(qosCallbackId, sessionId, false); 13943 waitForIdle(); 13944 verify(mQosCallbackMockHelper.mCallback) 13945 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 13946 } 13947 13948 private EpsBearerQosSessionAttributes sendQosSessionEvent( 13949 int qosCallbackId, int sessionId, boolean available) { 13950 if (available) { 13951 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13952 1, 2, 3, 4, 5, new ArrayList<>()); 13953 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13954 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13955 return attributes; 13956 } else { 13957 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13958 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 13959 return null; 13960 } 13961 13962 } 13963 13964 @Test 13965 public void testQosCallbackTooManyRequests() throws Exception { 13966 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13967 13968 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13969 .when(mQosCallbackMockHelper.mFilter).validate(); 13970 for (int i = 0; i < 100; i++) { 13971 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 13972 13973 try { 13974 mQosCallbackMockHelper.registerQosCallback( 13975 mQosCallbackMockHelper.mFilter, pair.first); 13976 } catch (ServiceSpecificException e) { 13977 assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); 13978 if (i < 50) { 13979 fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); 13980 } 13981 13982 // As long as there is at least 50 requests, it is safe to assume it works. 13983 // Note: The count isn't being tested precisely against 100 because the counter 13984 // is shared with request network. 13985 return; 13986 } 13987 } 13988 fail("TOO_MANY_REQUESTS never thrown"); 13989 } 13990 13991 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) { 13992 mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE); 13993 } 13994 13995 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid, 13996 @NonNull final UserHandle user) { 13997 final ApplicationInfo applicationInfo = new ApplicationInfo(); 13998 applicationInfo.uid = uid; 13999 try { 14000 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 14001 eq(packageName), anyInt(), eq(user)); 14002 } catch (Exception e) { 14003 fail(e.getMessage()); 14004 } 14005 } 14006 14007 private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName, 14008 @NonNull final UserHandle user) 14009 throws Exception { 14010 doThrow(new PackageManager.NameNotFoundException(packageName)).when( 14011 mPackageManager).getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)); 14012 } 14013 14014 private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) { 14015 doReturn(hasFeature).when(mPackageManager).hasSystemFeature(eq(featureName)); 14016 } 14017 14018 private Range<Integer> getNriFirstUidRange(@NonNull final NetworkRequestInfo nri) { 14019 return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); 14020 } 14021 14022 private OemNetworkPreferences createDefaultOemNetworkPreferences( 14023 @OemNetworkPreferences.OemNetworkPreference final int preference) { 14024 // Arrange PackageManager mocks 14025 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14026 14027 // Build OemNetworkPreferences object 14028 return new OemNetworkPreferences.Builder() 14029 .addNetworkPreference(TEST_PACKAGE_NAME, preference) 14030 .build(); 14031 } 14032 14033 @Test 14034 public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() { 14035 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14036 OEM_NETWORK_PREFERENCE_UNINITIALIZED; 14037 14038 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14039 assertThrows(IllegalArgumentException.class, 14040 () -> mService.new OemNetworkRequestFactory() 14041 .createNrisFromOemNetworkPreferences( 14042 createDefaultOemNetworkPreferences(prefToTest))); 14043 } 14044 14045 @Test 14046 public void testOemNetworkRequestFactoryPreferenceOemPaid() 14047 throws Exception { 14048 // Expectations 14049 final int expectedNumOfNris = 1; 14050 final int expectedNumOfRequests = 3; 14051 14052 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14053 OEM_NETWORK_PREFERENCE_OEM_PAID; 14054 14055 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14056 final ArraySet<NetworkRequestInfo> nris = 14057 mService.new OemNetworkRequestFactory() 14058 .createNrisFromOemNetworkPreferences( 14059 createDefaultOemNetworkPreferences(prefToTest)); 14060 final NetworkRequestInfo nri = nris.iterator().next(); 14061 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14062 final List<NetworkRequest> mRequests = nri.mRequests; 14063 assertEquals(expectedNumOfNris, nris.size()); 14064 assertEquals(expectedNumOfRequests, mRequests.size()); 14065 assertTrue(mRequests.get(0).isListen()); 14066 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 14067 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 14068 assertTrue(mRequests.get(1).isRequest()); 14069 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 14070 assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); 14071 assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( 14072 mRequests.get(2).networkCapabilities)); 14073 } 14074 14075 @Test 14076 public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() 14077 throws Exception { 14078 // Expectations 14079 final int expectedNumOfNris = 1; 14080 final int expectedNumOfRequests = 2; 14081 14082 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14083 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14084 14085 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14086 final ArraySet<NetworkRequestInfo> nris = 14087 mService.new OemNetworkRequestFactory() 14088 .createNrisFromOemNetworkPreferences( 14089 createDefaultOemNetworkPreferences(prefToTest)); 14090 final NetworkRequestInfo nri = nris.iterator().next(); 14091 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14092 final List<NetworkRequest> mRequests = nri.mRequests; 14093 assertEquals(expectedNumOfNris, nris.size()); 14094 assertEquals(expectedNumOfRequests, mRequests.size()); 14095 assertTrue(mRequests.get(0).isListen()); 14096 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 14097 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 14098 assertTrue(mRequests.get(1).isRequest()); 14099 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 14100 } 14101 14102 @Test 14103 public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() 14104 throws Exception { 14105 // Expectations 14106 final int expectedNumOfNris = 1; 14107 final int expectedNumOfRequests = 1; 14108 14109 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14110 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14111 14112 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14113 final ArraySet<NetworkRequestInfo> nris = 14114 mService.new OemNetworkRequestFactory() 14115 .createNrisFromOemNetworkPreferences( 14116 createDefaultOemNetworkPreferences(prefToTest)); 14117 final NetworkRequestInfo nri = nris.iterator().next(); 14118 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14119 final List<NetworkRequest> mRequests = nri.mRequests; 14120 assertEquals(expectedNumOfNris, nris.size()); 14121 assertEquals(expectedNumOfRequests, mRequests.size()); 14122 assertTrue(mRequests.get(0).isRequest()); 14123 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 14124 } 14125 14126 @Test 14127 public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() 14128 throws Exception { 14129 // Expectations 14130 final int expectedNumOfNris = 1; 14131 final int expectedNumOfRequests = 1; 14132 14133 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14134 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14135 14136 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14137 final ArraySet<NetworkRequestInfo> nris = 14138 mService.new OemNetworkRequestFactory() 14139 .createNrisFromOemNetworkPreferences( 14140 createDefaultOemNetworkPreferences(prefToTest)); 14141 final NetworkRequestInfo nri = nris.iterator().next(); 14142 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14143 final List<NetworkRequest> mRequests = nri.mRequests; 14144 assertEquals(expectedNumOfNris, nris.size()); 14145 assertEquals(expectedNumOfRequests, mRequests.size()); 14146 assertTrue(mRequests.get(0).isRequest()); 14147 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); 14148 assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 14149 } 14150 14151 @Test 14152 public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() 14153 throws Exception { 14154 // Expectations 14155 final int expectedNumOfNris = 2; 14156 14157 // Arrange PackageManager mocks 14158 final String testPackageName2 = "com.google.apps.dialer"; 14159 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14160 mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); 14161 14162 // Build OemNetworkPreferences object 14163 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14164 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14165 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14166 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14167 .addNetworkPreference(testPackageName2, testOemPref2) 14168 .build(); 14169 14170 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14171 final ArraySet<NetworkRequestInfo> nris = 14172 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 14173 14174 assertNotNull(nris); 14175 assertEquals(expectedNumOfNris, nris.size()); 14176 } 14177 14178 @Test 14179 public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() 14180 throws Exception { 14181 // Arrange PackageManager mocks 14182 final String testPackageName2 = "com.google.apps.dialer"; 14183 final int testPackageNameUid2 = 456; 14184 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14185 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 14186 14187 // Build OemNetworkPreferences object 14188 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14189 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14190 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14191 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14192 .addNetworkPreference(testPackageName2, testOemPref2) 14193 .build(); 14194 14195 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14196 final List<NetworkRequestInfo> nris = 14197 new ArrayList<>( 14198 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 14199 pref)); 14200 14201 // Sort by uid to access nris by index 14202 nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); 14203 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); 14204 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); 14205 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); 14206 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); 14207 } 14208 14209 @Test 14210 public void testOemNetworkRequestFactoryMultipleUsersSetsUids() 14211 throws Exception { 14212 // Arrange users 14213 final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID); 14214 final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID); 14215 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE)) 14216 .when(mUserManager).getUserHandles(anyBoolean()); 14217 14218 // Arrange PackageManager mocks testing for users who have and don't have a package. 14219 mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE); 14220 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE); 14221 mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE); 14222 14223 // Build OemNetworkPreferences object 14224 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14225 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14226 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14227 .build(); 14228 14229 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14230 final List<NetworkRequestInfo> nris = 14231 new ArrayList<>( 14232 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 14233 pref)); 14234 14235 // UIDs for users with installed packages should be present. 14236 // Three users exist, but only two have the test package installed. 14237 final int expectedUidSize = 2; 14238 final List<Range<Integer>> uids = 14239 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); 14240 assertEquals(expectedUidSize, uids.size()); 14241 14242 // Sort by uid to access nris by index 14243 uids.sort(Comparator.comparingInt(uid -> uid.getLower())); 14244 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower()); 14245 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper()); 14246 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower()); 14247 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper()); 14248 } 14249 14250 @Test 14251 public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() 14252 throws Exception { 14253 // Expectations 14254 final int expectedNumOfNris = 1; 14255 final int expectedNumOfAppUids = 2; 14256 14257 // Arrange PackageManager mocks 14258 final String testPackageName2 = "com.google.apps.dialer"; 14259 final int testPackageNameUid2 = 456; 14260 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14261 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 14262 14263 // Build OemNetworkPreferences object 14264 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14265 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14266 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14267 .addNetworkPreference(testPackageName2, testOemPref) 14268 .build(); 14269 14270 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14271 final ArraySet<NetworkRequestInfo> nris = 14272 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 14273 14274 assertEquals(expectedNumOfNris, nris.size()); 14275 assertEquals(expectedNumOfAppUids, 14276 nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); 14277 } 14278 14279 @Test 14280 public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { 14281 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14282 14283 // Act on ConnectivityService.setOemNetworkPreference() 14284 assertThrows(NullPointerException.class, 14285 () -> mService.setOemNetworkPreference( 14286 null, 14287 null)); 14288 } 14289 14290 @Test 14291 public void testSetOemNetworkPreferenceFailsForNonAutomotive() 14292 throws Exception { 14293 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14294 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14295 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14296 14297 // Act on ConnectivityService.setOemNetworkPreference() 14298 assertThrows(UnsupportedOperationException.class, 14299 () -> mService.setOemNetworkPreference( 14300 createDefaultOemNetworkPreferences(networkPref), 14301 null)); 14302 } 14303 14304 @Test 14305 public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() { 14306 // Calling setOemNetworkPreference() with a test pref requires the permission 14307 // MANAGE_TEST_NETWORKS. 14308 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14309 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14310 OEM_NETWORK_PREFERENCE_TEST; 14311 14312 // Act on ConnectivityService.setOemNetworkPreference() 14313 assertThrows(SecurityException.class, 14314 () -> mService.setOemNetworkPreference( 14315 createDefaultOemNetworkPreferences(networkPref), 14316 null)); 14317 } 14318 14319 @Test 14320 public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() { 14321 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST); 14322 } 14323 14324 @Test 14325 public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() { 14326 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY); 14327 } 14328 14329 private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest( 14330 @OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) { 14331 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14332 final String secondPackage = "does.not.matter"; 14333 14334 // A valid test request would only have a single mapping. 14335 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14336 .addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest) 14337 .addNetworkPreference(secondPackage, oemNetworkPreferenceForTest) 14338 .build(); 14339 14340 // Act on ConnectivityService.setOemNetworkPreference() 14341 assertThrows(IllegalArgumentException.class, 14342 () -> mService.setOemNetworkPreference(pref, null)); 14343 } 14344 14345 private void setOemNetworkPreferenceAgentConnected(final int transportType, 14346 final boolean connectAgent) throws Exception { 14347 switch(transportType) { 14348 // Corresponds to a metered cellular network. Will be used for the default network. 14349 case TRANSPORT_CELLULAR: 14350 if (!connectAgent) { 14351 mCellAgent.disconnect(); 14352 break; 14353 } 14354 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14355 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 14356 mCellAgent.connect(true); 14357 break; 14358 // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. 14359 case TRANSPORT_ETHERNET: 14360 if (!connectAgent) { 14361 stopOemManagedNetwork(); 14362 break; 14363 } 14364 startOemManagedNetwork(true); 14365 break; 14366 // Corresponds to unmetered Wi-Fi. 14367 case TRANSPORT_WIFI: 14368 if (!connectAgent) { 14369 mWiFiAgent.disconnect(); 14370 break; 14371 } 14372 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 14373 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 14374 mWiFiAgent.connect(true); 14375 break; 14376 default: 14377 throw new AssertionError("Unsupported transport type passed in."); 14378 14379 } 14380 waitForIdle(); 14381 } 14382 14383 private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { 14384 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 14385 mEthernetAgent.addCapability( 14386 isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); 14387 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14388 mEthernetAgent.connect(true); 14389 } 14390 14391 private void stopOemManagedNetwork() { 14392 mEthernetAgent.disconnect(); 14393 waitForIdle(); 14394 } 14395 14396 private void verifyMultipleDefaultNetworksTracksCorrectly( 14397 final int expectedOemRequestsSize, 14398 @NonNull final Network expectedDefaultNetwork, 14399 @NonNull final Network expectedPerAppNetwork) { 14400 // The current test setup assumes two tracked default network requests; one for the default 14401 // network and the other for the OEM network preference being tested. This will be validated 14402 // each time to confirm it doesn't change under test. 14403 final int expectedDefaultNetworkRequestsSize = 2; 14404 assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); 14405 for (final NetworkRequestInfo defaultRequest : mService.mDefaultNetworkRequests) { 14406 final Network defaultNetwork = defaultRequest.getSatisfier() == null 14407 ? null : defaultRequest.getSatisfier().network(); 14408 // If this is the default request. 14409 if (defaultRequest == mService.mDefaultRequest) { 14410 assertEquals( 14411 expectedDefaultNetwork, 14412 defaultNetwork); 14413 // Make sure this value doesn't change. 14414 assertEquals(1, defaultRequest.mRequests.size()); 14415 continue; 14416 } 14417 assertEquals(expectedPerAppNetwork, defaultNetwork); 14418 assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); 14419 } 14420 verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); 14421 } 14422 14423 /** 14424 * Verify default callbacks for 'available' fire as expected. This will only run if 14425 * registerDefaultNetworkCallbacks() was executed prior and will only be different if the 14426 * setOemNetworkPreference() per-app API was used for the current process. 14427 * @param expectedSystemDefault the expected network for the system default. 14428 * @param expectedPerAppDefault the expected network for the current process's default. 14429 */ 14430 private void verifyMultipleDefaultCallbacks( 14431 @NonNull final Network expectedSystemDefault, 14432 @NonNull final Network expectedPerAppDefault) { 14433 if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault 14434 && mService.mNoServiceNetwork.network() != expectedSystemDefault) { 14435 // getLastAvailableNetwork() is used as this method can be called successively with 14436 // the same network to validate therefore expectAvailableThenValidatedCallbacks 14437 // can't be used. 14438 assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), 14439 expectedSystemDefault); 14440 } 14441 if (null != mDefaultNetworkCallback && null != expectedPerAppDefault 14442 && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { 14443 assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), 14444 expectedPerAppDefault); 14445 } 14446 } 14447 14448 private void registerDefaultNetworkCallbacks() { 14449 if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null 14450 || mProfileDefaultNetworkCallback != null 14451 || mProfileDefaultNetworkCallbackAsAppUid2 != null 14452 || mTestPackageDefaultNetworkCallback2 != null 14453 || mTestPackageDefaultNetworkCallback != null) { 14454 throw new IllegalStateException("Default network callbacks already registered"); 14455 } 14456 14457 mSystemDefaultNetworkCallback = new TestNetworkCallback(); 14458 mDefaultNetworkCallback = new TestNetworkCallback(); 14459 mProfileDefaultNetworkCallback = new TestNetworkCallback(); 14460 mTestPackageDefaultNetworkCallback = new TestNetworkCallback(); 14461 mProfileDefaultNetworkCallbackAsAppUid2 = new TestNetworkCallback(); 14462 mTestPackageDefaultNetworkCallback2 = new TestNetworkCallback(); 14463 mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, 14464 new Handler(ConnectivityThread.getInstanceLooper())); 14465 mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); 14466 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, 14467 TEST_WORK_PROFILE_APP_UID); 14468 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID); 14469 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallbackAsAppUid2, 14470 TEST_WORK_PROFILE_APP_UID_2); 14471 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback2, 14472 TEST_PACKAGE_UID2); 14473 // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. 14474 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 14475 } 14476 14477 private void unregisterDefaultNetworkCallbacks() { 14478 if (null != mDefaultNetworkCallback) { 14479 mCm.unregisterNetworkCallback(mDefaultNetworkCallback); 14480 } 14481 if (null != mSystemDefaultNetworkCallback) { 14482 mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); 14483 } 14484 if (null != mProfileDefaultNetworkCallback) { 14485 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); 14486 } 14487 if (null != mTestPackageDefaultNetworkCallback) { 14488 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback); 14489 } 14490 if (null != mProfileDefaultNetworkCallbackAsAppUid2) { 14491 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallbackAsAppUid2); 14492 } 14493 if (null != mTestPackageDefaultNetworkCallback2) { 14494 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2); 14495 } 14496 mSystemDefaultNetworkCallback = null; 14497 mDefaultNetworkCallback = null; 14498 mProfileDefaultNetworkCallback = null; 14499 mTestPackageDefaultNetworkCallback = null; 14500 mProfileDefaultNetworkCallbackAsAppUid2 = null; 14501 mTestPackageDefaultNetworkCallback2 = null; 14502 } 14503 14504 private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( 14505 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14506 throws Exception { 14507 final int testPackageNameUid = TEST_PACKAGE_UID; 14508 final String testPackageName = "per.app.defaults.package"; 14509 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14510 networkPrefToSetup, testPackageNameUid, testPackageName); 14511 } 14512 14513 private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( 14514 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14515 throws Exception { 14516 final int testPackageNameUid = Process.myUid(); 14517 final String testPackageName = "per.app.defaults.package"; 14518 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14519 networkPrefToSetup, testPackageNameUid, testPackageName); 14520 } 14521 14522 private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14523 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14524 final int testPackageUid, @NonNull final String testPackageName) throws Exception { 14525 // Only the default request should be included at start. 14526 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14527 14528 final UidRangeParcel[] uidRanges = 14529 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14530 setupSetOemNetworkPreferenceForPreferenceTest( 14531 networkPrefToSetup, uidRanges, testPackageName); 14532 } 14533 14534 private void setupSetOemNetworkPreferenceForPreferenceTest( 14535 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14536 @NonNull final UidRangeParcel[] uidRanges, 14537 @NonNull final String testPackageName) throws Exception { 14538 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14539 testPackageName, PRIMARY_USER_HANDLE, true /* hasAutomotiveFeature */); 14540 } 14541 14542 private void setupSetOemNetworkPreferenceForPreferenceTest( 14543 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14544 @NonNull final UidRangeParcel[] uidRanges, 14545 @NonNull final String testPackageName, 14546 @NonNull final UserHandle user) throws Exception { 14547 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14548 testPackageName, user, true /* hasAutomotiveFeature */); 14549 } 14550 14551 private void setupSetOemNetworkPreferenceForPreferenceTest( 14552 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14553 @NonNull final UidRangeParcel[] uidRanges, 14554 @NonNull final String testPackageName, 14555 @NonNull final UserHandle user, 14556 final boolean hasAutomotiveFeature) throws Exception { 14557 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 14558 14559 // These tests work off a single UID therefore using 'start' is valid. 14560 mockGetApplicationInfo(testPackageName, uidRanges[0].start, user); 14561 14562 setOemNetworkPreference(networkPrefToSetup, testPackageName); 14563 } 14564 14565 private void setOemNetworkPreference(final int networkPrefToSetup, 14566 @NonNull final String... testPackageNames) 14567 throws Exception { 14568 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14569 14570 // Build OemNetworkPreferences object 14571 final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); 14572 for (final String packageName : testPackageNames) { 14573 builder.addNetworkPreference(packageName, networkPrefToSetup); 14574 } 14575 final OemNetworkPreferences pref = builder.build(); 14576 14577 // Act on ConnectivityService.setOemNetworkPreference() 14578 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 14579 mService.setOemNetworkPreference(pref, oemPrefListener); 14580 14581 // Verify call returned successfully 14582 oemPrefListener.expectOnComplete(); 14583 } 14584 14585 private static class TestOemListenerCallback implements IOnCompleteListener { 14586 final CompletableFuture<Object> mDone = new CompletableFuture<>(); 14587 14588 @Override 14589 public void onComplete() { 14590 mDone.complete(new Object()); 14591 } 14592 14593 void expectOnComplete() { 14594 try { 14595 mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 14596 } catch (TimeoutException e) { 14597 fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); 14598 } catch (Exception e) { 14599 fail(e.getMessage()); 14600 } 14601 } 14602 14603 @Override 14604 public IBinder asBinder() { 14605 return null; 14606 } 14607 } 14608 14609 @Test 14610 public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { 14611 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14612 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14613 final int expectedOemPrefRequestSize = 1; 14614 registerDefaultNetworkCallbacks(); 14615 14616 // Setup the test process to use networkPref for their default network. 14617 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14618 14619 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14620 // The active network for the default should be null at this point as this is a retricted 14621 // network. 14622 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14623 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14624 null, 14625 mEthernetAgent.getNetwork()); 14626 14627 // Verify that the active network is correct 14628 verifyActiveNetwork(TRANSPORT_ETHERNET); 14629 // default NCs will be unregistered in tearDown 14630 } 14631 14632 @Test 14633 public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { 14634 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14635 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14636 final int expectedOemPrefRequestSize = 1; 14637 registerDefaultNetworkCallbacks(); 14638 14639 // Setup the test process to use networkPref for their default network. 14640 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14641 14642 // Returns true by default when no network is available. 14643 assertTrue(mCm.isActiveNetworkMetered()); 14644 14645 // Connect to an unmetered restricted network that will only be available to the OEM pref. 14646 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 14647 mEthernetAgent.addCapability(NET_CAPABILITY_OEM_PAID); 14648 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 14649 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14650 mEthernetAgent.connect(true); 14651 waitForIdle(); 14652 14653 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14654 null, 14655 mEthernetAgent.getNetwork()); 14656 14657 assertFalse(mCm.isActiveNetworkMetered()); 14658 // default NCs will be unregistered in tearDown 14659 } 14660 14661 @Test 14662 public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { 14663 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14664 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14665 final int expectedOemPrefRequestSize = 1; 14666 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14667 14668 // Register the default network callback before the pref is already set. This means that 14669 // the policy will be applied to the callback on setOemNetworkPreference(). 14670 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14671 defaultNetworkCallback.assertNoCallback(); 14672 14673 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14674 withPermission(NETWORK_SETTINGS, () -> 14675 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14676 new Handler(ConnectivityThread.getInstanceLooper()))); 14677 14678 // Setup the test process to use networkPref for their default network. 14679 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14680 14681 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14682 // The active nai for the default is null at this point as this is a restricted network. 14683 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14684 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14685 null, 14686 mEthernetAgent.getNetwork()); 14687 14688 // At this point with a restricted network used, the available callback should trigger. 14689 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14690 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14691 otherUidDefaultCallback.assertNoCallback(); 14692 14693 // Now bring down the default network which should trigger a LOST callback. 14694 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14695 14696 // At this point, with no network is available, the lost callback should trigger 14697 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14698 otherUidDefaultCallback.assertNoCallback(); 14699 14700 // Confirm we can unregister without issues. 14701 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14702 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14703 } 14704 14705 @Test 14706 public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { 14707 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14708 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14709 final int expectedOemPrefRequestSize = 1; 14710 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14711 14712 // Setup the test process to use networkPref for their default network. 14713 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14714 14715 // Register the default network callback after the pref is already set. This means that 14716 // the policy will be applied to the callback on requestNetwork(). 14717 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14718 defaultNetworkCallback.assertNoCallback(); 14719 14720 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14721 withPermission(NETWORK_SETTINGS, () -> 14722 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14723 new Handler(ConnectivityThread.getInstanceLooper()))); 14724 14725 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14726 // The active nai for the default is null at this point as this is a restricted network. 14727 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14728 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14729 null, 14730 mEthernetAgent.getNetwork()); 14731 14732 // At this point with a restricted network used, the available callback should trigger 14733 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14734 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14735 otherUidDefaultCallback.assertNoCallback(); 14736 14737 // Now bring down the default network which should trigger a LOST callback. 14738 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14739 otherUidDefaultCallback.assertNoCallback(); 14740 14741 // At this point, with no network is available, the lost callback should trigger 14742 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14743 otherUidDefaultCallback.assertNoCallback(); 14744 14745 // Confirm we can unregister without issues. 14746 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14747 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14748 } 14749 14750 @Test 14751 public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { 14752 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14753 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14754 final int expectedOemPrefRequestSize = 1; 14755 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14756 final int userId = UserHandle.getUserId(Process.myUid()); 14757 14758 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14759 defaultNetworkCallback.assertNoCallback(); 14760 14761 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14762 withPermission(NETWORK_SETTINGS, () -> 14763 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14764 new Handler(ConnectivityThread.getInstanceLooper()))); 14765 14766 // Setup a process different than the test process to use the default network. This means 14767 // that the defaultNetworkCallback won't be tracked by the per-app policy. 14768 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 14769 14770 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14771 // The active nai for the default is null at this point as this is a restricted network. 14772 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14773 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14774 null, 14775 mEthernetAgent.getNetwork()); 14776 14777 // As this callback does not have access to the OEM_PAID network, it will not fire. 14778 defaultNetworkCallback.assertNoCallback(); 14779 assertDefaultNetworkCapabilities(userId /* no networks */); 14780 14781 // The other UID does have access, and gets a callback. 14782 otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14783 14784 // Bring up unrestricted cellular. This should now satisfy the default network. 14785 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14786 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14787 mCellAgent.getNetwork(), 14788 mEthernetAgent.getNetwork()); 14789 14790 // At this point with an unrestricted network used, the available callback should trigger 14791 // The other UID is unaffected and remains on the paid network. 14792 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 14793 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCellAgent.getNetwork()); 14794 assertDefaultNetworkCapabilities(userId, mCellAgent); 14795 otherUidDefaultCallback.assertNoCallback(); 14796 14797 // Now bring down the per-app network. 14798 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14799 14800 // Since the callback didn't use the per-app network, only the other UID gets a callback. 14801 // Because the preference specifies no fallback, it does not switch to cellular. 14802 defaultNetworkCallback.assertNoCallback(); 14803 otherUidDefaultCallback.expect(LOST, mEthernetAgent); 14804 14805 // Now bring down the default network. 14806 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14807 14808 // As this callback was tracking the default, this should now trigger. 14809 defaultNetworkCallback.expect(LOST, mCellAgent); 14810 otherUidDefaultCallback.assertNoCallback(); 14811 14812 // Confirm we can unregister without issues. 14813 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14814 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14815 } 14816 14817 /** 14818 * This method assumes that the same uidRanges input will be used to verify that dependencies 14819 * are called as expected. 14820 */ 14821 private void verifySetOemNetworkPreferenceForPreference( 14822 @NonNull final UidRangeParcel[] uidRanges, 14823 final int addUidRangesNetId, 14824 final int addUidRangesTimes, 14825 final int removeUidRangesNetId, 14826 final int removeUidRangesTimes, 14827 final boolean shouldDestroyNetwork) throws RemoteException { 14828 verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, 14829 addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, 14830 shouldDestroyNetwork); 14831 } 14832 14833 private void verifySetOemNetworkPreferenceForPreference( 14834 @NonNull final UidRangeParcel[] addedUidRanges, 14835 @NonNull final UidRangeParcel[] removedUidRanges, 14836 final int addUidRangesNetId, 14837 final int addUidRangesTimes, 14838 final int removeUidRangesNetId, 14839 final int removeUidRangesTimes, 14840 final boolean shouldDestroyNetwork) throws RemoteException { 14841 final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; 14842 final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; 14843 14844 // Validate that add/remove uid range (with oem priority) to/from netd. 14845 verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config -> 14846 (useAnyIdForAdd ? true : addUidRangesNetId == config.netId) 14847 && Arrays.equals(addedUidRanges, config.uidRanges) 14848 && PREFERENCE_ORDER_OEM == config.subPriority)); 14849 verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel( 14850 argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId) 14851 && Arrays.equals(removedUidRanges, config.uidRanges) 14852 && PREFERENCE_ORDER_OEM == config.subPriority)); 14853 if (shouldDestroyNetwork) { 14854 verify(mMockNetd, times(1)) 14855 .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); 14856 } 14857 reset(mMockNetd); 14858 } 14859 14860 /** 14861 * Test the tracked default requests allows test requests without standard setup. 14862 */ 14863 @Test 14864 public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception { 14865 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14866 OEM_NETWORK_PREFERENCE_TEST; 14867 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14868 } 14869 14870 /** 14871 * Test the tracked default requests allows test only requests without standard setup. 14872 */ 14873 @Test 14874 public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks() 14875 throws Exception { 14876 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14877 OEM_NETWORK_PREFERENCE_TEST_ONLY; 14878 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14879 } 14880 14881 private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref) 14882 throws Exception { 14883 // The caller must have the MANAGE_TEST_NETWORKS permission. 14884 final int testPackageUid = 123; 14885 final String validTestPackageName = "does.not.matter"; 14886 final UidRangeParcel[] uidRanges = 14887 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14888 mServiceContext.setPermission( 14889 Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 14890 14891 // Put the system into a state in which setOemNetworkPreference() would normally fail. This 14892 // will confirm that a valid test request can bypass these checks. 14893 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14894 mServiceContext.setPermission( 14895 Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED); 14896 14897 // Validate the starting requests only includes the system default request. 14898 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14899 14900 // Add an OEM default network request to track. 14901 setupSetOemNetworkPreferenceForPreferenceTest( 14902 networkPref, uidRanges, validTestPackageName, PRIMARY_USER_HANDLE, 14903 false /* hasAutomotiveFeature */); 14904 14905 // Two requests should now exist; the system default and the test request. 14906 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14907 } 14908 14909 /** 14910 * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). 14911 */ 14912 @Test 14913 public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { 14914 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14915 OEM_NETWORK_PREFERENCE_OEM_PAID; 14916 final int testPackageUid = 123; 14917 final String testPackageName = "com.google.apps.contacts"; 14918 final UidRangeParcel[] uidRanges = 14919 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14920 14921 // Validate the starting requests only includes the system default request. 14922 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14923 14924 // Add an OEM default network request to track. 14925 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 14926 14927 // Two requests should exist, one for the fallback and one for the pref. 14928 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14929 14930 networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14931 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 14932 14933 // Two requests should still exist validating the previous per-app request was replaced. 14934 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14935 } 14936 14937 /** 14938 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 14939 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 14940 */ 14941 @Test 14942 public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() 14943 throws Exception { 14944 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14945 OEM_NETWORK_PREFERENCE_OEM_PAID; 14946 14947 // Arrange PackageManager mocks 14948 final UidRangeParcel[] uidRanges = 14949 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14950 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14951 14952 // Verify the starting state. No networks should be connected. 14953 verifySetOemNetworkPreferenceForPreference(uidRanges, 14954 OEM_PREF_ANY_NET_ID, 0 /* times */, 14955 OEM_PREF_ANY_NET_ID, 0 /* times */, 14956 false /* shouldDestroyNetwork */); 14957 14958 // Test lowest to highest priority requests. 14959 // Bring up metered cellular. This will satisfy the fallback network. 14960 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14961 verifySetOemNetworkPreferenceForPreference(uidRanges, 14962 mCellAgent.getNetwork().netId, 1 /* times */, 14963 OEM_PREF_ANY_NET_ID, 0 /* times */, 14964 false /* shouldDestroyNetwork */); 14965 14966 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14967 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14968 verifySetOemNetworkPreferenceForPreference(uidRanges, 14969 mEthernetAgent.getNetwork().netId, 1 /* times */, 14970 mCellAgent.getNetwork().netId, 1 /* times */, 14971 false /* shouldDestroyNetwork */); 14972 14973 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 14974 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14975 verifySetOemNetworkPreferenceForPreference(uidRanges, 14976 mWiFiAgent.getNetwork().netId, 1 /* times */, 14977 mEthernetAgent.getNetwork().netId, 1 /* times */, 14978 false /* shouldDestroyNetwork */); 14979 14980 // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. 14981 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14982 // netd should not be called as default networks haven't changed. 14983 verifySetOemNetworkPreferenceForPreference(uidRanges, 14984 OEM_PREF_ANY_NET_ID, 0 /* times */, 14985 OEM_PREF_ANY_NET_ID, 0 /* times */, 14986 false /* shouldDestroyNetwork */); 14987 14988 // Disconnecting unmetered should put PANS on lowest priority fallback request. 14989 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 14990 verifySetOemNetworkPreferenceForPreference(uidRanges, 14991 mCellAgent.getNetwork().netId, 1 /* times */, 14992 mWiFiAgent.getNetwork().netId, 0 /* times */, 14993 true /* shouldDestroyNetwork */); 14994 14995 // Disconnecting the fallback network should result in no connectivity. 14996 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14997 verifySetOemNetworkPreferenceForPreference(uidRanges, 14998 OEM_PREF_ANY_NET_ID, 0 /* times */, 14999 mCellAgent.getNetwork().netId, 0 /* times */, 15000 true /* shouldDestroyNetwork */); 15001 } 15002 15003 /** 15004 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 15005 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 15006 */ 15007 @Test 15008 public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() 15009 throws Exception { 15010 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15011 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 15012 15013 // Arrange PackageManager mocks 15014 final UidRangeParcel[] uidRanges = 15015 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15016 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15017 15018 // Verify the starting state. This preference doesn't support using the fallback network 15019 // therefore should be on the disconnected network as it has no networks to connect to. 15020 verifySetOemNetworkPreferenceForPreference(uidRanges, 15021 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15022 OEM_PREF_ANY_NET_ID, 0 /* times */, 15023 false /* shouldDestroyNetwork */); 15024 15025 // Test lowest to highest priority requests. 15026 // Bring up metered cellular. This will satisfy the fallback network. 15027 // This preference should not use this network as it doesn't support fallback usage. 15028 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15029 verifySetOemNetworkPreferenceForPreference(uidRanges, 15030 OEM_PREF_ANY_NET_ID, 0 /* times */, 15031 OEM_PREF_ANY_NET_ID, 0 /* times */, 15032 false /* shouldDestroyNetwork */); 15033 15034 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15035 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15036 verifySetOemNetworkPreferenceForPreference(uidRanges, 15037 mEthernetAgent.getNetwork().netId, 1 /* times */, 15038 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15039 false /* shouldDestroyNetwork */); 15040 15041 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15042 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15043 verifySetOemNetworkPreferenceForPreference(uidRanges, 15044 mWiFiAgent.getNetwork().netId, 1 /* times */, 15045 mEthernetAgent.getNetwork().netId, 1 /* times */, 15046 false /* shouldDestroyNetwork */); 15047 15048 // Disconnecting unmetered should put PANS on OEM_PAID. 15049 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15050 verifySetOemNetworkPreferenceForPreference(uidRanges, 15051 mEthernetAgent.getNetwork().netId, 1 /* times */, 15052 mWiFiAgent.getNetwork().netId, 0 /* times */, 15053 true /* shouldDestroyNetwork */); 15054 15055 // Disconnecting OEM_PAID should result in no connectivity. 15056 // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. 15057 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15058 verifySetOemNetworkPreferenceForPreference(uidRanges, 15059 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15060 mEthernetAgent.getNetwork().netId, 0 /* times */, 15061 true /* shouldDestroyNetwork */); 15062 } 15063 15064 /** 15065 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 15066 * NET_CAPABILITY_OEM_PAID 15067 * This preference should only apply to OEM_PAID networks. 15068 */ 15069 @Test 15070 public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() 15071 throws Exception { 15072 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15073 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 15074 15075 // Arrange PackageManager mocks 15076 final UidRangeParcel[] uidRanges = 15077 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15078 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15079 15080 // Verify the starting state. This preference doesn't support using the fallback network 15081 // therefore should be on the disconnected network as it has no networks to connect to. 15082 verifySetOemNetworkPreferenceForPreference(uidRanges, 15083 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15084 OEM_PREF_ANY_NET_ID, 0 /* times */, 15085 false /* shouldDestroyNetwork */); 15086 15087 // Bring up metered cellular. This should not apply to this preference. 15088 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15089 verifySetOemNetworkPreferenceForPreference(uidRanges, 15090 OEM_PREF_ANY_NET_ID, 0 /* times */, 15091 OEM_PREF_ANY_NET_ID, 0 /* times */, 15092 false /* shouldDestroyNetwork */); 15093 15094 // Bring up unmetered Wi-Fi. This should not apply to this preference. 15095 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15096 verifySetOemNetworkPreferenceForPreference(uidRanges, 15097 OEM_PREF_ANY_NET_ID, 0 /* times */, 15098 OEM_PREF_ANY_NET_ID, 0 /* times */, 15099 false /* shouldDestroyNetwork */); 15100 15101 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15102 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15103 verifySetOemNetworkPreferenceForPreference(uidRanges, 15104 mEthernetAgent.getNetwork().netId, 1 /* times */, 15105 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15106 false /* shouldDestroyNetwork */); 15107 15108 // Disconnecting OEM_PAID should result in no connectivity. 15109 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15110 verifySetOemNetworkPreferenceForPreference(uidRanges, 15111 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15112 mEthernetAgent.getNetwork().netId, 0 /* times */, 15113 true /* shouldDestroyNetwork */); 15114 } 15115 15116 /** 15117 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 15118 * NET_CAPABILITY_OEM_PRIVATE 15119 * This preference should only apply to OEM_PRIVATE networks. 15120 */ 15121 @Test 15122 public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() 15123 throws Exception { 15124 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15125 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15126 15127 // Arrange PackageManager mocks 15128 final UidRangeParcel[] uidRanges = 15129 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15130 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15131 15132 // Verify the starting state. This preference doesn't support using the fallback network 15133 // therefore should be on the disconnected network as it has no networks to connect to. 15134 verifySetOemNetworkPreferenceForPreference(uidRanges, 15135 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15136 OEM_PREF_ANY_NET_ID, 0 /* times */, 15137 false /* shouldDestroyNetwork */); 15138 15139 // Bring up metered cellular. This should not apply to this preference. 15140 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15141 verifySetOemNetworkPreferenceForPreference(uidRanges, 15142 OEM_PREF_ANY_NET_ID, 0 /* times */, 15143 OEM_PREF_ANY_NET_ID, 0 /* times */, 15144 false /* shouldDestroyNetwork */); 15145 15146 // Bring up unmetered Wi-Fi. This should not apply to this preference. 15147 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15148 verifySetOemNetworkPreferenceForPreference(uidRanges, 15149 OEM_PREF_ANY_NET_ID, 0 /* times */, 15150 OEM_PREF_ANY_NET_ID, 0 /* times */, 15151 false /* shouldDestroyNetwork */); 15152 15153 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 15154 startOemManagedNetwork(false); 15155 verifySetOemNetworkPreferenceForPreference(uidRanges, 15156 mEthernetAgent.getNetwork().netId, 1 /* times */, 15157 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15158 false /* shouldDestroyNetwork */); 15159 15160 // Disconnecting OEM_PRIVATE should result in no connectivity. 15161 stopOemManagedNetwork(); 15162 verifySetOemNetworkPreferenceForPreference(uidRanges, 15163 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15164 mEthernetAgent.getNetwork().netId, 0 /* times */, 15165 true /* shouldDestroyNetwork */); 15166 } 15167 15168 @Test 15169 public void testMultilayerForMultipleUsersEvaluatesCorrectly() 15170 throws Exception { 15171 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15172 OEM_NETWORK_PREFERENCE_OEM_PAID; 15173 15174 // Arrange users 15175 final int secondUser = 10; 15176 final UserHandle secondUserHandle = new UserHandle(secondUser); 15177 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 15178 .getUserHandles(anyBoolean()); 15179 15180 // Arrange PackageManager mocks 15181 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 15182 final UidRangeParcel[] uidRanges = 15183 toUidRangeStableParcels( 15184 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 15185 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 15186 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15187 15188 // Verify the starting state. No networks should be connected. 15189 verifySetOemNetworkPreferenceForPreference(uidRanges, 15190 OEM_PREF_ANY_NET_ID, 0 /* times */, 15191 OEM_PREF_ANY_NET_ID, 0 /* times */, 15192 false /* shouldDestroyNetwork */); 15193 15194 // Test that we correctly add the expected values for multiple users. 15195 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15196 verifySetOemNetworkPreferenceForPreference(uidRanges, 15197 mCellAgent.getNetwork().netId, 1 /* times */, 15198 OEM_PREF_ANY_NET_ID, 0 /* times */, 15199 false /* shouldDestroyNetwork */); 15200 15201 // Test that we correctly remove the expected values for multiple users. 15202 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15203 verifySetOemNetworkPreferenceForPreference(uidRanges, 15204 OEM_PREF_ANY_NET_ID, 0 /* times */, 15205 mCellAgent.getNetwork().netId, 0 /* times */, 15206 true /* shouldDestroyNetwork */); 15207 } 15208 15209 @Test 15210 public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() 15211 throws Exception { 15212 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15213 OEM_NETWORK_PREFERENCE_OEM_PAID; 15214 15215 // Arrange users 15216 final int secondUser = 10; 15217 final UserHandle secondUserHandle = new UserHandle(secondUser); 15218 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 15219 15220 // Arrange PackageManager mocks 15221 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 15222 final UidRangeParcel[] uidRangesSingleUser = 15223 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15224 final UidRangeParcel[] uidRangesBothUsers = 15225 toUidRangeStableParcels( 15226 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 15227 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 15228 setupSetOemNetworkPreferenceForPreferenceTest( 15229 networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); 15230 15231 // Verify the starting state. No networks should be connected. 15232 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 15233 OEM_PREF_ANY_NET_ID, 0 /* times */, 15234 OEM_PREF_ANY_NET_ID, 0 /* times */, 15235 false /* shouldDestroyNetwork */); 15236 15237 // Test that we correctly add the expected values for multiple users. 15238 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15239 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 15240 mCellAgent.getNetwork().netId, 1 /* times */, 15241 OEM_PREF_ANY_NET_ID, 0 /* times */, 15242 false /* shouldDestroyNetwork */); 15243 15244 // Send a broadcast indicating a user was added. 15245 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 15246 .getUserHandles(anyBoolean()); 15247 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 15248 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 15249 processBroadcast(addedIntent); 15250 15251 // Test that we correctly add values for all users and remove for the single user. 15252 verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, 15253 mCellAgent.getNetwork().netId, 1 /* times */, 15254 mCellAgent.getNetwork().netId, 1 /* times */, 15255 false /* shouldDestroyNetwork */); 15256 15257 // Send a broadcast indicating a user was removed. 15258 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 15259 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 15260 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 15261 processBroadcast(removedIntent); 15262 15263 // Test that we correctly add values for the single user and remove for the all users. 15264 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, 15265 mCellAgent.getNetwork().netId, 1 /* times */, 15266 mCellAgent.getNetwork().netId, 1 /* times */, 15267 false /* shouldDestroyNetwork */); 15268 } 15269 15270 @Test 15271 public void testMultilayerForPackageChangesEvaluatesCorrectly() 15272 throws Exception { 15273 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15274 OEM_NETWORK_PREFERENCE_OEM_PAID; 15275 final String packageScheme = "package:"; 15276 15277 // Arrange PackageManager mocks 15278 final String packageToInstall = "package.to.install"; 15279 final int packageToInstallUid = 81387; 15280 final UidRangeParcel[] uidRangesSinglePackage = 15281 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15282 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 15283 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 15284 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); 15285 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); 15286 15287 // Verify the starting state. No networks should be connected. 15288 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 15289 OEM_PREF_ANY_NET_ID, 0 /* times */, 15290 OEM_PREF_ANY_NET_ID, 0 /* times */, 15291 false /* shouldDestroyNetwork */); 15292 15293 // Test that we correctly add the expected values for installed packages. 15294 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15295 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 15296 mCellAgent.getNetwork().netId, 1 /* times */, 15297 OEM_PREF_ANY_NET_ID, 0 /* times */, 15298 false /* shouldDestroyNetwork */); 15299 15300 // Set the system to recognize the package to be installed 15301 mockGetApplicationInfo(packageToInstall, packageToInstallUid); 15302 final UidRangeParcel[] uidRangesAllPackages = 15303 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); 15304 15305 // Send a broadcast indicating a package was installed. 15306 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 15307 addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 15308 processBroadcast(addedIntent); 15309 15310 // Test the single package is removed and the combined packages are added. 15311 verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, 15312 mCellAgent.getNetwork().netId, 1 /* times */, 15313 mCellAgent.getNetwork().netId, 1 /* times */, 15314 false /* shouldDestroyNetwork */); 15315 15316 // Set the system to no longer recognize the package to be installed 15317 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 15318 15319 // Send a broadcast indicating a package was removed. 15320 final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); 15321 removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 15322 processBroadcast(removedIntent); 15323 15324 // Test the combined packages are removed and the single package is added. 15325 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, 15326 mCellAgent.getNetwork().netId, 1 /* times */, 15327 mCellAgent.getNetwork().netId, 1 /* times */, 15328 false /* shouldDestroyNetwork */); 15329 15330 // Set the system to change the installed package's uid 15331 final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; 15332 mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); 15333 final UidRangeParcel[] uidRangesReplacedPackage = 15334 toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); 15335 15336 // Send a broadcast indicating a package was replaced. 15337 final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); 15338 replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); 15339 processBroadcast(replacedIntent); 15340 15341 // Test the original uid is removed and is replaced with the new uid. 15342 verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, 15343 mCellAgent.getNetwork().netId, 1 /* times */, 15344 mCellAgent.getNetwork().netId, 1 /* times */, 15345 false /* shouldDestroyNetwork */); 15346 } 15347 15348 /** 15349 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 15350 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 15351 */ 15352 @Test 15353 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() 15354 throws Exception { 15355 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15356 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 15357 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15358 final int expectedDefaultRequestSize = 2; 15359 final int expectedOemPrefRequestSize = 3; 15360 registerDefaultNetworkCallbacks(); 15361 15362 // The fallback as well as the OEM preference should now be tracked. 15363 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15364 15365 // Test lowest to highest priority requests. 15366 // Bring up metered cellular. This will satisfy the fallback network. 15367 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15368 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15369 mCellAgent.getNetwork(), 15370 mCellAgent.getNetwork()); 15371 15372 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15373 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15374 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15375 mCellAgent.getNetwork(), 15376 mEthernetAgent.getNetwork()); 15377 15378 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15379 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15380 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15381 mWiFiAgent.getNetwork(), 15382 mWiFiAgent.getNetwork()); 15383 15384 // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. 15385 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15386 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15387 mCellAgent.getNetwork(), 15388 mEthernetAgent.getNetwork()); 15389 15390 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 15391 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15392 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15393 null, 15394 mEthernetAgent.getNetwork()); 15395 15396 // Disconnecting OEM_PAID will put both on null as it is the last network. 15397 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15398 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15399 null, 15400 null); 15401 15402 // default callbacks will be unregistered in tearDown 15403 } 15404 15405 @Test 15406 public void testNetworkFactoryRequestsWithMultilayerRequest() 15407 throws Exception { 15408 // First use OEM_PAID preference to create a multi-layer request : 1. listen for 15409 // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for 15410 // fallback. 15411 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15412 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 15413 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15414 15415 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 15416 handlerThread.start(); 15417 NetworkCapabilities internetFilter = new NetworkCapabilities() 15418 .addCapability(NET_CAPABILITY_INTERNET) 15419 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 15420 final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), 15421 mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); 15422 internetFactory.setScoreFilter(40); 15423 internetFactory.register(); 15424 // Default internet request only. The unmetered request is never sent to factories (it's a 15425 // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT 15426 // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the 15427 // internetFactory filter. 15428 internetFactory.expectRequestAdds(1); 15429 internetFactory.assertRequestCountEquals(1); 15430 15431 NetworkCapabilities oemPaidFilter = new NetworkCapabilities() 15432 .addCapability(NET_CAPABILITY_INTERNET) 15433 .addCapability(NET_CAPABILITY_OEM_PAID) 15434 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 15435 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15436 final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), 15437 mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); 15438 oemPaidFactory.setScoreFilter(40); 15439 oemPaidFactory.register(); 15440 oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request 15441 15442 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15443 mCellAgent.connect(true); 15444 15445 // A network connected that satisfies the default internet request. For the OEM_PAID 15446 // preference, this is not as good as an OEM_PAID network, so even if the score of 15447 // the network is better than the factory announced, it still should try to bring up 15448 // the network. 15449 expectNoRequestChanged(oemPaidFactory); 15450 oemPaidFactory.assertRequestCountEquals(1); 15451 // The internet factory however is outscored, and should lose its requests. 15452 internetFactory.expectRequestRemove(); 15453 internetFactory.assertRequestCountEquals(0); 15454 15455 final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); 15456 oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); 15457 oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15458 final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 15459 new LinkProperties(), oemPaidNc); 15460 oemPaidAgent.connect(true); 15461 15462 // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can 15463 // provide, therefore it loses the request. 15464 oemPaidFactory.expectRequestRemove(); 15465 oemPaidFactory.assertRequestCountEquals(0); 15466 expectNoRequestChanged(internetFactory); 15467 internetFactory.assertRequestCountEquals(0); 15468 15469 oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); 15470 // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the 15471 // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID 15472 // for the preference request, so it doesn't see the request. 15473 oemPaidFactory.expectRequestAdd(); 15474 oemPaidFactory.assertRequestCountEquals(1); 15475 expectNoRequestChanged(internetFactory); 15476 internetFactory.assertRequestCountEquals(0); 15477 15478 mCellAgent.disconnect(); 15479 // The network satisfying the default internet request has disconnected, so the 15480 // internetFactory sees the default request again. However there is a network with OEM_PAID 15481 // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't 15482 // care about networks that don't have OEM_PAID. 15483 expectNoRequestChanged(oemPaidFactory); 15484 oemPaidFactory.assertRequestCountEquals(1); 15485 internetFactory.expectRequestAdd(); 15486 internetFactory.assertRequestCountEquals(1); 15487 15488 // Cell connects again, still with score 50. Back to the previous state. 15489 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15490 mCellAgent.connect(true); 15491 expectNoRequestChanged(oemPaidFactory); 15492 oemPaidFactory.assertRequestCountEquals(1); 15493 internetFactory.expectRequestRemove(); 15494 internetFactory.assertRequestCountEquals(0); 15495 15496 // Create a request that holds the upcoming wifi network. 15497 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 15498 mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 15499 wifiCallback); 15500 15501 // Now WiFi connects and it's unmetered, but it's weaker than cell. 15502 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15503 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 15504 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) 15505 .build()); // Not the best Internet network, but unmetered 15506 mWiFiAgent.connect(true); 15507 15508 // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so 15509 // the oemPaidFactory can't beat wifi no matter how high its score. 15510 oemPaidFactory.expectRequestRemove(); 15511 expectNoRequestChanged(internetFactory); 15512 15513 mCellAgent.disconnect(); 15514 // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi 15515 // at this point), the default internet request is satisfied by a network worse than 15516 // the internetFactory announced, so it gets the request. However, there is still an 15517 // unmetered network, so the oemPaidNetworkFactory still can't beat this. 15518 expectNoRequestChanged(oemPaidFactory); 15519 internetFactory.expectRequestAdd(); 15520 mCm.unregisterNetworkCallback(wifiCallback); 15521 handlerThread.quitSafely(); 15522 handlerThread.join(); 15523 } 15524 15525 /** 15526 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 15527 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 15528 */ 15529 @Test 15530 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() 15531 throws Exception { 15532 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15533 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 15534 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15535 final int expectedDefaultRequestSize = 2; 15536 final int expectedOemPrefRequestSize = 2; 15537 registerDefaultNetworkCallbacks(); 15538 15539 // The fallback as well as the OEM preference should now be tracked. 15540 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15541 15542 // Test lowest to highest priority requests. 15543 // Bring up metered cellular. This will satisfy the fallback network but not the pref. 15544 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15545 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15546 mCellAgent.getNetwork(), 15547 mService.mNoServiceNetwork.network()); 15548 15549 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15550 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15551 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15552 mCellAgent.getNetwork(), 15553 mEthernetAgent.getNetwork()); 15554 15555 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15556 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15557 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15558 mWiFiAgent.getNetwork(), 15559 mWiFiAgent.getNetwork()); 15560 15561 // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. 15562 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15563 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15564 mCellAgent.getNetwork(), 15565 mEthernetAgent.getNetwork()); 15566 15567 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 15568 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15569 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15570 null, 15571 mEthernetAgent.getNetwork()); 15572 15573 // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. 15574 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15575 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15576 null, 15577 mService.mNoServiceNetwork.network()); 15578 15579 // default callbacks will be unregistered in tearDown 15580 } 15581 15582 /** 15583 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 15584 * NET_CAPABILITY_OEM_PAID 15585 * This preference should only apply to OEM_PAID networks. 15586 */ 15587 @Test 15588 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() 15589 throws Exception { 15590 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15591 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 15592 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15593 final int expectedDefaultRequestSize = 2; 15594 final int expectedOemPrefRequestSize = 1; 15595 registerDefaultNetworkCallbacks(); 15596 15597 // The fallback as well as the OEM preference should now be tracked. 15598 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15599 15600 // Test lowest to highest priority requests. 15601 // Bring up metered cellular. This will satisfy the fallback network. 15602 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15603 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15604 mCellAgent.getNetwork(), 15605 mService.mNoServiceNetwork.network()); 15606 15607 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15608 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15609 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15610 mCellAgent.getNetwork(), 15611 mEthernetAgent.getNetwork()); 15612 15613 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15614 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15615 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15616 mWiFiAgent.getNetwork(), 15617 mEthernetAgent.getNetwork()); 15618 15619 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15620 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15621 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15622 mCellAgent.getNetwork(), 15623 mEthernetAgent.getNetwork()); 15624 15625 // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. 15626 // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. 15627 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15628 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15629 mCellAgent.getNetwork(), 15630 mService.mNoServiceNetwork.network()); 15631 15632 // Disconnecting cellular will put the fallback on null and the pref on disconnected. 15633 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15634 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15635 null, 15636 mService.mNoServiceNetwork.network()); 15637 15638 // default callbacks will be unregistered in tearDown 15639 } 15640 15641 /** 15642 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 15643 * NET_CAPABILITY_OEM_PRIVATE 15644 * This preference should only apply to OEM_PRIVATE networks. 15645 */ 15646 @Test 15647 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() 15648 throws Exception { 15649 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15650 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15651 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15652 final int expectedDefaultRequestSize = 2; 15653 final int expectedOemPrefRequestSize = 1; 15654 registerDefaultNetworkCallbacks(); 15655 15656 // The fallback as well as the OEM preference should now be tracked. 15657 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15658 15659 // Test lowest to highest priority requests. 15660 // Bring up metered cellular. This will satisfy the fallback network. 15661 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15662 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15663 mCellAgent.getNetwork(), 15664 mService.mNoServiceNetwork.network()); 15665 15666 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 15667 startOemManagedNetwork(false); 15668 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15669 mCellAgent.getNetwork(), 15670 mEthernetAgent.getNetwork()); 15671 15672 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15673 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15674 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15675 mWiFiAgent.getNetwork(), 15676 mEthernetAgent.getNetwork()); 15677 15678 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15679 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15680 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15681 mCellAgent.getNetwork(), 15682 mEthernetAgent.getNetwork()); 15683 15684 // Disconnecting OEM_PRIVATE will keep the fallback on cellular. 15685 // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. 15686 stopOemManagedNetwork(); 15687 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15688 mCellAgent.getNetwork(), 15689 mService.mNoServiceNetwork.network()); 15690 15691 // Disconnecting cellular will put the fallback on null and pref on disconnected. 15692 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15693 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15694 null, 15695 mService.mNoServiceNetwork.network()); 15696 15697 // default callbacks will be unregistered in tearDown 15698 } 15699 15700 @Test 15701 public void testCapabilityWithOemNetworkPreference() throws Exception { 15702 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15703 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15704 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 15705 registerDefaultNetworkCallbacks(); 15706 15707 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15708 15709 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15710 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15711 15712 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15713 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 15714 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15715 mDefaultNetworkCallback.expectCaps(mCellAgent, 15716 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15717 15718 // default callbacks will be unregistered in tearDown 15719 } 15720 15721 @Test 15722 public void testSetOemNetworkPreferenceLogsRequest() throws Exception { 15723 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 15724 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15725 OEM_NETWORK_PREFERENCE_OEM_PAID; 15726 final StringWriter stringWriter = new StringWriter(); 15727 final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; 15728 final Pattern pattern = Pattern.compile(logIdentifier); 15729 15730 final int expectedNumLogs = 2; 15731 final UidRangeParcel[] uidRanges = 15732 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15733 15734 // Call twice to generate two logs. 15735 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15736 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15737 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 15738 15739 final String dumpOutput = stringWriter.toString(); 15740 final Matcher matcher = pattern.matcher(dumpOutput); 15741 int count = 0; 15742 while (matcher.find()) { 15743 count++; 15744 } 15745 assertEquals(expectedNumLogs, count); 15746 } 15747 15748 @Test 15749 public void testGetAllNetworkStateSnapshots() throws Exception { 15750 verifyNoNetwork(); 15751 15752 // Setup test cellular network with specified LinkProperties and NetworkCapabilities, 15753 // verify the content of the snapshot matches. 15754 final LinkProperties cellLp = new LinkProperties(); 15755 final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); 15756 final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); 15757 cellLp.setInterfaceName("test01"); 15758 cellLp.addLinkAddress(myIpv4Addr); 15759 cellLp.addLinkAddress(myIpv6Addr); 15760 cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 15761 cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 15762 cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); 15763 cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); 15764 final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() 15765 .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); 15766 15767 final TestNetworkCallback cellCb = new TestNetworkCallback(); 15768 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15769 cellCb); 15770 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); 15771 mCellAgent.connect(true); 15772 cellCb.expectAvailableCallbacksUnvalidated(mCellAgent); 15773 List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); 15774 assertLength(1, snapshots); 15775 15776 // Compose the expected cellular snapshot for verification. 15777 final NetworkCapabilities cellNc = 15778 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15779 final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( 15780 mCellAgent.getNetwork(), cellNc, cellLp, 15781 null, ConnectivityManager.TYPE_MOBILE); 15782 assertEquals(cellSnapshot, snapshots.get(0)); 15783 15784 // Connect wifi and verify the snapshots. 15785 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15786 mWiFiAgent.connect(true); 15787 waitForIdle(); 15788 // Compose the expected wifi snapshot for verification. 15789 final NetworkCapabilities wifiNc = 15790 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 15791 final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( 15792 mWiFiAgent.getNetwork(), wifiNc, new LinkProperties(), null, 15793 ConnectivityManager.TYPE_WIFI); 15794 15795 snapshots = mCm.getAllNetworkStateSnapshots(); 15796 assertLength(2, snapshots); 15797 assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); 15798 15799 // Set cellular as suspended, verify the snapshots will contain suspended networks. 15800 mCellAgent.suspend(); 15801 waitForIdle(); 15802 final NetworkCapabilities cellSuspendedNc = 15803 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15804 assertFalse(cellSuspendedNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 15805 final NetworkStateSnapshot cellSuspendedSnapshot = new NetworkStateSnapshot( 15806 mCellAgent.getNetwork(), cellSuspendedNc, cellLp, 15807 null, ConnectivityManager.TYPE_MOBILE); 15808 snapshots = mCm.getAllNetworkStateSnapshots(); 15809 assertLength(2, snapshots); 15810 assertContainsAll(snapshots, cellSuspendedSnapshot, wifiSnapshot); 15811 15812 // Disconnect wifi, verify the snapshots contain only cellular. 15813 mWiFiAgent.disconnect(); 15814 waitForIdle(); 15815 snapshots = mCm.getAllNetworkStateSnapshots(); 15816 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 15817 assertLength(1, snapshots); 15818 assertEquals(cellSuspendedSnapshot, snapshots.get(0)); 15819 15820 mCellAgent.resume(); 15821 waitForIdle(); 15822 snapshots = mCm.getAllNetworkStateSnapshots(); 15823 assertLength(1, snapshots); 15824 assertEquals(cellSnapshot, snapshots.get(0)); 15825 15826 mCellAgent.disconnect(); 15827 waitForIdle(); 15828 verifyNoNetwork(); 15829 mCm.unregisterNetworkCallback(cellCb); 15830 } 15831 15832 // Cannot be part of MockNetworkFactory since it requires method of the test. 15833 private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { 15834 waitForIdle(); 15835 factory.assertNoRequestChanged(); 15836 } 15837 15838 @Test 15839 public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { 15840 // Prepare mock mms factory. 15841 final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); 15842 handlerThread.start(); 15843 NetworkCapabilities filter = new NetworkCapabilities() 15844 .addTransportType(TRANSPORT_CELLULAR) 15845 .addCapability(NET_CAPABILITY_MMS); 15846 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 15847 mServiceContext, "testFactory", filter, mCsHandlerThread); 15848 testFactory.setScoreFilter(40); 15849 15850 try { 15851 // Register the factory. It doesn't see the default request because its filter does 15852 // not include INTERNET. 15853 testFactory.register(); 15854 expectNoRequestChanged(testFactory); 15855 testFactory.assertRequestCountEquals(0); 15856 // The factory won't try to start the network since the default request doesn't 15857 // match the filter (no INTERNET capability). 15858 assertFalse(testFactory.getMyStartRequested()); 15859 15860 // Register callback for listening best matching network. Verify that the request won't 15861 // be sent to factory. 15862 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15863 mCm.registerBestMatchingNetworkCallback( 15864 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15865 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15866 bestMatchingCb.assertNoCallback(); 15867 expectNoRequestChanged(testFactory); 15868 testFactory.assertRequestCountEquals(0); 15869 assertFalse(testFactory.getMyStartRequested()); 15870 15871 // Fire a normal mms request, verify the factory will only see the request. 15872 final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); 15873 final NetworkRequest mmsRequest = new NetworkRequest.Builder() 15874 .addCapability(NET_CAPABILITY_MMS).build(); 15875 mCm.requestNetwork(mmsRequest, mmsNetworkCallback); 15876 testFactory.expectRequestAdd(); 15877 testFactory.assertRequestCountEquals(1); 15878 assertTrue(testFactory.getMyStartRequested()); 15879 15880 // Unregister best matching callback, verify factory see no change. 15881 mCm.unregisterNetworkCallback(bestMatchingCb); 15882 expectNoRequestChanged(testFactory); 15883 testFactory.assertRequestCountEquals(1); 15884 assertTrue(testFactory.getMyStartRequested()); 15885 } finally { 15886 testFactory.terminate(); 15887 handlerThread.quitSafely(); 15888 handlerThread.join(); 15889 } 15890 } 15891 15892 @Test 15893 public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { 15894 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15895 mCm.registerBestMatchingNetworkCallback( 15896 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), 15897 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15898 15899 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15900 mCellAgent.connect(true); 15901 bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellAgent); 15902 15903 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15904 mWiFiAgent.connect(true); 15905 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 15906 15907 // Change something on cellular to trigger capabilities changed, since the callback 15908 // only cares about the best network, verify it received nothing from cellular. 15909 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15910 bestMatchingCb.assertNoCallback(); 15911 15912 // Make cellular the best network again, verify the callback now tracks cellular. 15913 mWiFiAgent.adjustScore(-50); 15914 bestMatchingCb.expectAvailableCallbacksValidated(mCellAgent); 15915 15916 // Make cellular temporary non-trusted, which will not satisfying the request. 15917 // Verify the callback switch from/to the other network accordingly. 15918 mCellAgent.removeCapability(NET_CAPABILITY_TRUSTED); 15919 bestMatchingCb.expectAvailableCallbacksValidated(mWiFiAgent); 15920 mCellAgent.addCapability(NET_CAPABILITY_TRUSTED); 15921 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellAgent); 15922 15923 // Verify the callback doesn't care about wifi disconnect. 15924 mWiFiAgent.disconnect(); 15925 bestMatchingCb.assertNoCallback(); 15926 mCellAgent.disconnect(); 15927 bestMatchingCb.expect(LOST, mCellAgent); 15928 } 15929 15930 private UidRangeParcel[] uidRangeFor(final UserHandle handle) { 15931 final UidRange range = UidRange.createForUser(handle); 15932 return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; 15933 } 15934 15935 private UidRangeParcel[] uidRangeFor(final UserHandle handle, 15936 ProfileNetworkPreference profileNetworkPreference) { 15937 final Set<UidRange> uidRangeSet; 15938 UidRange range = UidRange.createForUser(handle); 15939 if (profileNetworkPreference.getIncludedUids().length != 0) { 15940 uidRangeSet = UidRangeUtils.convertArrayToUidRange( 15941 profileNetworkPreference.getIncludedUids()); 15942 15943 } else if (profileNetworkPreference.getExcludedUids().length != 0) { 15944 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange( 15945 range, UidRangeUtils.convertArrayToUidRange( 15946 profileNetworkPreference.getExcludedUids())); 15947 } else { 15948 uidRangeSet = new ArraySet<>(); 15949 uidRangeSet.add(range); 15950 } 15951 UidRangeParcel[] uidRangeParcels = new UidRangeParcel[uidRangeSet.size()]; 15952 int i = 0; 15953 for (UidRange range1 : uidRangeSet) { 15954 uidRangeParcels[i] = new UidRangeParcel(range1.start, range1.stop); 15955 i++; 15956 } 15957 return uidRangeParcels; 15958 } 15959 15960 private static class TestOnCompleteListener implements Runnable { 15961 final class OnComplete {} 15962 final ArrayTrackRecord<OnComplete>.ReadHead mHistory = 15963 new ArrayTrackRecord<OnComplete>().newReadHead(); 15964 15965 @Override 15966 public void run() { 15967 mHistory.add(new OnComplete()); 15968 } 15969 15970 public void expectOnComplete() { 15971 assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); 15972 } 15973 } 15974 15975 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { 15976 final NetworkCapabilities workNc = new NetworkCapabilities(); 15977 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 15978 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15979 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 15980 } 15981 15982 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent(int enterpriseId) throws Exception { 15983 final NetworkCapabilities workNc = new NetworkCapabilities(); 15984 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 15985 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15986 workNc.addEnterpriseId(enterpriseId); 15987 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 15988 } 15989 15990 private TestNetworkCallback mEnterpriseCallback; 15991 private UserHandle setupEnterpriseNetwork() { 15992 final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 15993 mServiceContext.setWorkProfile(userHandle, true); 15994 15995 // File a request to avoid the enterprise network being disconnected as soon as the default 15996 // request goes away – it would make impossible to test that networkRemoveUidRanges 15997 // is called, as the network would disconnect first for lack of a request. 15998 mEnterpriseCallback = new TestNetworkCallback(); 15999 final NetworkRequest keepUpRequest = new NetworkRequest.Builder() 16000 .addCapability(NET_CAPABILITY_ENTERPRISE) 16001 .build(); 16002 mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); 16003 return userHandle; 16004 } 16005 16006 private void maybeTearDownEnterpriseNetwork() { 16007 if (null != mEnterpriseCallback) { 16008 mCm.unregisterNetworkCallback(mEnterpriseCallback); 16009 } 16010 } 16011 16012 /** 16013 * Make sure per profile network preferences behave as expected for a given 16014 * profile network preference. 16015 */ 16016 private void doTestPreferenceForUserNetworkUpDownForGivenPreference( 16017 ProfileNetworkPreference profileNetworkPreference, 16018 boolean connectWorkProfileAgentAhead, 16019 UserHandle testHandle, 16020 TestNetworkCallback profileDefaultNetworkCallback, 16021 TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception { 16022 final InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); 16023 16024 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16025 mCellAgent.connect(true); 16026 16027 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16028 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16029 profileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16030 if (disAllowProfileDefaultNetworkCallback != null) { 16031 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16032 } 16033 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16034 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16035 16036 final TestNetworkAgentWrapper workAgent = 16037 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 16038 if (mService.shouldCreateNetworksImmediately()) { 16039 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 16040 null /* iface */, inOrder); 16041 } 16042 if (connectWorkProfileAgentAhead) { 16043 workAgent.connect(false); 16044 if (!mService.shouldCreateNetworksImmediately()) { 16045 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 16046 null /* iface */, inOrder); 16047 } 16048 } 16049 16050 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16051 mCm.setProfileNetworkPreferences(testHandle, List.of(profileNetworkPreference), 16052 r -> r.run(), listener); 16053 listener.expectOnComplete(); 16054 boolean allowFallback = true; 16055 if (profileNetworkPreference.getPreference() 16056 == PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) { 16057 allowFallback = false; 16058 } 16059 if (allowFallback && !connectWorkProfileAgentAhead) { 16060 // Setting a network preference for this user will create a new set of routing rules for 16061 // the UID range that corresponds to this user, inorder to define the default network 16062 // for these apps separately. This is true because the multi-layer request relevant to 16063 // this UID range contains a TRACK_DEFAULT, so the range will be moved through 16064 // UID-specific rules to the correct network – in this case the system default network. 16065 // The case where the default network for the profile happens to be the same as the 16066 // system default is not handled specially, the rules are always active as long as 16067 // a preference is set. 16068 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16069 mCellAgent.getNetwork().netId, 16070 uidRangeFor(testHandle, profileNetworkPreference), 16071 PREFERENCE_ORDER_PROFILE)); 16072 } 16073 16074 // The enterprise network is not ready yet. 16075 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16076 if (allowFallback && !connectWorkProfileAgentAhead) { 16077 assertNoCallbacks(profileDefaultNetworkCallback); 16078 } else if (!connectWorkProfileAgentAhead) { 16079 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 16080 if (disAllowProfileDefaultNetworkCallback != null) { 16081 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16082 } 16083 } 16084 16085 if (!connectWorkProfileAgentAhead) { 16086 workAgent.connect(false); 16087 if (!mService.shouldCreateNetworksImmediately()) { 16088 inOrder.verify(mMockNetd).networkCreate( 16089 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, 16090 INetd.PERMISSION_SYSTEM)); 16091 } 16092 } 16093 16094 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); 16095 if (disAllowProfileDefaultNetworkCallback != null) { 16096 disAllowProfileDefaultNetworkCallback.assertNoCallback(); 16097 } 16098 mSystemDefaultNetworkCallback.assertNoCallback(); 16099 mDefaultNetworkCallback.assertNoCallback(); 16100 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16101 workAgent.getNetwork().netId, 16102 uidRangeFor(testHandle, profileNetworkPreference), 16103 PREFERENCE_ORDER_PROFILE)); 16104 16105 if (allowFallback && !connectWorkProfileAgentAhead) { 16106 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16107 mCellAgent.getNetwork().netId, 16108 uidRangeFor(testHandle, profileNetworkPreference), 16109 PREFERENCE_ORDER_PROFILE)); 16110 } 16111 16112 // Make sure changes to the work agent send callbacks to the app in the work profile, but 16113 // not to the other apps. 16114 workAgent.setNetworkValid(true /* privateDnsProbeSent */); 16115 workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 16116 profileDefaultNetworkCallback.expectCaps(workAgent, 16117 c -> c.hasCapability(NET_CAPABILITY_VALIDATED) 16118 && c.hasCapability(NET_CAPABILITY_ENTERPRISE) 16119 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 16120 && c.getEnterpriseIds().length == 1); 16121 if (disAllowProfileDefaultNetworkCallback != null) { 16122 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16123 } 16124 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16125 16126 workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 16127 profileDefaultNetworkCallback.expectCaps(workAgent, 16128 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16129 if (disAllowProfileDefaultNetworkCallback != null) { 16130 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16131 } 16132 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16133 16134 // Conversely, change a capability on the system-wide default network and make sure 16135 // that only the apps outside of the work profile receive the callbacks. 16136 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 16137 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 16138 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16139 mDefaultNetworkCallback.expectCaps(mCellAgent, 16140 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16141 if (disAllowProfileDefaultNetworkCallback != null) { 16142 disAllowProfileDefaultNetworkCallback.expectCaps(mCellAgent, 16143 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16144 } 16145 profileDefaultNetworkCallback.assertNoCallback(); 16146 16147 // Disconnect and reconnect the system-wide default network and make sure that the 16148 // apps on this network see the appropriate callbacks, and the app on the work profile 16149 // doesn't because it continues to use the enterprise network. 16150 mCellAgent.disconnect(); 16151 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 16152 mDefaultNetworkCallback.expect(LOST, mCellAgent); 16153 if (disAllowProfileDefaultNetworkCallback != null) { 16154 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 16155 } 16156 profileDefaultNetworkCallback.assertNoCallback(); 16157 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 16158 16159 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16160 mCellAgent.connect(true); 16161 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16162 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16163 if (disAllowProfileDefaultNetworkCallback != null) { 16164 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16165 16166 } 16167 profileDefaultNetworkCallback.assertNoCallback(); 16168 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16169 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16170 16171 // When the agent disconnects, test that the app on the work profile falls back to the 16172 // default network. 16173 workAgent.disconnect(); 16174 profileDefaultNetworkCallback.expect(LOST, workAgent); 16175 if (allowFallback) { 16176 profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16177 if (disAllowProfileDefaultNetworkCallback != null) { 16178 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16179 } 16180 } 16181 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16182 if (allowFallback) { 16183 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16184 mCellAgent.getNetwork().netId, 16185 uidRangeFor(testHandle, profileNetworkPreference), 16186 PREFERENCE_ORDER_PROFILE)); 16187 } 16188 inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); 16189 16190 mCellAgent.disconnect(); 16191 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 16192 mDefaultNetworkCallback.expect(LOST, mCellAgent); 16193 if (disAllowProfileDefaultNetworkCallback != null) { 16194 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 16195 } 16196 if (allowFallback) { 16197 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 16198 } 16199 16200 // Waiting for the handler to be idle before checking for networkDestroy is necessary 16201 // here because ConnectivityService calls onLost before the network is fully torn down. 16202 waitForIdle(); 16203 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 16204 16205 // If the control comes here, callbacks seem to behave correctly in the presence of 16206 // a default network when the enterprise network goes up and down. Now, make sure they 16207 // also behave correctly in the absence of a system-wide default network. 16208 final TestNetworkAgentWrapper workAgent2 = 16209 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 16210 workAgent2.connect(false); 16211 16212 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); 16213 if (disAllowProfileDefaultNetworkCallback != null) { 16214 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16215 } 16216 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16217 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16218 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16219 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16220 workAgent2.getNetwork().netId, 16221 uidRangeFor(testHandle, profileNetworkPreference), PREFERENCE_ORDER_PROFILE)); 16222 16223 workAgent2.setNetworkValid(true /* privateDnsProbeSent */); 16224 workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); 16225 profileDefaultNetworkCallback.expectCaps(workAgent2, 16226 c -> c.hasCapability(NET_CAPABILITY_ENTERPRISE) 16227 && !c.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 16228 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 16229 && c.getEnterpriseIds().length == 1); 16230 if (disAllowProfileDefaultNetworkCallback != null) { 16231 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16232 } 16233 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16234 inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 16235 16236 // When the agent disconnects, test that the app on the work profile fall back to the 16237 // default network. 16238 workAgent2.disconnect(); 16239 profileDefaultNetworkCallback.expect(LOST, workAgent2); 16240 if (disAllowProfileDefaultNetworkCallback != null) { 16241 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16242 } 16243 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16244 inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); 16245 16246 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 16247 profileDefaultNetworkCallback); 16248 16249 // Callbacks will be unregistered by tearDown() 16250 } 16251 16252 /** 16253 * Make sure per-profile networking preference behaves as expected when the enterprise network 16254 * goes up and down while the preference is active. Make sure they behave as expected whether 16255 * there is a general default network or not. 16256 */ 16257 @Test 16258 public void testPreferenceForUserNetworkUpDown() throws Exception { 16259 final UserHandle testHandle = setupEnterpriseNetwork(); 16260 registerDefaultNetworkCallbacks(); 16261 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16262 new ProfileNetworkPreference.Builder(); 16263 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16264 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16265 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16266 profileNetworkPreferenceBuilder.build(), false, 16267 testHandle, mProfileDefaultNetworkCallback, null); 16268 } 16269 16270 /** 16271 * Make sure per-profile networking preference behaves as expected when the enterprise network 16272 * goes up and down while the preference is active. Make sure they behave as expected whether 16273 * there is a general default network or not when configured to not fallback to default network. 16274 */ 16275 @Test 16276 public void testPreferenceForUserNetworkUpDownWithNoFallback() throws Exception { 16277 final UserHandle testHandle = setupEnterpriseNetwork(); 16278 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16279 new ProfileNetworkPreference.Builder(); 16280 profileNetworkPreferenceBuilder.setPreference( 16281 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16282 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16283 registerDefaultNetworkCallbacks(); 16284 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16285 profileNetworkPreferenceBuilder.build(), false, 16286 testHandle, mProfileDefaultNetworkCallback, null); 16287 } 16288 16289 /** 16290 * Make sure per-profile networking preference behaves as expected when the enterprise network 16291 * goes up and down while the preference is active. Make sure they behave as expected whether 16292 * there is a general default network or not when configured to not fallback to default network 16293 * along with already connected enterprise work agent 16294 */ 16295 @Test 16296 public void testPreferenceForUserNetworkUpDownWithNoFallbackWithAlreadyConnectedWorkAgent() 16297 throws Exception { 16298 final UserHandle testHandle = setupEnterpriseNetwork(); 16299 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16300 new ProfileNetworkPreference.Builder(); 16301 profileNetworkPreferenceBuilder.setPreference( 16302 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16303 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16304 registerDefaultNetworkCallbacks(); 16305 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16306 profileNetworkPreferenceBuilder.build(), true, testHandle, 16307 mProfileDefaultNetworkCallback, null); 16308 } 16309 16310 /** 16311 * Make sure per-profile networking preference for specific uid of test handle 16312 * behaves as expected 16313 */ 16314 @Test 16315 public void testPreferenceForDefaultUidOfTestHandle() throws Exception { 16316 final UserHandle testHandle = setupEnterpriseNetwork(); 16317 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16318 new ProfileNetworkPreference.Builder(); 16319 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16320 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16321 profileNetworkPreferenceBuilder.setIncludedUids( 16322 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}); 16323 registerDefaultNetworkCallbacks(); 16324 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16325 profileNetworkPreferenceBuilder.build(), false, testHandle, 16326 mProfileDefaultNetworkCallback, null); 16327 } 16328 16329 /** 16330 * Make sure per-profile networking preference for specific uid of test handle 16331 * behaves as expected 16332 */ 16333 @Test 16334 public void testPreferenceForSpecificUidOfOnlyOneApp() throws Exception { 16335 final UserHandle testHandle = setupEnterpriseNetwork(); 16336 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16337 new ProfileNetworkPreference.Builder(); 16338 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16339 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16340 profileNetworkPreferenceBuilder.setIncludedUids( 16341 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16342 registerDefaultNetworkCallbacks(); 16343 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16344 profileNetworkPreferenceBuilder.build(), false, 16345 testHandle, mProfileDefaultNetworkCallbackAsAppUid2, null); 16346 } 16347 16348 /** 16349 * Make sure per-profile networking preference for specific uid of test handle 16350 * behaves as expected 16351 */ 16352 @Test 16353 public void testPreferenceForDisallowSpecificUidOfApp() throws Exception { 16354 final UserHandle testHandle = setupEnterpriseNetwork(); 16355 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16356 new ProfileNetworkPreference.Builder(); 16357 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16358 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16359 profileNetworkPreferenceBuilder.setExcludedUids( 16360 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16361 registerDefaultNetworkCallbacks(); 16362 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16363 profileNetworkPreferenceBuilder.build(), false, 16364 testHandle, mProfileDefaultNetworkCallback, 16365 mProfileDefaultNetworkCallbackAsAppUid2); 16366 } 16367 16368 /** 16369 * Make sure per-profile networking preference for specific uid of test handle 16370 * invalid uid inputs 16371 */ 16372 @Test 16373 public void testPreferenceForInvalidUids() throws Exception { 16374 final UserHandle testHandle = setupEnterpriseNetwork(); 16375 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16376 new ProfileNetworkPreference.Builder(); 16377 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16378 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16379 profileNetworkPreferenceBuilder.setExcludedUids( 16380 new int[]{testHandle.getUid(0) - 1}); 16381 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16382 Assert.assertThrows(IllegalArgumentException.class, () -> mCm.setProfileNetworkPreferences( 16383 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16384 r -> r.run(), listener)); 16385 16386 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16387 profileNetworkPreferenceBuilder.setIncludedUids( 16388 new int[]{testHandle.getUid(0) - 1}); 16389 Assert.assertThrows(IllegalArgumentException.class, 16390 () -> mCm.setProfileNetworkPreferences( 16391 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16392 r -> r.run(), listener)); 16393 16394 16395 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16396 profileNetworkPreferenceBuilder.setIncludedUids( 16397 new int[]{testHandle.getUid(0) - 1}); 16398 profileNetworkPreferenceBuilder.setExcludedUids( 16399 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16400 Assert.assertThrows(IllegalArgumentException.class, 16401 () -> mCm.setProfileNetworkPreferences( 16402 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16403 r -> r.run(), listener)); 16404 16405 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16406 new ProfileNetworkPreference.Builder(); 16407 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16408 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16409 profileNetworkPreferenceBuilder2.setIncludedUids( 16410 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16411 profileNetworkPreferenceBuilder.setIncludedUids( 16412 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16413 Assert.assertThrows(IllegalArgumentException.class, 16414 () -> mCm.setProfileNetworkPreferences( 16415 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16416 profileNetworkPreferenceBuilder2.build()), 16417 r -> r.run(), listener)); 16418 16419 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16420 profileNetworkPreferenceBuilder2.setExcludedUids( 16421 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16422 profileNetworkPreferenceBuilder.setExcludedUids( 16423 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16424 Assert.assertThrows(IllegalArgumentException.class, 16425 () -> mCm.setProfileNetworkPreferences( 16426 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16427 profileNetworkPreferenceBuilder2.build()), 16428 r -> r.run(), listener)); 16429 16430 profileNetworkPreferenceBuilder2.setPreference( 16431 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16432 profileNetworkPreferenceBuilder2.setExcludedUids( 16433 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16434 profileNetworkPreferenceBuilder.setExcludedUids( 16435 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16436 Assert.assertThrows(IllegalArgumentException.class, 16437 () -> mCm.setProfileNetworkPreferences( 16438 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16439 profileNetworkPreferenceBuilder2.build()), 16440 r -> r.run(), listener)); 16441 } 16442 16443 /** 16444 * Make sure per-profile networking preference behaves as expected when the enterprise network 16445 * goes up and down while the preference is active. Make sure they behave as expected whether 16446 * there is a general default network or not when configured to fallback to default network 16447 * along with already connected enterprise work agent 16448 */ 16449 @Test 16450 public void testPreferenceForUserNetworkUpDownWithFallbackWithAlreadyConnectedWorkAgent() 16451 throws Exception { 16452 final UserHandle testHandle = setupEnterpriseNetwork(); 16453 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16454 new ProfileNetworkPreference.Builder(); 16455 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16456 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16457 registerDefaultNetworkCallbacks(); 16458 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16459 profileNetworkPreferenceBuilder.build(), true, 16460 testHandle, mProfileDefaultNetworkCallback, 16461 null); 16462 } 16463 16464 /** 16465 * Make sure per-profile networking preference behaves as expected when the enterprise network 16466 * goes up and down while the preference is active for a given enterprise identifier 16467 */ 16468 @Test 16469 public void testPreferenceForUserNetworkUpDownWithDefaultEnterpriseId() 16470 throws Exception { 16471 final UserHandle testHandle = setupEnterpriseNetwork(); 16472 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16473 new ProfileNetworkPreference.Builder(); 16474 profileNetworkPreferenceBuilder.setPreference( 16475 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16476 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16477 registerDefaultNetworkCallbacks(); 16478 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16479 profileNetworkPreferenceBuilder.build(), true, 16480 testHandle, mProfileDefaultNetworkCallback, 16481 null); 16482 } 16483 16484 /** 16485 * Make sure per-profile networking preference behaves as expected when the enterprise network 16486 * goes up and down while the preference is active for a given enterprise identifier 16487 */ 16488 @Test 16489 public void testPreferenceForUserNetworkUpDownWithId2() 16490 throws Exception { 16491 final UserHandle testHandle = setupEnterpriseNetwork(); 16492 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16493 new ProfileNetworkPreference.Builder(); 16494 profileNetworkPreferenceBuilder.setPreference( 16495 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16496 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId( 16497 NET_ENTERPRISE_ID_2); 16498 registerDefaultNetworkCallbacks(); 16499 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16500 profileNetworkPreferenceBuilder.build(), true, 16501 testHandle, mProfileDefaultNetworkCallback, null); 16502 } 16503 16504 /** 16505 * Make sure per-profile networking preference behaves as expected when the enterprise network 16506 * goes up and down while the preference is active for a given enterprise identifier 16507 */ 16508 @Test 16509 public void testPreferenceForUserNetworkUpDownWithInvalidId() 16510 throws Exception { 16511 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16512 new ProfileNetworkPreference.Builder(); 16513 profileNetworkPreferenceBuilder.setPreference( 16514 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16515 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(0); 16516 registerDefaultNetworkCallbacks(); 16517 assertThrows("Should not be able to set invalid enterprise id", 16518 IllegalStateException.class, () -> profileNetworkPreferenceBuilder.build()); 16519 } 16520 16521 /** 16522 * Make sure per-profile networking preference throws exception when default preference 16523 * is set along with enterprise preference. 16524 */ 16525 @Test 16526 public void testPreferenceWithInvalidPreferenceDefaultAndEnterpriseTogether() 16527 throws Exception { 16528 final UserHandle testHandle = setupEnterpriseNetwork(); 16529 mServiceContext.setWorkProfile(testHandle, true); 16530 16531 final int testWorkProfileAppUid1 = 16532 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16533 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16534 new ProfileNetworkPreference.Builder(); 16535 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16536 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16537 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16538 16539 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16540 new ProfileNetworkPreference.Builder(); 16541 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16542 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16543 Assert.assertThrows(IllegalArgumentException.class, 16544 () -> mCm.setProfileNetworkPreferences( 16545 testHandle, List.of(profileNetworkPreferenceBuilder1.build(), 16546 profileNetworkPreferenceBuilder2.build()), 16547 r -> r.run(), listener)); 16548 Assert.assertThrows(IllegalArgumentException.class, 16549 () -> mCm.setProfileNetworkPreferences( 16550 testHandle, List.of(profileNetworkPreferenceBuilder2.build(), 16551 profileNetworkPreferenceBuilder1.build()), 16552 r -> r.run(), listener)); 16553 } 16554 16555 /** 16556 * Make sure per profile network preferences behave as expected when two slices with 16557 * two different apps within same user profile is configured 16558 * Make sure per profile network preferences overrides with latest preference when 16559 * same user preference is set twice 16560 */ 16561 @Test 16562 public void testSetPreferenceWithOverridingPreference() 16563 throws Exception { 16564 final InOrder inOrder = inOrder(mMockNetd); 16565 final UserHandle testHandle = setupEnterpriseNetwork(); 16566 mServiceContext.setWorkProfile(testHandle, true); 16567 registerDefaultNetworkCallbacks(); 16568 16569 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16570 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16571 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16572 16573 final int testWorkProfileAppUid1 = 16574 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16575 final int testWorkProfileAppUid2 = 16576 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16577 final int testWorkProfileAppUid3 = 16578 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16579 16580 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16581 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16582 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16583 16584 // Connect both a regular cell agent and an enterprise network first. 16585 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16586 mCellAgent.connect(true); 16587 16588 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16589 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16590 workAgent1.connect(true); 16591 workAgent2.connect(true); 16592 16593 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16594 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16595 16596 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16597 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16598 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16599 16600 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16601 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16602 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16603 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16604 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16605 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16606 16607 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16608 16609 // Set preferences for testHandle to map testWorkProfileAppUid1 to 16610 // NET_ENTERPRISE_ID_1 and testWorkProfileAppUid2 to NET_ENTERPRISE_ID_2. 16611 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16612 new ProfileNetworkPreference.Builder(); 16613 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16614 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16615 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16616 16617 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16618 new ProfileNetworkPreference.Builder(); 16619 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16620 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16621 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16622 16623 mCm.setProfileNetworkPreferences(testHandle, 16624 List.of(profileNetworkPreferenceBuilder1.build(), 16625 profileNetworkPreferenceBuilder2.build()), 16626 r -> r.run(), listener); 16627 listener.expectOnComplete(); 16628 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16629 workAgent2.getNetwork().netId, 16630 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16631 PREFERENCE_ORDER_PROFILE)); 16632 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16633 workAgent1.getNetwork().netId, 16634 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16635 PREFERENCE_ORDER_PROFILE)); 16636 16637 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16638 appCb1.expectAvailableCallbacksValidated(workAgent1); 16639 appCb2.expectAvailableCallbacksValidated(workAgent2); 16640 16641 // Set preferences for testHandle to map testWorkProfileAppUid3 to 16642 // to NET_ENTERPRISE_ID_1. 16643 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16644 new ProfileNetworkPreference.Builder(); 16645 profileNetworkPreferenceBuilder3.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16646 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16647 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16648 16649 mCm.setProfileNetworkPreferences(testHandle, 16650 List.of(profileNetworkPreferenceBuilder3.build()), 16651 r -> r.run(), listener); 16652 listener.expectOnComplete(); 16653 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16654 workAgent1.getNetwork().netId, 16655 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16656 PREFERENCE_ORDER_PROFILE)); 16657 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16658 workAgent2.getNetwork().netId, 16659 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16660 PREFERENCE_ORDER_PROFILE)); 16661 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16662 workAgent1.getNetwork().netId, 16663 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16664 PREFERENCE_ORDER_PROFILE)); 16665 16666 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16667 appCb3.expectAvailableCallbacksValidated(workAgent1); 16668 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16669 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16670 16671 // Set the preferences for testHandle to default. 16672 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16673 new ProfileNetworkPreference.Builder(); 16674 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16675 16676 mCm.setProfileNetworkPreferences(testHandle, 16677 List.of(profileNetworkPreferenceBuilder.build()), 16678 r -> r.run(), listener); 16679 listener.expectOnComplete(); 16680 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16681 workAgent1.getNetwork().netId, 16682 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16683 PREFERENCE_ORDER_PROFILE)); 16684 16685 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb2); 16686 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16687 workAgent2.disconnect(); 16688 mCellAgent.disconnect(); 16689 16690 mCm.unregisterNetworkCallback(appCb1); 16691 mCm.unregisterNetworkCallback(appCb2); 16692 mCm.unregisterNetworkCallback(appCb3); 16693 // Other callbacks will be unregistered by tearDown() 16694 } 16695 16696 private NetworkCallback requestForEnterpriseId(@NetworkCapabilities.EnterpriseId final int id) { 16697 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 16698 .addCapability(NET_CAPABILITY_ENTERPRISE).addEnterpriseId(id).build(); 16699 final NetworkRequest req = new NetworkRequest.Builder().setCapabilities(nc).build(); 16700 final NetworkCallback cb = new TestableNetworkCallback(); 16701 mCm.requestNetwork(req, cb); 16702 return cb; 16703 } 16704 16705 /** 16706 * Make sure per profile network preferences behave as expected when multiple slices with 16707 * multiple different apps within same user profile is configured. 16708 */ 16709 @Test 16710 public void testSetPreferenceWithMultiplePreferences() 16711 throws Exception { 16712 final UserHandle testHandle = setupEnterpriseNetwork(); 16713 mServiceContext.setWorkProfile(testHandle, true); 16714 registerDefaultNetworkCallbacks(); 16715 16716 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16717 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16718 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16719 final TestNetworkCallback appCb4 = new TestNetworkCallback(); 16720 final TestNetworkCallback appCb5 = new TestNetworkCallback(); 16721 16722 final int testWorkProfileAppUid1 = 16723 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16724 final int testWorkProfileAppUid2 = 16725 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16726 final int testWorkProfileAppUid3 = 16727 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16728 final int testWorkProfileAppUid4 = 16729 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_4); 16730 final int testWorkProfileAppUid5 = 16731 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_5); 16732 16733 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16734 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16735 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16736 registerDefaultNetworkCallbackAsUid(appCb4, testWorkProfileAppUid4); 16737 registerDefaultNetworkCallbackAsUid(appCb5, testWorkProfileAppUid5); 16738 16739 // Connect both a regular cell agent and an enterprise network first. 16740 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16741 mCellAgent.connect(true); 16742 16743 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16744 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16745 final TestNetworkAgentWrapper workAgent3 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_3); 16746 final TestNetworkAgentWrapper workAgent4 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_4); 16747 final TestNetworkAgentWrapper workAgent5 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_5); 16748 16749 final NetworkCallback keepupCb1 = requestForEnterpriseId(NET_ENTERPRISE_ID_1); 16750 final NetworkCallback keepupCb2 = requestForEnterpriseId(NET_ENTERPRISE_ID_2); 16751 final NetworkCallback keepupCb3 = requestForEnterpriseId(NET_ENTERPRISE_ID_3); 16752 final NetworkCallback keepupCb4 = requestForEnterpriseId(NET_ENTERPRISE_ID_4); 16753 final NetworkCallback keepupCb5 = requestForEnterpriseId(NET_ENTERPRISE_ID_5); 16754 16755 workAgent1.connect(true); 16756 workAgent2.connect(true); 16757 workAgent3.connect(true); 16758 workAgent4.connect(true); 16759 workAgent5.connect(true); 16760 16761 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16762 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16763 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16764 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16765 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16766 appCb4.expectAvailableThenValidatedCallbacks(mCellAgent); 16767 appCb5.expectAvailableThenValidatedCallbacks(mCellAgent); 16768 16769 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16770 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16771 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16772 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16773 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16774 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16775 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16776 workAgent3.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16777 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16778 workAgent4.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16779 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16780 workAgent5.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16781 16782 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16783 16784 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16785 new ProfileNetworkPreference.Builder(); 16786 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16787 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16788 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16789 16790 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16791 new ProfileNetworkPreference.Builder(); 16792 profileNetworkPreferenceBuilder2.setPreference( 16793 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16794 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16795 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16796 16797 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16798 new ProfileNetworkPreference.Builder(); 16799 profileNetworkPreferenceBuilder3.setPreference( 16800 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16801 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_3); 16802 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16803 16804 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder4 = 16805 new ProfileNetworkPreference.Builder(); 16806 profileNetworkPreferenceBuilder4.setPreference( 16807 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16808 profileNetworkPreferenceBuilder4.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_4); 16809 profileNetworkPreferenceBuilder4.setIncludedUids(new int[]{testWorkProfileAppUid4}); 16810 16811 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder5 = 16812 new ProfileNetworkPreference.Builder(); 16813 profileNetworkPreferenceBuilder5.setPreference( 16814 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16815 profileNetworkPreferenceBuilder5.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_5); 16816 profileNetworkPreferenceBuilder5.setIncludedUids(new int[]{testWorkProfileAppUid5}); 16817 16818 mCm.setProfileNetworkPreferences(testHandle, 16819 List.of(profileNetworkPreferenceBuilder1.build(), 16820 profileNetworkPreferenceBuilder2.build(), 16821 profileNetworkPreferenceBuilder3.build(), 16822 profileNetworkPreferenceBuilder4.build(), 16823 profileNetworkPreferenceBuilder5.build()), 16824 r -> r.run(), listener); 16825 16826 listener.expectOnComplete(); 16827 16828 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16829 workAgent1.getNetwork().netId, 16830 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16831 PREFERENCE_ORDER_PROFILE)); 16832 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16833 workAgent2.getNetwork().netId, 16834 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16835 PREFERENCE_ORDER_PROFILE)); 16836 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16837 workAgent3.getNetwork().netId, 16838 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16839 PREFERENCE_ORDER_PROFILE)); 16840 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16841 workAgent4.getNetwork().netId, 16842 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16843 PREFERENCE_ORDER_PROFILE)); 16844 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16845 workAgent5.getNetwork().netId, 16846 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16847 PREFERENCE_ORDER_PROFILE)); 16848 16849 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16850 appCb1.expectAvailableCallbacksValidated(workAgent1); 16851 appCb2.expectAvailableCallbacksValidated(workAgent2); 16852 appCb3.expectAvailableCallbacksValidated(workAgent3); 16853 appCb4.expectAvailableCallbacksValidated(workAgent4); 16854 appCb5.expectAvailableCallbacksValidated(workAgent5); 16855 16856 workAgent1.disconnect(); 16857 workAgent2.disconnect(); 16858 workAgent3.disconnect(); 16859 workAgent4.disconnect(); 16860 workAgent5.disconnect(); 16861 16862 appCb1.expect(LOST, workAgent1); 16863 appCb2.expect(LOST, workAgent2); 16864 appCb3.expect(LOST, workAgent3); 16865 appCb4.expect(LOST, workAgent4); 16866 appCb5.expect(LOST, workAgent5); 16867 16868 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16869 appCb2.assertNoCallback(); 16870 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16871 appCb4.assertNoCallback(); 16872 appCb5.expectAvailableCallbacksValidated(mCellAgent); 16873 16874 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16875 mCellAgent.getNetwork().netId, 16876 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16877 PREFERENCE_ORDER_PROFILE)); 16878 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16879 mCellAgent.getNetwork().netId, 16880 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16881 PREFERENCE_ORDER_PROFILE)); 16882 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16883 mCellAgent.getNetwork().netId, 16884 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16885 PREFERENCE_ORDER_PROFILE)); 16886 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16887 mCellAgent.getNetwork().netId, 16888 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16889 PREFERENCE_ORDER_PROFILE)); 16890 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16891 mCellAgent.getNetwork().netId, 16892 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16893 PREFERENCE_ORDER_PROFILE)); 16894 16895 mSystemDefaultNetworkCallback.assertNoCallback(); 16896 mDefaultNetworkCallback.assertNoCallback(); 16897 16898 // Set the preferences for testHandle to default. 16899 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16900 new ProfileNetworkPreference.Builder(); 16901 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16902 16903 mCm.setProfileNetworkPreferences(testHandle, 16904 List.of(profileNetworkPreferenceBuilder.build()), 16905 r -> r.run(), listener); 16906 listener.expectOnComplete(); 16907 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb3, 16908 appCb5); 16909 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16910 appCb4.expectAvailableCallbacksValidated(mCellAgent); 16911 mCellAgent.disconnect(); 16912 16913 mCm.unregisterNetworkCallback(keepupCb1); 16914 mCm.unregisterNetworkCallback(keepupCb2); 16915 mCm.unregisterNetworkCallback(keepupCb3); 16916 mCm.unregisterNetworkCallback(keepupCb4); 16917 mCm.unregisterNetworkCallback(keepupCb5); 16918 16919 mCm.unregisterNetworkCallback(appCb1); 16920 mCm.unregisterNetworkCallback(appCb2); 16921 mCm.unregisterNetworkCallback(appCb3); 16922 mCm.unregisterNetworkCallback(appCb4); 16923 mCm.unregisterNetworkCallback(appCb5); 16924 // Other callbacks will be unregistered by tearDown() 16925 } 16926 16927 /** 16928 * Test that, in a given networking context, calling setPreferenceForUser to set per-profile 16929 * defaults on then off works as expected. 16930 */ 16931 @Test 16932 public void testSetPreferenceForUserOnOff() throws Exception { 16933 final InOrder inOrder = inOrder(mMockNetd); 16934 final UserHandle testHandle = setupEnterpriseNetwork(); 16935 16936 // Connect both a regular cell agent and an enterprise network first. 16937 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16938 mCellAgent.connect(true); 16939 16940 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16941 workAgent.connect(true); 16942 16943 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16944 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16945 r -> r.run(), listener); 16946 listener.expectOnComplete(); 16947 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16948 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16949 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16950 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 16951 16952 registerDefaultNetworkCallbacks(); 16953 16954 mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16955 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16956 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 16957 16958 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 16959 r -> r.run(), listener); 16960 listener.expectOnComplete(); 16961 16962 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16963 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16964 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16965 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 16966 16967 workAgent.disconnect(); 16968 mCellAgent.disconnect(); 16969 16970 // Callbacks will be unregistered by tearDown() 16971 } 16972 16973 /** 16974 * Test per-profile default networks for two different profiles concurrently. 16975 */ 16976 @Test 16977 public void testSetPreferenceForTwoProfiles() throws Exception { 16978 final InOrder inOrder = inOrder(mMockNetd); 16979 final UserHandle testHandle2 = setupEnterpriseNetwork(); 16980 final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); 16981 mServiceContext.setWorkProfile(testHandle4, true); 16982 registerDefaultNetworkCallbacks(); 16983 16984 final TestNetworkCallback app4Cb = new TestNetworkCallback(); 16985 final int testWorkProfileAppUid4 = 16986 UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); 16987 registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); 16988 16989 // Connect both a regular cell agent and an enterprise network first. 16990 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16991 mCellAgent.connect(true); 16992 16993 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16994 workAgent.connect(true); 16995 16996 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16997 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16998 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16999 app4Cb.expectAvailableThenValidatedCallbacks(mCellAgent); 17000 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17001 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 17002 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17003 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 17004 17005 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17006 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17007 r -> r.run(), listener); 17008 listener.expectOnComplete(); 17009 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17010 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 17011 17012 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 17013 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17014 app4Cb); 17015 17016 mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17017 r -> r.run(), listener); 17018 listener.expectOnComplete(); 17019 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17020 workAgent.getNetwork().netId, uidRangeFor(testHandle4), PREFERENCE_ORDER_PROFILE)); 17021 17022 app4Cb.expectAvailableCallbacksValidated(workAgent); 17023 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17024 mProfileDefaultNetworkCallback); 17025 17026 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, 17027 r -> r.run(), listener); 17028 listener.expectOnComplete(); 17029 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 17030 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 17031 17032 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17033 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17034 app4Cb); 17035 17036 workAgent.disconnect(); 17037 mCellAgent.disconnect(); 17038 17039 mCm.unregisterNetworkCallback(app4Cb); 17040 // Other callbacks will be unregistered by tearDown() 17041 } 17042 17043 @Test 17044 public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { 17045 final InOrder inOrder = inOrder(mMockNetd); 17046 final UserHandle testHandle = setupEnterpriseNetwork(); 17047 17048 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17049 mCellAgent.connect(true); 17050 17051 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17052 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17053 r -> r.run(), listener); 17054 listener.expectOnComplete(); 17055 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17056 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 17057 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17058 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 17059 PREFERENCE_ORDER_PROFILE)); 17060 17061 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 17062 removedIntent.putExtra(Intent.EXTRA_USER, testHandle); 17063 processBroadcast(removedIntent); 17064 17065 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 17066 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 17067 PREFERENCE_ORDER_PROFILE)); 17068 } 17069 17070 @Test 17071 public void testProfileNetworkPreferenceBlocking_addUser() throws Exception { 17072 final InOrder inOrder = inOrder(mMockNetd); 17073 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 17074 17075 // Only one network 17076 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17077 mCellAgent.connect(true); 17078 17079 // Verify uid ranges 0~99999 are allowed 17080 final ArraySet<UidRange> allowedRanges = new ArraySet<>(); 17081 allowedRanges.add(PRIMARY_UIDRANGE); 17082 final NativeUidRangeConfig config1User = new NativeUidRangeConfig( 17083 mCellAgent.getNetwork().netId, 17084 toUidRangeStableParcels(allowedRanges), 17085 0 /* subPriority */); 17086 if (mDeps.isAtLeastU()) { 17087 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config1User}); 17088 } else { 17089 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17090 } 17091 17092 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE)) 17093 .when(mUserManager).getUserHandles(anyBoolean()); 17094 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 17095 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(SECONDARY_USER)); 17096 processBroadcast(addedIntent); 17097 17098 // Make sure the allow list has been updated. 17099 allowedRanges.add(UidRange.createForUser(SECONDARY_USER_HANDLE)); 17100 final NativeUidRangeConfig config2Users = new NativeUidRangeConfig( 17101 mCellAgent.getNetwork().netId, 17102 toUidRangeStableParcels(allowedRanges), 17103 0 /* subPriority */); 17104 if (mDeps.isAtLeastU()) { 17105 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config2Users}); 17106 } else { 17107 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17108 } 17109 } 17110 17111 @Test 17112 public void testProfileNetworkPreferenceBlocking_changePreference() throws Exception { 17113 final InOrder inOrder = inOrder(mMockNetd); 17114 final UserHandle testHandle = setupEnterpriseNetwork(); 17115 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 17116 .when(mUserManager).getUserHandles(anyBoolean()); 17117 17118 // Start with 1 default network and 1 enterprise network, both networks should 17119 // not be restricted since the blocking preference is not set yet. 17120 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17121 mCellAgent.connect(true); 17122 17123 // Verify uid ranges 0~99999, 200000~299999 are all allowed for cellular. 17124 final UidRange profileUidRange = 17125 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 17126 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 17127 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 17128 allowedAllUidRanges.add(profileUidRange); 17129 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 17130 allowedAllUidRanges); 17131 final NativeUidRangeConfig cellAllAllowedConfig = new NativeUidRangeConfig( 17132 mCellAgent.getNetwork().netId, 17133 allowAllUidRangesParcel, 17134 0 /* subPriority */); 17135 if (mDeps.isAtLeastU()) { 17136 inOrder.verify(mMockNetd).setNetworkAllowlist( 17137 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 17138 } else { 17139 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17140 } 17141 17142 // Verify the same uid ranges are also applied for enterprise network. 17143 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 17144 NET_ENTERPRISE_ID_1); 17145 enterpriseAgent.connect(true); 17146 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 17147 enterpriseAgent.getNetwork().netId, 17148 allowAllUidRangesParcel, 17149 0 /* subPriority */); 17150 // Network agents are stored in an ArraySet which does not guarantee the order and 17151 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 17152 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 17153 NativeUidRangeConfig[].class); 17154 if (mDeps.isAtLeastU()) { 17155 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17156 assertContainsAll(List.of(configsCaptor.getValue()), 17157 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 17158 } else { 17159 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17160 } 17161 17162 // Setup profile preference which only applies to test app uid on the managed profile. 17163 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 17164 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 17165 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 17166 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17167 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17168 mCm.setProfileNetworkPreferences(testHandle, 17169 List.of(prefBuilder.build()), 17170 r -> r.run(), listener); 17171 listener.expectOnComplete(); 17172 17173 // Verify Netd is called for the preferences changed. 17174 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 17175 // Enterprise: 0~99999, 200000~299999 17176 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 17177 excludeAppRanges.add(PRIMARY_UIDRANGE); 17178 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 17179 profileUidRange, 17180 new ArraySet(new UidRange[]{ 17181 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 17182 )); 17183 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 17184 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 17185 mCellAgent.getNetwork().netId, 17186 excludeAppRangesParcel, 17187 0 /* subPriority */); 17188 if (mDeps.isAtLeastU()) { 17189 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17190 assertContainsAll(List.of(configsCaptor.getValue()), 17191 List.of(cellExcludeAppConfig, enterpriseAllAllowedConfig)); 17192 } else { 17193 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17194 } 17195 17196 // Verify unset by giving all allowed set for all users when the preference got removed. 17197 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17198 r -> r.run(), listener); 17199 listener.expectOnComplete(); 17200 if (mDeps.isAtLeastU()) { 17201 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17202 assertContainsAll(List.of(configsCaptor.getValue()), 17203 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 17204 } else { 17205 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17206 } 17207 17208 // Verify issuing with cellular set only when a network with enterprise capability 17209 // disconnects. 17210 enterpriseAgent.disconnect(); 17211 waitForIdle(); 17212 if (mDeps.isAtLeastU()) { 17213 inOrder.verify(mMockNetd).setNetworkAllowlist( 17214 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 17215 } else { 17216 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17217 } 17218 } 17219 17220 @Test 17221 public void testProfileNetworkPreferenceBlocking_networkChanges() throws Exception { 17222 final InOrder inOrder = inOrder(mMockNetd); 17223 final UserHandle testHandle = setupEnterpriseNetwork(); 17224 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 17225 .when(mUserManager).getUserHandles(anyBoolean()); 17226 17227 // Setup profile preference which only applies to test app uid on the managed profile. 17228 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 17229 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 17230 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 17231 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17232 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17233 mCm.setProfileNetworkPreferences(testHandle, 17234 List.of(prefBuilder.build()), 17235 r -> r.run(), listener); 17236 listener.expectOnComplete(); 17237 if (mDeps.isAtLeastU()) { 17238 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 17239 } else { 17240 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17241 } 17242 17243 // Start with 1 default network, which should be restricted since the blocking 17244 // preference is already set. 17245 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17246 mCellAgent.connect(true); 17247 17248 // Verify cellular network applies to the allow list. 17249 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 17250 // Enterprise: 0~99999, 200000~299999 17251 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 17252 final UidRange profileUidRange = 17253 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 17254 excludeAppRanges.add(PRIMARY_UIDRANGE); 17255 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 17256 profileUidRange, 17257 new ArraySet(new UidRange[]{ 17258 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 17259 )); 17260 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 17261 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 17262 mCellAgent.getNetwork().netId, 17263 excludeAppRangesParcel, 17264 0 /* subPriority */); 17265 if (mDeps.isAtLeastU()) { 17266 inOrder.verify(mMockNetd).setNetworkAllowlist( 17267 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 17268 } else { 17269 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17270 } 17271 17272 // Verify enterprise network is not blocked for test app. 17273 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 17274 NET_ENTERPRISE_ID_1); 17275 enterpriseAgent.connect(true); 17276 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 17277 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 17278 allowedAllUidRanges.add(profileUidRange); 17279 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 17280 allowedAllUidRanges); 17281 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 17282 enterpriseAgent.getNetwork().netId, 17283 allowAllUidRangesParcel, 17284 0 /* subPriority */); 17285 // Network agents are stored in an ArraySet which does not guarantee the order and 17286 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 17287 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 17288 NativeUidRangeConfig[].class); 17289 if (mDeps.isAtLeastU()) { 17290 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17291 assertContainsAll(List.of(configsCaptor.getValue()), 17292 List.of(enterpriseAllAllowedConfig, cellExcludeAppConfig)); 17293 } else { 17294 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17295 } 17296 17297 // Verify issuing with cellular set only when enterprise network disconnects. 17298 enterpriseAgent.disconnect(); 17299 waitForIdle(); 17300 if (mDeps.isAtLeastU()) { 17301 inOrder.verify(mMockNetd).setNetworkAllowlist( 17302 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 17303 } else { 17304 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17305 } 17306 17307 mCellAgent.disconnect(); 17308 waitForIdle(); 17309 if (mDeps.isAtLeastU()) { 17310 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 17311 } else { 17312 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17313 } 17314 } 17315 17316 /** 17317 * Make sure wrong preferences for per-profile default networking are rejected. 17318 */ 17319 @Test 17320 public void testProfileNetworkPrefWrongPreference() throws Exception { 17321 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17322 mServiceContext.setWorkProfile(testHandle, true); 17323 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 17324 new ProfileNetworkPreference.Builder(); 17325 profileNetworkPreferenceBuilder.setPreference( 17326 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING + 1); 17327 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17328 assertThrows("Should not be able to set an illegal preference", 17329 IllegalArgumentException.class, 17330 () -> mCm.setProfileNetworkPreferences(testHandle, 17331 List.of(profileNetworkPreferenceBuilder.build()), 17332 null, null)); 17333 } 17334 17335 /** 17336 * Make sure requests for per-profile default networking for a non-work profile are 17337 * rejected 17338 */ 17339 @Test 17340 public void testProfileNetworkPrefWrongProfile() throws Exception { 17341 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17342 mServiceContext.setWorkProfile(testHandle, false); 17343 mServiceContext.setDeviceOwner(testHandle, null); 17344 assertThrows("Should not be able to set a user pref for a non-work profile " 17345 + "and non device owner", 17346 IllegalArgumentException.class , () -> 17347 mCm.setProfileNetworkPreference(testHandle, 17348 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); 17349 } 17350 17351 /** 17352 * Make sure requests for per-profile default networking for a device owner is 17353 * accepted on T and not accepted on S 17354 */ 17355 @Test 17356 public void testProfileNetworkDeviceOwner() throws Exception { 17357 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17358 mServiceContext.setWorkProfile(testHandle, false); 17359 mServiceContext.setDeviceOwner(testHandle, "deviceOwnerPackage"); 17360 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 17361 new ProfileNetworkPreference.Builder(); 17362 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 17363 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17364 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17365 if (mDeps.isAtLeastT()) { 17366 mCm.setProfileNetworkPreferences(testHandle, 17367 List.of(profileNetworkPreferenceBuilder.build()), 17368 r -> r.run(), listener); 17369 } else { 17370 // S should not allow setting preference on device owner 17371 assertThrows("Should not be able to set a user pref for a non-work profile on S", 17372 IllegalArgumentException.class , () -> 17373 mCm.setProfileNetworkPreferences(testHandle, 17374 List.of(profileNetworkPreferenceBuilder.build()), 17375 r -> r.run(), listener)); 17376 } 17377 } 17378 17379 @Test 17380 public void testSubIdsExist() throws Exception { 17381 final Set<Integer> subIds = Collections.singleton(Process.myUid()); 17382 final NetworkCapabilities nc = new NetworkCapabilities(); 17383 nc.setSubscriptionIds(subIds); 17384 17385 final NetworkCapabilities result = 17386 mService.networkCapabilitiesRestrictedForCallerPermissions( 17387 nc, Process.myPid(), Process.myUid()); 17388 assertEquals(subIds, result.getSubscriptionIds()); 17389 } 17390 17391 private NetworkRequest getRequestWithSubIds() { 17392 return new NetworkRequest.Builder() 17393 .setSubscriptionIds(Collections.singleton(Process.myUid())) 17394 .build(); 17395 } 17396 17397 private NetworkRequest getRestrictedRequestForWifiWithSubIds() { 17398 return new NetworkRequest.Builder() 17399 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 17400 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 17401 .setSubscriptionIds(Collections.singleton(TEST_SUBSCRIPTION_ID)) 17402 .build(); 17403 } 17404 17405 @Test 17406 public void testNetworkRequestWithSubIds() throws Exception { 17407 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 17408 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 17409 final NetworkCallback networkCallback1 = new NetworkCallback(); 17410 final NetworkCallback networkCallback2 = new NetworkCallback(); 17411 17412 mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); 17413 mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); 17414 mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); 17415 17416 mCm.unregisterNetworkCallback(networkCallback1); 17417 mCm.releaseNetworkRequest(pendingIntent); 17418 mCm.unregisterNetworkCallback(networkCallback2); 17419 } 17420 17421 @Test 17422 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17423 public void testCarrierConfigAppSendNetworkRequestForRestrictedWifi() throws Exception { 17424 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 17425 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17426 .isCarrierServiceUidForNetworkCapabilities(anyInt(), any()); 17427 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 17428 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 17429 final NetworkCallback networkCallback1 = new NetworkCallback(); 17430 final NetworkCallback networkCallback2 = new NetworkCallback(); 17431 17432 mCm.requestNetwork( 17433 getRestrictedRequestForWifiWithSubIds(), networkCallback1); 17434 mCm.requestNetwork( 17435 getRestrictedRequestForWifiWithSubIds(), pendingIntent); 17436 mCm.registerNetworkCallback( 17437 getRestrictedRequestForWifiWithSubIds(), networkCallback2); 17438 17439 mCm.unregisterNetworkCallback(networkCallback1); 17440 mCm.releaseNetworkRequest(pendingIntent); 17441 mCm.unregisterNetworkCallback(networkCallback2); 17442 } 17443 17444 private void doTestNetworkRequestWithCarrierPrivilegesLost( 17445 boolean shouldGrantRestrictedNetworkPermission, 17446 int lostPrivilegeUid, 17447 int lostPrivilegeSubId, 17448 boolean expectUnavailable, 17449 boolean expectCapChanged) throws Exception { 17450 if (shouldGrantRestrictedNetworkPermission) { 17451 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 17452 } else { 17453 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 17454 } 17455 17456 NetworkCapabilities filter = 17457 getRestrictedRequestForWifiWithSubIds().networkCapabilities; 17458 final HandlerThread handlerThread = new HandlerThread("testRestrictedFactoryRequests"); 17459 handlerThread.start(); 17460 17461 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 17462 mServiceContext, "testFactory", filter, mCsHandlerThread); 17463 testFactory.register(); 17464 testFactory.assertRequestCountEquals(0); 17465 17466 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17467 .isCarrierServiceUidForNetworkCapabilities(eq(Process.myUid()), any()); 17468 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 17469 final NetworkRequest networkrequest = 17470 getRestrictedRequestForWifiWithSubIds(); 17471 mCm.requestNetwork(networkrequest, networkCallback); 17472 testFactory.expectRequestAdd(); 17473 testFactory.assertRequestCountEquals(1); 17474 17475 NetworkCapabilities nc = new NetworkCapabilities.Builder(filter) 17476 .setAllowedUids(Set.of(Process.myUid())) 17477 .build(); 17478 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), nc); 17479 mWiFiAgent.connect(false); 17480 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 17481 final NetworkAgentInfo nai = mService.getNetworkAgentInfoForNetwork( 17482 mWiFiAgent.getNetwork()); 17483 17484 doReturn(false).when(mCarrierPrivilegeAuthenticator) 17485 .isCarrierServiceUidForNetworkCapabilities(eq(Process.myUid()), any()); 17486 doReturn(TEST_SUBSCRIPTION_ID).when(mCarrierPrivilegeAuthenticator) 17487 .getSubIdFromNetworkCapabilities(any()); 17488 17489 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> { 17490 mDeps.mCarrierPrivilegesLostListener.accept(lostPrivilegeUid, lostPrivilegeSubId); 17491 }); 17492 waitForIdle(); 17493 17494 if (expectCapChanged) { 17495 networkCallback.expect(NETWORK_CAPS_UPDATED); 17496 } 17497 if (expectUnavailable) { 17498 networkCallback.expect(UNAVAILABLE); 17499 } 17500 if (!expectCapChanged && !expectUnavailable) { 17501 networkCallback.assertNoCallback(); 17502 } 17503 17504 mWiFiAgent.disconnect(); 17505 17506 if (expectUnavailable) { 17507 testFactory.expectRequestRemove(); 17508 testFactory.assertRequestCountEquals(0); 17509 } else { 17510 testFactory.expectRequestAdd(); 17511 testFactory.assertRequestCountEquals(1); 17512 } 17513 17514 handlerThread.quitSafely(); 17515 handlerThread.join(); 17516 } 17517 17518 @Test 17519 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17520 public void testRestrictedRequestRemovedDueToCarrierPrivilegesLost() throws Exception { 17521 doTestNetworkRequestWithCarrierPrivilegesLost( 17522 false /* shouldGrantRestrictedNetworkPermission */, 17523 Process.myUid(), 17524 TEST_SUBSCRIPTION_ID, 17525 true /* expectUnavailable */, 17526 true /* expectCapChanged */); 17527 } 17528 17529 @Test 17530 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17531 public void testRequestNotRemoved_MismatchSubId() throws Exception { 17532 doTestNetworkRequestWithCarrierPrivilegesLost( 17533 false /* shouldGrantRestrictedNetworkPermission */, 17534 Process.myUid(), 17535 TEST_SUBSCRIPTION_ID + 1, 17536 false /* expectUnavailable */, 17537 false /* expectCapChanged */); 17538 } 17539 @Test 17540 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17541 public void testRequestNotRemoved_MismatchUid() throws Exception { 17542 doTestNetworkRequestWithCarrierPrivilegesLost( 17543 false /* shouldGrantRestrictedNetworkPermission */, 17544 Process.myUid() + 1, 17545 TEST_SUBSCRIPTION_ID, 17546 false /* expectUnavailable */, 17547 false /* expectCapChanged */); 17548 } 17549 17550 @Test 17551 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17552 public void testRequestNotRemoved_HasRestrictedNetworkPermission() throws Exception { 17553 doTestNetworkRequestWithCarrierPrivilegesLost( 17554 true /* shouldGrantRestrictedNetworkPermission */, 17555 Process.myUid(), 17556 TEST_SUBSCRIPTION_ID, 17557 false /* expectUnavailable */, 17558 true /* expectCapChanged */); 17559 } 17560 17561 @Test 17562 public void testAllowedUidsExistWithoutNetworkFactoryPermission() throws Exception { 17563 // Make sure NETWORK_FACTORY permission is not granted. 17564 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 17565 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17566 final TestNetworkCallback cb = new TestNetworkCallback(); 17567 mCm.requestNetwork(new NetworkRequest.Builder() 17568 .clearCapabilities() 17569 .addTransportType(TRANSPORT_TEST) 17570 .addTransportType(TRANSPORT_CELLULAR) 17571 .build(), 17572 cb); 17573 17574 final ArraySet<Integer> uids = new ArraySet<>(); 17575 uids.add(200); 17576 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 17577 .addTransportType(TRANSPORT_TEST) 17578 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17579 .setAllowedUids(uids) 17580 .setOwnerUid(Process.myUid()) 17581 .setAdministratorUids(new int[] {Process.myUid()}) 17582 .build(); 17583 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 17584 new LinkProperties(), nc); 17585 agent.connect(true); 17586 cb.expectAvailableThenValidatedCallbacks(agent); 17587 17588 uids.add(300); 17589 uids.add(400); 17590 nc.setAllowedUids(uids); 17591 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17592 if (mDeps.isAtLeastT()) { 17593 // AllowedUids is not cleared even without the NETWORK_FACTORY permission 17594 // because the caller is the owner of the network. 17595 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17596 } else { 17597 cb.assertNoCallback(); 17598 } 17599 } 17600 17601 @Test 17602 public void testAllowedUids() throws Exception { 17603 final int preferenceOrder = 17604 ConnectivityService.PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT; 17605 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17606 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17607 final TestNetworkCallback cb = new TestNetworkCallback(); 17608 mCm.requestNetwork(new NetworkRequest.Builder() 17609 .clearCapabilities() 17610 .addTransportType(TRANSPORT_TEST) 17611 .addTransportType(TRANSPORT_CELLULAR) 17612 .build(), 17613 cb); 17614 17615 final ArraySet<Integer> uids = new ArraySet<>(); 17616 uids.add(200); 17617 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 17618 .addTransportType(TRANSPORT_TEST) 17619 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17620 .setAllowedUids(uids) 17621 .build(); 17622 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 17623 new LinkProperties(), nc); 17624 agent.connect(true); 17625 cb.expectAvailableThenValidatedCallbacks(agent); 17626 17627 final InOrder inOrder = inOrder(mMockNetd); 17628 final NativeUidRangeConfig uids200Parcel = new NativeUidRangeConfig( 17629 agent.getNetwork().getNetId(), 17630 intToUidRangeStableParcels(uids), 17631 preferenceOrder); 17632 if (mDeps.isAtLeastT()) { 17633 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids200Parcel); 17634 } 17635 17636 uids.add(300); 17637 uids.add(400); 17638 nc.setAllowedUids(uids); 17639 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17640 if (mDeps.isAtLeastT()) { 17641 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17642 } else { 17643 cb.assertNoCallback(); 17644 } 17645 17646 uids.remove(200); 17647 final NativeUidRangeConfig uids300400Parcel = new NativeUidRangeConfig( 17648 agent.getNetwork().getNetId(), 17649 intToUidRangeStableParcels(uids), 17650 preferenceOrder); 17651 if (mDeps.isAtLeastT()) { 17652 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids300400Parcel); 17653 } 17654 17655 nc.setAllowedUids(uids); 17656 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17657 if (mDeps.isAtLeastT()) { 17658 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17659 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids200Parcel); 17660 } else { 17661 cb.assertNoCallback(); 17662 } 17663 17664 uids.clear(); 17665 uids.add(600); 17666 nc.setAllowedUids(uids); 17667 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17668 if (mDeps.isAtLeastT()) { 17669 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17670 } else { 17671 cb.assertNoCallback(); 17672 } 17673 final NativeUidRangeConfig uids600Parcel = new NativeUidRangeConfig( 17674 agent.getNetwork().getNetId(), 17675 intToUidRangeStableParcels(uids), 17676 preferenceOrder); 17677 if (mDeps.isAtLeastT()) { 17678 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids600Parcel); 17679 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids300400Parcel); 17680 } 17681 17682 uids.clear(); 17683 nc.setAllowedUids(uids); 17684 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17685 if (mDeps.isAtLeastT()) { 17686 cb.expectCaps(agent, c -> c.getAllowedUids().isEmpty()); 17687 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids600Parcel); 17688 } else { 17689 cb.assertNoCallback(); 17690 verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17691 verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17692 } 17693 17694 } 17695 17696 @Test 17697 public void testAutomotiveEthernetAllowedUids() throws Exception { 17698 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17699 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17700 17701 // Has automotive feature. 17702 validateAutomotiveEthernetAllowedUids(true); 17703 17704 // No automotive feature. 17705 validateAutomotiveEthernetAllowedUids(false); 17706 } 17707 17708 private void validateAutomotiveEthernetAllowedUids(final boolean hasAutomotiveFeature) 17709 throws Exception { 17710 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 17711 17712 // Simulate a restricted ethernet network. 17713 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17714 .addTransportType(TRANSPORT_ETHERNET) 17715 .addCapability(NET_CAPABILITY_INTERNET) 17716 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17717 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17718 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 17719 17720 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, 17721 new LinkProperties(), ncb.build()); 17722 17723 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17724 serviceUidSet.add(TEST_PACKAGE_UID); 17725 17726 final TestNetworkCallback cb = new TestNetworkCallback(); 17727 17728 mCm.requestNetwork(new NetworkRequest.Builder() 17729 .addTransportType(TRANSPORT_ETHERNET) 17730 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17731 .build(), cb); 17732 mEthernetAgent.connect(true); 17733 cb.expectAvailableThenValidatedCallbacks(mEthernetAgent); 17734 17735 // Cell gets to set the service UID as access UID 17736 ncb.setAllowedUids(serviceUidSet); 17737 mEthernetAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17738 if (mDeps.isAtLeastT() && hasAutomotiveFeature) { 17739 cb.expectCaps(mEthernetAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17740 } else { 17741 // S and no automotive feature must ignore access UIDs. 17742 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17743 } 17744 17745 mEthernetAgent.disconnect(); 17746 cb.expect(LOST, mEthernetAgent); 17747 mCm.unregisterNetworkCallback(cb); 17748 } 17749 17750 @Test 17751 public void testCbsAllowedUids() throws Exception { 17752 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17753 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17754 17755 // In this test TEST_PACKAGE_UID will be the UID of the carrier service UID. 17756 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17757 .isCarrierServiceUidForNetworkCapabilities(eq(TEST_PACKAGE_UID), any()); 17758 17759 // Simulate a restricted telephony network. The telephony factory is entitled to set 17760 // the access UID to the service package on any of its restricted networks. 17761 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17762 .addTransportType(TRANSPORT_CELLULAR) 17763 .addCapability(NET_CAPABILITY_INTERNET) 17764 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17765 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17766 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17767 .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); 17768 17769 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 17770 new LinkProperties(), ncb.build()); 17771 17772 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17773 serviceUidSet.add(TEST_PACKAGE_UID); 17774 final ArraySet<Integer> nonServiceUidSet = new ArraySet<>(); 17775 nonServiceUidSet.add(TEST_PACKAGE_UID2); 17776 final ArraySet<Integer> serviceUidSetPlus = new ArraySet<>(); 17777 serviceUidSetPlus.add(TEST_PACKAGE_UID); 17778 serviceUidSetPlus.add(TEST_PACKAGE_UID2); 17779 17780 final TestNetworkCallback cb = new TestNetworkCallback(); 17781 17782 // Cell gets to set the service UID as access UID 17783 mCm.requestNetwork(new NetworkRequest.Builder() 17784 .addTransportType(TRANSPORT_CELLULAR) 17785 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17786 .build(), cb); 17787 mCellAgent.connect(true); 17788 cb.expectAvailableThenValidatedCallbacks(mCellAgent); 17789 ncb.setAllowedUids(serviceUidSet); 17790 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17791 if (mDeps.isAtLeastT()) { 17792 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17793 } else { 17794 // S must ignore access UIDs. 17795 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17796 } 17797 17798 // ...but not to some other UID. Rejection sets UIDs to the empty set 17799 ncb.setAllowedUids(nonServiceUidSet); 17800 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17801 if (mDeps.isAtLeastT()) { 17802 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().isEmpty()); 17803 } else { 17804 // S must ignore access UIDs. 17805 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17806 } 17807 17808 // ...and also not to multiple UIDs even including the service UID 17809 ncb.setAllowedUids(serviceUidSetPlus); 17810 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17811 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17812 17813 mCellAgent.disconnect(); 17814 cb.expect(LOST, mCellAgent); 17815 mCm.unregisterNetworkCallback(cb); 17816 17817 // Must be unset before touching the transports, because remove and add transport types 17818 // check the specifier on the builder immediately, contradicting normal builder semantics 17819 // TODO : fix the builder 17820 ncb.setNetworkSpecifier(null); 17821 ncb.removeTransportType(TRANSPORT_CELLULAR); 17822 ncb.addTransportType(TRANSPORT_BLUETOOTH); 17823 // Wifi does not get to set access UID, even to the correct UID 17824 mCm.requestNetwork(new NetworkRequest.Builder() 17825 .addTransportType(TRANSPORT_BLUETOOTH) 17826 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17827 .build(), cb); 17828 final TestNetworkAgentWrapper bluetoothAgent = new TestNetworkAgentWrapper( 17829 TRANSPORT_BLUETOOTH, new LinkProperties(), ncb.build()); 17830 bluetoothAgent.connect(true); 17831 cb.expectAvailableThenValidatedCallbacks(bluetoothAgent); 17832 ncb.setAllowedUids(serviceUidSet); 17833 bluetoothAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17834 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17835 mCm.unregisterNetworkCallback(cb); 17836 } 17837 17838 @Test 17839 public void testSanitizedCapabilitiesFromAgentDoesNotMutateArgument() 17840 throws Exception { 17841 // This NetworkCapabilities builds an usual object to maximize the chance that this requires 17842 // sanitization, so we have a high chance to detect any changes to the original. 17843 final NetworkCapabilities unsanitized = new NetworkCapabilities.Builder() 17844 .withoutDefaultCapabilities() 17845 .addTransportType(TRANSPORT_WIFI) 17846 .addCapability(NET_CAPABILITY_INTERNET) 17847 .setOwnerUid(12345) 17848 .setAdministratorUids(new int[] {12345, 23456, 34567}) 17849 .setLinkUpstreamBandwidthKbps(20) 17850 .setLinkDownstreamBandwidthKbps(10) 17851 .setNetworkSpecifier(new EthernetNetworkSpecifier("foobar")) 17852 .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build()) 17853 .setSignalStrength(-75) 17854 .setSsid("SSID1") 17855 .setRequestorUid(98765) 17856 .setRequestorPackageName("TestPackage") 17857 .setSubscriptionIds(Collections.singleton(Process.myUid())) 17858 .setUids(UidRange.toIntRanges(uidRangesForUids( 17859 UserHandle.getUid(PRIMARY_USER, 10100), 17860 UserHandle.getUid(SECONDARY_USER, 10101), 17861 UserHandle.getUid(TERTIARY_USER, 10043)))) 17862 .setAllowedUids(Set.of(45678, 56789, 65432)) 17863 .setUnderlyingNetworks(List.of(new Network(99999))) 17864 .build(); 17865 final NetworkCapabilities copyOfUnsanitized = new NetworkCapabilities(unsanitized); 17866 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 17867 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 17868 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 17869 final NetworkAgentInfo agent = fakeNai(unsanitized, info); 17870 agent.setDeclaredCapabilities(unsanitized); 17871 final NetworkCapabilities sanitized = agent.getDeclaredCapabilitiesSanitized( 17872 null /* carrierPrivilegeAuthenticator */); 17873 assertEquals(copyOfUnsanitized, unsanitized); 17874 assertNotEquals(sanitized, unsanitized); 17875 } 17876 17877 /** 17878 * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. 17879 */ 17880 @Test 17881 public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { 17882 final UserHandle testHandle = setupEnterpriseNetwork(); 17883 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17884 // Leave one request available so the profile preference can be set. 17885 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> { 17886 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17887 Process.myPid(), Process.myUid(), () -> { 17888 // Set initially to test the limit prior to having existing requests. 17889 mCm.setProfileNetworkPreference(testHandle, 17890 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17891 Runnable::run, listener); 17892 }); 17893 listener.expectOnComplete(); 17894 17895 // Simulate filing requests as some app on the work profile 17896 final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, 17897 UserHandle.getAppId(Process.myUid() + 1)); 17898 final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID 17899 - mService.mNetworkRequestCounter.get(otherAppUid) 17900 - 1; 17901 final NetworkCallback[] callbacks = new NetworkCallback[remainingCount]; 17902 doAsUid(otherAppUid, () -> { 17903 for (int i = 0; i < remainingCount; ++i) { 17904 callbacks[i] = new TestNetworkCallback(); 17905 mCm.registerDefaultNetworkCallback(callbacks[i]); 17906 } 17907 }); 17908 17909 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17910 Process.myPid(), Process.myUid(), () -> { 17911 // re-set so as to test the limit as part of replacing existing requests. 17912 mCm.setProfileNetworkPreference(testHandle, 17913 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener); 17914 }); 17915 listener.expectOnComplete(); 17916 17917 doAsUid(otherAppUid, () -> { 17918 for (final NetworkCallback callback : callbacks) { 17919 mCm.unregisterNetworkCallback(callback); 17920 } 17921 }); 17922 }); 17923 } 17924 17925 /** 17926 * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. 17927 */ 17928 @Test 17929 public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { 17930 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 17931 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 17932 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 17933 // Leave one request available so the OEM preference can be set. 17934 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 17935 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 17936 // Set initially to test the limit prior to having existing requests. 17937 final TestOemListenerCallback listener = new TestOemListenerCallback(); 17938 mService.setOemNetworkPreference( 17939 createDefaultOemNetworkPreferences(networkPref), listener); 17940 listener.expectOnComplete(); 17941 17942 // re-set so as to test the limit as part of replacing existing requests. 17943 mService.setOemNetworkPreference( 17944 createDefaultOemNetworkPreferences(networkPref), listener); 17945 listener.expectOnComplete(); 17946 })); 17947 } 17948 17949 private void withRequestCountersAcquired(final int countToLeaveAvailable, 17950 @NonNull final ThrowingRunnable r) throws Exception { 17951 final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); 17952 try { 17953 final int requestCount = mService.mSystemNetworkRequestCounter.get(Process.myUid()); 17954 // The limit is hit when total requests = limit - 1, and exceeded with a crash when 17955 // total requests >= limit. 17956 final int countToFile = 17957 MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable; 17958 // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter 17959 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 17960 for (int i = 1; i < countToFile; i++) { 17961 final TestNetworkCallback cb = new TestNetworkCallback(); 17962 mCm.registerDefaultNetworkCallback(cb); 17963 callbacks.add(cb); 17964 } 17965 assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable, 17966 mService.mSystemNetworkRequestCounter.get(Process.myUid())); 17967 }); 17968 // Code to run to check if it triggers a max request count limit error. 17969 r.run(); 17970 } finally { 17971 for (final TestNetworkCallback cb : callbacks) { 17972 mCm.unregisterNetworkCallback(cb); 17973 } 17974 } 17975 } 17976 17977 private void assertCreateNrisFromMobileDataPreferredUids(Set<Integer> uids) { 17978 final Set<NetworkRequestInfo> nris = 17979 mService.createNrisFromMobileDataPreferredUids(uids); 17980 final NetworkRequestInfo nri = nris.iterator().next(); 17981 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 17982 // multiple uid ranges, so it only need create one NRI here. 17983 assertEquals(1, nris.size()); 17984 assertTrue(nri.isMultilayerRequest()); 17985 assertEquals(nri.getUids(), uidRangesForUids(uids)); 17986 assertEquals(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED, nri.mPreferenceOrder); 17987 } 17988 17989 /** 17990 * Test createNrisFromMobileDataPreferredUids returns correct NetworkRequestInfo. 17991 */ 17992 @Test 17993 public void testCreateNrisFromMobileDataPreferredUids() { 17994 // Verify that empty uid set should not create any NRI for it. 17995 final Set<NetworkRequestInfo> nrisNoUid = 17996 mService.createNrisFromMobileDataPreferredUids(new ArraySet<>()); 17997 assertEquals(0, nrisNoUid.size()); 17998 17999 final int uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 18000 final int uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2); 18001 final int uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 18002 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1)); 18003 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid3)); 18004 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid2)); 18005 } 18006 18007 private void setAndUpdateMobileDataPreferredUids(Set<Integer> uids) { 18008 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, uids); 18009 mService.updateMobileDataPreferredUids(); 18010 waitForIdle(); 18011 } 18012 18013 /** 18014 * Test that MOBILE_DATA_PREFERRED_UIDS changes will send correct net id and uid ranges to netd. 18015 */ 18016 @Test 18017 public void testMobileDataPreferredUidsChanged() throws Exception { 18018 final InOrder inorder = inOrder(mMockNetd); 18019 registerDefaultNetworkCallbacks(); 18020 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18021 mCellAgent.connect(true); 18022 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18023 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18024 18025 final int cellNetId = mCellAgent.getNetwork().netId; 18026 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18027 cellNetId, INetd.PERMISSION_NONE)); 18028 18029 // Initial mobile data preferred uids status. 18030 setAndUpdateMobileDataPreferredUids(Set.of()); 18031 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18032 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18033 18034 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that net id and uid ranges send to netd 18035 final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18036 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18037 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 18038 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18039 setAndUpdateMobileDataPreferredUids(uids1); 18040 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 18041 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18042 18043 // Set MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 18044 // new rules are added. 18045 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID), 18046 PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2), 18047 SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18048 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18049 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2, 18050 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18051 setAndUpdateMobileDataPreferredUids(uids2); 18052 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 18053 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2); 18054 18055 // Clear MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 18056 // new rules are not added. 18057 setAndUpdateMobileDataPreferredUids(Set.of()); 18058 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 18059 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18060 } 18061 18062 /** 18063 * Make sure mobile data preferred uids feature behaves as expected when the mobile network 18064 * goes up and down while the uids is set. Make sure they behave as expected whether 18065 * there is a general default network or not. 18066 */ 18067 @Test 18068 public void testMobileDataPreferenceForMobileNetworkUpDown() throws Exception { 18069 final InOrder inorder = inOrder(mMockNetd); 18070 // File a request for cell to ensure it doesn't go down. 18071 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 18072 final NetworkRequest cellRequest = new NetworkRequest.Builder() 18073 .addTransportType(TRANSPORT_CELLULAR).build(); 18074 mCm.requestNetwork(cellRequest, cellNetworkCallback); 18075 cellNetworkCallback.assertNoCallback(); 18076 18077 registerDefaultNetworkCallbacks(); 18078 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18079 mWiFiAgent.connect(true); 18080 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18081 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18082 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18083 18084 final int wifiNetId = mWiFiAgent.getNetwork().netId; 18085 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18086 wifiNetId, INetd.PERMISSION_NONE)); 18087 18088 // Initial mobile data preferred uids status. 18089 setAndUpdateMobileDataPreferredUids(Set.of()); 18090 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18091 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18092 18093 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that wifi net id and uid ranges send to 18094 // netd. 18095 final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18096 final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids)); 18097 final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges, 18098 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18099 setAndUpdateMobileDataPreferredUids(uids); 18100 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 18101 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18102 18103 // Cellular network connected. mTestPackageDefaultNetworkCallback should receive 18104 // callback with cellular network and net id and uid ranges should be updated to netd. 18105 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18106 mCellAgent.connect(true); 18107 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18108 mDefaultNetworkCallback.assertNoCallback(); 18109 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18110 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18111 18112 final int cellNetId = mCellAgent.getNetwork().netId; 18113 final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges, 18114 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18115 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18116 cellNetId, INetd.PERMISSION_NONE)); 18117 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig); 18118 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 18119 18120 // Cellular network disconnected. mTestPackageDefaultNetworkCallback should receive 18121 // callback with wifi network from fallback request. 18122 mCellAgent.disconnect(); 18123 mDefaultNetworkCallback.assertNoCallback(); 18124 cellNetworkCallback.expect(LOST, mCellAgent); 18125 mTestPackageDefaultNetworkCallback.expect(LOST, mCellAgent); 18126 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18127 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18128 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 18129 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18130 inorder.verify(mMockNetd).networkDestroy(cellNetId); 18131 18132 // Cellular network comes back. mTestPackageDefaultNetworkCallback should receive 18133 // callback with cellular network. 18134 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18135 mCellAgent.connect(true); 18136 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18137 mDefaultNetworkCallback.assertNoCallback(); 18138 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18139 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18140 18141 final int cellNetId2 = mCellAgent.getNetwork().netId; 18142 final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges, 18143 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18144 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18145 cellNetId2, INetd.PERMISSION_NONE)); 18146 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2); 18147 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 18148 18149 // Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive 18150 // any callback. 18151 mWiFiAgent.disconnect(); 18152 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 18153 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18154 mTestPackageDefaultNetworkCallback.assertNoCallback(); 18155 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18156 waitForIdle(); 18157 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18158 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18159 inorder.verify(mMockNetd).networkDestroy(wifiNetId); 18160 18161 mCm.unregisterNetworkCallback(cellNetworkCallback); 18162 } 18163 18164 @Test 18165 public void testMultilayerRequestsOfSetMobileDataPreferredUids() throws Exception { 18166 // First set mobile data preferred uid to create a multi-layer requests: 1. request for 18167 // cellular, 2. track the default network for fallback. 18168 setAndUpdateMobileDataPreferredUids( 18169 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 18170 18171 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 18172 handlerThread.start(); 18173 final NetworkCapabilities cellFilter = new NetworkCapabilities() 18174 .addTransportType(TRANSPORT_CELLULAR) 18175 .addCapability(NET_CAPABILITY_INTERNET) 18176 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 18177 final MockNetworkFactory cellFactory = new MockNetworkFactory(handlerThread.getLooper(), 18178 mServiceContext, "cellFactory", cellFilter, mCsHandlerThread); 18179 cellFactory.setScoreFilter(40); 18180 18181 try { 18182 cellFactory.register(); 18183 // Default internet request and the mobile data preferred request. 18184 cellFactory.expectRequestAdds(2); 18185 cellFactory.assertRequestCountEquals(2); 18186 18187 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18188 mWiFiAgent.connect(true); 18189 18190 // The cellFactory however is outscored, and should lose default internet request. 18191 // But it should still see mobile data preferred request. 18192 cellFactory.expectRequestRemove(); 18193 cellFactory.assertRequestCountEquals(1); 18194 18195 mWiFiAgent.disconnect(); 18196 // The network satisfying the default internet request has disconnected, so the 18197 // cellFactory sees the default internet requests again. 18198 cellFactory.expectRequestAdd(); 18199 cellFactory.assertRequestCountEquals(2); 18200 } finally { 18201 cellFactory.terminate(); 18202 handlerThread.quitSafely(); 18203 handlerThread.join(); 18204 } 18205 } 18206 18207 /** 18208 * Validate request counts are counted accurately on MOBILE_DATA_PREFERRED_UIDS change 18209 * on set/replace. 18210 */ 18211 @Test 18212 public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception { 18213 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, 18214 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 18215 // Leave one request available so MDO preference set up above can be set. 18216 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 18217 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 18218 Process.myPid(), Process.myUid(), () -> { 18219 // Set initially to test the limit prior to having existing requests. 18220 mService.updateMobileDataPreferredUids(); 18221 waitForIdle(); 18222 18223 // re-set so as to test the limit as part of replacing existing requests 18224 mService.updateMobileDataPreferredUids(); 18225 waitForIdle(); 18226 })); 18227 } 18228 18229 @Test 18230 public void testAllNetworkPreferencesCanCoexist() 18231 throws Exception { 18232 final InOrder inorder = inOrder(mMockNetd); 18233 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 18234 OEM_NETWORK_PREFERENCE_OEM_PAID; 18235 final UserHandle testHandle = setupEnterpriseNetwork(); 18236 18237 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 18238 final int cellNetId = mCellAgent.getNetwork().netId; 18239 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18240 cellNetId, INetd.PERMISSION_NONE)); 18241 18242 // Set oem network preference 18243 final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) }; 18244 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18245 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 18246 PREFERENCE_ORDER_OEM); 18247 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 18248 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 18249 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18250 18251 // Set user profile network preference 18252 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 18253 workAgent.connect(true); 18254 18255 final TestOnCompleteListener listener = new TestOnCompleteListener(); 18256 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 18257 r -> r.run(), listener); 18258 listener.expectOnComplete(); 18259 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId, 18260 uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE); 18261 inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 18262 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 18263 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18264 inorder.verify(mMockNetd).networkAddUidRangesParcel(config2); 18265 18266 // Set MOBILE_DATA_PREFERRED_UIDS setting 18267 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)); 18268 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18269 final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2, 18270 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18271 setAndUpdateMobileDataPreferredUids(uids2); 18272 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18273 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3); 18274 18275 // Set oem network preference again with different uid. 18276 final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3)); 18277 final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3)); 18278 final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3, 18279 PREFERENCE_ORDER_OEM); 18280 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test"); 18281 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 18282 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4); 18283 18284 // Remove user profile network preference 18285 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 18286 r -> r.run(), listener); 18287 listener.expectOnComplete(); 18288 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 18289 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18290 18291 // Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference. 18292 final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3, 18293 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18294 setAndUpdateMobileDataPreferredUids(uids3); 18295 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3); 18296 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6); 18297 } 18298 18299 @Test 18300 public void testNetworkCallbackAndActiveNetworkForUid_AllNetworkPreferencesEnabled() 18301 throws Exception { 18302 // File a request for cell to ensure it doesn't go down. 18303 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 18304 final NetworkRequest cellRequest = new NetworkRequest.Builder() 18305 .addTransportType(TRANSPORT_CELLULAR).build(); 18306 mCm.requestNetwork(cellRequest, cellNetworkCallback); 18307 cellNetworkCallback.assertNoCallback(); 18308 18309 // Register callbacks and have wifi network as default network. 18310 registerDefaultNetworkCallbacks(); 18311 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18312 mWiFiAgent.connect(true); 18313 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18314 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18315 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18316 assertEquals(mWiFiAgent.getNetwork(), 18317 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18318 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18319 18320 // Set MOBILE_DATA_PREFERRED_UIDS setting with TEST_WORK_PROFILE_APP_UID and 18321 // TEST_PACKAGE_UID. Both mProfileDefaultNetworkCallback and 18322 // mTestPackageDefaultNetworkCallback should receive callback with cell network. 18323 setAndUpdateMobileDataPreferredUids(Set.of(TEST_WORK_PROFILE_APP_UID, TEST_PACKAGE_UID)); 18324 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18325 mCellAgent.connect(true); 18326 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18327 mDefaultNetworkCallback.assertNoCallback(); 18328 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18329 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18330 assertEquals(mCellAgent.getNetwork(), 18331 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18332 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18333 18334 // Set user profile network preference with test profile. mProfileDefaultNetworkCallback 18335 // should receive callback with higher priority network preference (enterprise network). 18336 // The others should have no callbacks. 18337 final UserHandle testHandle = setupEnterpriseNetwork(); 18338 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 18339 workAgent.connect(true); 18340 final TestOnCompleteListener listener = new TestOnCompleteListener(); 18341 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 18342 r -> r.run(), listener); 18343 listener.expectOnComplete(); 18344 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18345 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 18346 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18347 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18348 18349 // Set oem network preference with TEST_PACKAGE_UID. mTestPackageDefaultNetworkCallback 18350 // should receive callback with higher priority network preference (current default network) 18351 // and the others should have no callbacks. 18352 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 18353 OEM_NETWORK_PREFERENCE_OEM_PAID; 18354 final int[] uids1 = new int[] { TEST_PACKAGE_UID }; 18355 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18356 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 18357 assertNoCallbacks(mDefaultNetworkCallback, mProfileDefaultNetworkCallback); 18358 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18359 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18360 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18361 18362 // Set oem network preference with TEST_WORK_PROFILE_APP_UID. Both 18363 // mProfileDefaultNetworkCallback and mTestPackageDefaultNetworkCallback should receive 18364 // callback. 18365 final int[] uids2 = new int[] { TEST_WORK_PROFILE_APP_UID }; 18366 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18367 doReturn(Arrays.asList(testHandle)).when(mUserManager).getUserHandles(anyBoolean()); 18368 setupSetOemNetworkPreferenceForPreferenceTest( 18369 networkPref, uidRanges2, "com.android.test", testHandle); 18370 mDefaultNetworkCallback.assertNoCallback(); 18371 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18372 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18373 assertEquals(mWiFiAgent.getNetwork(), 18374 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18375 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18376 18377 // Remove oem network preference, mProfileDefaultNetworkCallback should receive callback 18378 // with current highest priority network preference (enterprise network) and the others 18379 // should have no callbacks. 18380 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 18381 mService.setOemNetworkPreference( 18382 new OemNetworkPreferences.Builder().build(), oemPrefListener); 18383 oemPrefListener.expectOnComplete(); 18384 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18385 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 18386 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18387 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18388 18389 // Remove user profile network preference. 18390 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 18391 r -> r.run(), listener); 18392 listener.expectOnComplete(); 18393 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18394 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18395 assertEquals(mCellAgent.getNetwork(), 18396 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18397 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18398 18399 // Disconnect wifi 18400 mWiFiAgent.disconnect(); 18401 assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18402 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 18403 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18404 } 18405 18406 @Test 18407 public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { 18408 assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( 18409 ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", 18410 null /* callingAttributionTag */)); 18411 } 18412 18413 @Test @IgnoreUpTo(SC_V2) 18414 public void testUpdateRateLimit_EnableDisable() throws Exception { 18415 final LinkProperties wifiLp = new LinkProperties(); 18416 wifiLp.setInterfaceName(WIFI_IFNAME); 18417 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18418 mWiFiAgent.connect(true); 18419 18420 final LinkProperties cellLp = new LinkProperties(); 18421 cellLp.setInterfaceName(MOBILE_IFNAME); 18422 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18423 mCellAgent.connect(false); 18424 18425 waitForIdle(); 18426 18427 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18428 mDeps.mRateLimitHistory.newReadHead(); 18429 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadCell = 18430 mDeps.mRateLimitHistory.newReadHead(); 18431 18432 // set rate limit to 8MBit/s => 1MB/s 18433 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 18434 setIngressRateLimit(rateLimitInBytesPerSec); 18435 18436 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18437 it -> it.first == wifiLp.getInterfaceName() 18438 && it.second == rateLimitInBytesPerSec)); 18439 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 18440 it -> it.first == cellLp.getInterfaceName() 18441 && it.second == rateLimitInBytesPerSec)); 18442 18443 // disable rate limiting 18444 setIngressRateLimit(-1); 18445 18446 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18447 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 18448 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 18449 it -> it.first == cellLp.getInterfaceName() && it.second == -1)); 18450 } 18451 18452 @Test @IgnoreUpTo(SC_V2) 18453 public void testUpdateRateLimit_WhenNewNetworkIsAdded() throws Exception { 18454 final LinkProperties wifiLp = new LinkProperties(); 18455 wifiLp.setInterfaceName(WIFI_IFNAME); 18456 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18457 mWiFiAgent.connect(true); 18458 18459 waitForIdle(); 18460 18461 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 18462 mDeps.mRateLimitHistory.newReadHead(); 18463 18464 // set rate limit to 8MBit/s => 1MB/s 18465 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 18466 setIngressRateLimit(rateLimitInBytesPerSec); 18467 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName() 18468 && it.second == rateLimitInBytesPerSec)); 18469 18470 final LinkProperties cellLp = new LinkProperties(); 18471 cellLp.setInterfaceName(MOBILE_IFNAME); 18472 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18473 mCellAgent.connect(false); 18474 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == cellLp.getInterfaceName() 18475 && it.second == rateLimitInBytesPerSec)); 18476 } 18477 18478 @Test @IgnoreUpTo(SC_V2) 18479 public void testUpdateRateLimit_OnlyAffectsInternetCapableNetworks() throws Exception { 18480 final LinkProperties wifiLp = new LinkProperties(); 18481 wifiLp.setInterfaceName(WIFI_IFNAME); 18482 18483 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18484 mWiFiAgent.connectWithoutInternet(); 18485 18486 waitForIdle(); 18487 18488 setIngressRateLimit(1000); 18489 setIngressRateLimit(-1); 18490 18491 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18492 mDeps.mRateLimitHistory.newReadHead(); 18493 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 18494 } 18495 18496 @Test @IgnoreUpTo(SC_V2) 18497 public void testUpdateRateLimit_DisconnectingResetsRateLimit() 18498 throws Exception { 18499 // Steps: 18500 // - connect network 18501 // - set rate limit 18502 // - disconnect network (interface still exists) 18503 // - disable rate limit 18504 // - connect network 18505 // - ensure network interface is not rate limited 18506 final LinkProperties wifiLp = new LinkProperties(); 18507 wifiLp.setInterfaceName(WIFI_IFNAME); 18508 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18509 mWiFiAgent.connect(true); 18510 waitForIdle(); 18511 18512 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18513 mDeps.mRateLimitHistory.newReadHead(); 18514 18515 int rateLimitInBytesPerSec = 1000; 18516 setIngressRateLimit(rateLimitInBytesPerSec); 18517 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18518 it -> it.first == wifiLp.getInterfaceName() 18519 && it.second == rateLimitInBytesPerSec)); 18520 18521 mWiFiAgent.disconnect(); 18522 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18523 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 18524 18525 setIngressRateLimit(-1); 18526 18527 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18528 mWiFiAgent.connect(true); 18529 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 18530 } 18531 18532 @Test @IgnoreUpTo(SC_V2) 18533 public void testUpdateRateLimit_UpdateExistingRateLimit() throws Exception { 18534 final LinkProperties wifiLp = new LinkProperties(); 18535 wifiLp.setInterfaceName(WIFI_IFNAME); 18536 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18537 mWiFiAgent.connect(true); 18538 waitForIdle(); 18539 18540 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18541 mDeps.mRateLimitHistory.newReadHead(); 18542 18543 // update an active ingress rate limit 18544 setIngressRateLimit(1000); 18545 setIngressRateLimit(2000); 18546 18547 // verify the following order of execution: 18548 // 1. ingress rate limit set to 1000. 18549 // 2. ingress rate limit disabled (triggered by updating active rate limit). 18550 // 3. ingress rate limit set to 2000. 18551 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18552 it -> it.first == wifiLp.getInterfaceName() 18553 && it.second == 1000)); 18554 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18555 it -> it.first == wifiLp.getInterfaceName() 18556 && it.second == -1)); 18557 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18558 it -> it.first == wifiLp.getInterfaceName() 18559 && it.second == 2000)); 18560 } 18561 18562 @Test @IgnoreAfter(SC_V2) 18563 public void testUpdateRateLimit_DoesNothingBeforeT() throws Exception { 18564 final LinkProperties wifiLp = new LinkProperties(); 18565 wifiLp.setInterfaceName(WIFI_IFNAME); 18566 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18567 mWiFiAgent.connect(true); 18568 waitForIdle(); 18569 18570 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 18571 mDeps.mRateLimitHistory.newReadHead(); 18572 18573 setIngressRateLimit(1000); 18574 waitForIdle(); 18575 18576 assertNull(readHead.poll(TEST_CALLBACK_TIMEOUT_MS, it -> true)); 18577 } 18578 18579 @Test 18580 public void testOfferNetwork_ChecksArgumentsOutsideOfHandler() throws Exception { 18581 final TestableNetworkOfferCallback callback = new TestableNetworkOfferCallback( 18582 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 18583 final NetworkProvider testProvider = new NetworkProvider(mServiceContext, 18584 mCsHandlerThread.getLooper(), "Test provider"); 18585 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 18586 .addCapability(NET_CAPABILITY_INTERNET) 18587 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 18588 .build(); 18589 18590 final NetworkScore score = new NetworkScore.Builder().build(); 18591 testProvider.registerNetworkOffer(score, caps, r -> r.run(), callback); 18592 testProvider.unregisterNetworkOffer(callback); 18593 18594 assertThrows(NullPointerException.class, 18595 () -> mService.offerNetwork(100, score, caps, null)); 18596 assertThrows(NullPointerException.class, () -> mService.unofferNetwork(null)); 18597 } 18598 18599 public void doTestIgnoreValidationAfterRoam(int resValue, final boolean enabled) 18600 throws Exception { 18601 doReturn(resValue).when(mResources) 18602 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18603 18604 final String bssid1 = "AA:AA:AA:AA:AA:AA"; 18605 final String bssid2 = "BB:BB:BB:BB:BB:BB"; 18606 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18607 mCellAgent.connect(true); 18608 NetworkCapabilities wifiNc1 = new NetworkCapabilities() 18609 .addCapability(NET_CAPABILITY_INTERNET) 18610 .addCapability(NET_CAPABILITY_NOT_VPN) 18611 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 18612 .addCapability(NET_CAPABILITY_TRUSTED) 18613 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 18614 .addTransportType(TRANSPORT_WIFI) 18615 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid1).build()); 18616 NetworkCapabilities wifiNc2 = new NetworkCapabilities(wifiNc1) 18617 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid2).build()); 18618 final LinkProperties wifiLp = new LinkProperties(); 18619 wifiLp.setInterfaceName(WIFI_IFNAME); 18620 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1); 18621 mWiFiAgent.connect(true); 18622 18623 // The default network will be switching to Wi-Fi Network. 18624 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 18625 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 18626 .addTransportType(TRANSPORT_WIFI).build(); 18627 mCm.requestNetwork(wifiRequest, wifiNetworkCallback); 18628 wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18629 registerDefaultNetworkCallbacks(); 18630 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18631 18632 // There is a bug in the current code where ignoring validation after roam will not 18633 // correctly change the default network if the result if the validation is partial or 18634 // captive portal. TODO : fix the bug and reinstate this code. 18635 if (false) { 18636 // Wi-Fi roaming from wifiNc1 to wifiNc2 but the network is now behind a captive portal. 18637 mWiFiAgent.setNetworkCapabilities(wifiNc2, true /* sendToConnectivityService */); 18638 // The only thing changed in this CAPS is the BSSID, which can't be tested for in this 18639 // test because it's redacted. 18640 wifiNetworkCallback.expectCaps(mWiFiAgent); 18641 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18642 mWiFiAgent.setNetworkPortal(TEST_REDIRECT_URL, false /* privateDnsProbeSent */); 18643 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18644 // Wi-Fi is now detected to have a portal : cell should become the default network. 18645 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18646 wifiNetworkCallback.expectCaps(mWiFiAgent, 18647 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 18648 wifiNetworkCallback.expectCaps(mWiFiAgent, 18649 c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 18650 18651 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 18652 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18653 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18654 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18655 wifiNetworkCallback.expectCaps(mWiFiAgent, 18656 c -> !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 18657 18658 // Wi-Fi roaming from wifiNc2 to wifiNc1, and the network now has partial connectivity. 18659 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18660 wifiNetworkCallback.expectCaps(mWiFiAgent); 18661 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18662 mWiFiAgent.setNetworkPartial(); 18663 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18664 // Wi-Fi now only offers partial connectivity, so in the absence of accepting partial 18665 // connectivity explicitly for this network, it loses default status to cell. 18666 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18667 wifiNetworkCallback.expectCaps(mWiFiAgent, 18668 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18669 18670 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 18671 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18672 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18673 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18674 wifiNetworkCallback.expectCaps(mWiFiAgent, 18675 c -> !c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18676 } 18677 mCm.unregisterNetworkCallback(wifiNetworkCallback); 18678 18679 // Wi-Fi roams from wifiNc1 to wifiNc2, and now becomes really invalid. If validation 18680 // failures after roam are not ignored, this will cause cell to become the default network. 18681 // If they are ignored, this will not cause a switch until later. 18682 mWiFiAgent.setNetworkCapabilities(wifiNc2, true); 18683 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18684 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 18685 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18686 18687 if (enabled) { 18688 // Network validation failed, but the result will be ignored. 18689 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 18690 NET_CAPABILITY_VALIDATED)); 18691 mWiFiAgent.setNetworkValid(false); 18692 18693 // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis 18694 ConditionVariable waitForValidationBlock = new ConditionVariable(); 18695 doReturn(50).when(mResources) 18696 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18697 // Wi-Fi roaming from wifiNc2 to wifiNc1. 18698 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18699 mWiFiAgent.setNetworkInvalid(false); 18700 waitForValidationBlock.block(150); 18701 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18702 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18703 } else { 18704 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18705 } 18706 18707 // Wi-Fi is still connected and would become the default network if cell were to 18708 // disconnect. This assertion ensures that the switch to cellular was not caused by 18709 // Wi-Fi disconnecting (e.g., because the capability change to wifiNc2 caused it 18710 // to stop satisfying the default request). 18711 mCellAgent.disconnect(); 18712 mDefaultNetworkCallback.expect(LOST, mCellAgent); 18713 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 18714 18715 } 18716 18717 @Test 18718 public void testIgnoreValidationAfterRoamDisabled() throws Exception { 18719 doTestIgnoreValidationAfterRoam(-1, false /* enabled */); 18720 } 18721 18722 @Test 18723 public void testIgnoreValidationAfterRoamEnabled() throws Exception { 18724 final boolean enabled = !mDeps.isAtLeastT(); 18725 doTestIgnoreValidationAfterRoam(5_000, enabled); 18726 } 18727 18728 @Test 18729 public void testShouldIgnoreValidationFailureAfterRoam() { 18730 // Always disabled on T+. 18731 assumeFalse(mDeps.isAtLeastT()); 18732 18733 NetworkAgentInfo nai = fakeWifiNai(new NetworkCapabilities()); 18734 18735 // Enabled, but never roamed. 18736 doReturn(5_000).when(mResources) 18737 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18738 assertEquals(0, nai.lastRoamTime); 18739 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18740 18741 // Roamed recently. 18742 nai.lastRoamTime = SystemClock.elapsedRealtime() - 500 /* ms */; 18743 assertTrue(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18744 18745 // Disabled due to invalid setting (maximum is 10 seconds). 18746 doReturn(15_000).when(mResources) 18747 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18748 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18749 18750 // Disabled. 18751 doReturn(-1).when(mResources) 18752 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18753 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18754 } 18755 18756 18757 @Test 18758 public void testLegacyTetheringApiGuardWithProperPermission() throws Exception { 18759 final String testIface = "test0"; 18760 mServiceContext.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED); 18761 assertThrows(SecurityException.class, () -> mService.getLastTetherError(testIface)); 18762 assertThrows(SecurityException.class, () -> mService.getTetherableIfaces()); 18763 assertThrows(SecurityException.class, () -> mService.getTetheredIfaces()); 18764 assertThrows(SecurityException.class, () -> mService.getTetheringErroredIfaces()); 18765 assertThrows(SecurityException.class, () -> mService.getTetherableUsbRegexs()); 18766 assertThrows(SecurityException.class, () -> mService.getTetherableWifiRegexs()); 18767 18768 withPermission(ACCESS_NETWORK_STATE, () -> { 18769 mService.getLastTetherError(testIface); 18770 verify(mTetheringManager).getLastTetherError(testIface); 18771 18772 mService.getTetherableIfaces(); 18773 verify(mTetheringManager).getTetherableIfaces(); 18774 18775 mService.getTetheredIfaces(); 18776 verify(mTetheringManager).getTetheredIfaces(); 18777 18778 mService.getTetheringErroredIfaces(); 18779 verify(mTetheringManager).getTetheringErroredIfaces(); 18780 18781 mService.getTetherableUsbRegexs(); 18782 verify(mTetheringManager).getTetherableUsbRegexs(); 18783 18784 mService.getTetherableWifiRegexs(); 18785 verify(mTetheringManager).getTetherableWifiRegexs(); 18786 }); 18787 } 18788 18789 private void verifyMtuSetOnWifiInterface(int mtu) throws Exception { 18790 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18791 } 18792 18793 private void verifyMtuNeverSetOnWifiInterface() throws Exception { 18794 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18795 } 18796 18797 private void verifyMtuSetOnWifiInterfaceOnlyUpToT(int mtu) throws Exception { 18798 if (!mService.shouldCreateNetworksImmediately()) { 18799 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18800 } else { 18801 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18802 } 18803 } 18804 18805 private void verifyMtuSetOnWifiInterfaceOnlyStartingFromU(int mtu) throws Exception { 18806 if (mService.shouldCreateNetworksImmediately()) { 18807 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18808 } else { 18809 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18810 } 18811 } 18812 18813 @Test 18814 public void testSendLinkPropertiesSetInterfaceMtuBeforeConnect() throws Exception { 18815 final int mtu = 1281; 18816 LinkProperties lp = new LinkProperties(); 18817 lp.setInterfaceName(WIFI_IFNAME); 18818 lp.setMtu(mtu); 18819 18820 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18821 mWiFiAgent.sendLinkProperties(lp); 18822 waitForIdle(); 18823 verifyMtuSetOnWifiInterface(mtu); 18824 reset(mMockNetd); 18825 18826 mWiFiAgent.connect(false /* validated */); 18827 // Before U, the MTU is always (re-)applied when the network connects. 18828 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu); 18829 } 18830 18831 @Test 18832 public void testSendLinkPropertiesUpdateInterfaceMtuBeforeConnect() throws Exception { 18833 final int mtu = 1327; 18834 LinkProperties lp = new LinkProperties(); 18835 lp.setInterfaceName(WIFI_IFNAME); 18836 lp.setMtu(mtu); 18837 18838 // Registering an agent with an MTU only sets the MTU on U+. 18839 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18840 waitForIdle(); 18841 verifyMtuSetOnWifiInterfaceOnlyStartingFromU(mtu); 18842 reset(mMockNetd); 18843 18844 // Future updates with the same MTU don't set the MTU even on T when it's not set initially. 18845 mWiFiAgent.sendLinkProperties(lp); 18846 waitForIdle(); 18847 verifyMtuNeverSetOnWifiInterface(); 18848 18849 // Updating with a different MTU does work. 18850 lp.setMtu(mtu + 1); 18851 mWiFiAgent.sendLinkProperties(lp); 18852 waitForIdle(); 18853 verifyMtuSetOnWifiInterface(mtu + 1); 18854 reset(mMockNetd); 18855 18856 mWiFiAgent.connect(false /* validated */); 18857 // Before U, the MTU is always (re-)applied when the network connects. 18858 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu + 1); 18859 } 18860 18861 @Test 18862 public void testSendLinkPropertiesUpdateInterfaceMtuAfterConnect() throws Exception { 18863 final int mtu = 1327; 18864 LinkProperties lp = new LinkProperties(); 18865 lp.setInterfaceName(WIFI_IFNAME); 18866 lp.setMtu(mtu); 18867 18868 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18869 mWiFiAgent.connect(false /* validated */); 18870 verifyMtuNeverSetOnWifiInterface(); 18871 18872 mWiFiAgent.sendLinkProperties(lp); 18873 waitForIdle(); 18874 // The MTU is always (re-)applied when the network connects. 18875 verifyMtuSetOnWifiInterface(mtu); 18876 } 18877 18878 @Test 18879 public void testSendLinkPropertiesSetInterfaceMtu_DifferentMtu() throws Exception { 18880 final int mtu = 1328, mtu2 = 1500; 18881 LinkProperties lp = new LinkProperties(); 18882 lp.setInterfaceName(WIFI_IFNAME); 18883 lp.setMtu(mtu); 18884 18885 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18886 mWiFiAgent.connect(false /* validated */); 18887 verifyMtuSetOnWifiInterface(mtu); 18888 reset(mMockNetd); 18889 18890 LinkProperties lp2 = new LinkProperties(lp); 18891 lp2.setMtu(mtu2); 18892 mWiFiAgent.sendLinkProperties(lp2); 18893 waitForIdle(); 18894 verifyMtuSetOnWifiInterface(mtu2); 18895 } 18896 18897 @Test 18898 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndIface() throws Exception { 18899 final int mtu = 1329; 18900 LinkProperties lp = new LinkProperties(); 18901 lp.setInterfaceName(WIFI_IFNAME); 18902 lp.setMtu(mtu); 18903 18904 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18905 mWiFiAgent.connect(false /* validated */); 18906 verifyMtuSetOnWifiInterface(mtu); 18907 reset(mMockNetd); 18908 18909 mWiFiAgent.sendLinkProperties(new LinkProperties(lp)); 18910 waitForIdle(); 18911 verifyMtuNeverSetOnWifiInterface(); 18912 } 18913 18914 @Test 18915 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndNullIface() throws Exception { 18916 final int mtu = 1330; 18917 LinkProperties lp = new LinkProperties(); 18918 lp.setInterfaceName(WIFI_IFNAME); 18919 lp.setMtu(mtu); 18920 18921 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18922 mWiFiAgent.connect(false /* validated */); 18923 verifyMtuSetOnWifiInterface(mtu); 18924 reset(mMockNetd); 18925 18926 LinkProperties lp2 = new LinkProperties(lp); 18927 lp2.setInterfaceName(null); 18928 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 18929 waitForIdle(); 18930 verifyMtuNeverSetOnWifiInterface(); 18931 } 18932 18933 @Test 18934 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuDiffIface() throws Exception { 18935 final int mtu = 1331; 18936 LinkProperties lp = new LinkProperties(); 18937 lp.setInterfaceName(WIFI_IFNAME); 18938 lp.setMtu(mtu); 18939 18940 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18941 mWiFiAgent.connect(false /* validated */); 18942 verifyMtuSetOnWifiInterface(mtu); 18943 reset(mMockNetd); 18944 18945 final String ifaceName2 = WIFI_IFNAME + "_2"; 18946 LinkProperties lp2 = new LinkProperties(lp); 18947 lp2.setInterfaceName(ifaceName2); 18948 18949 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 18950 waitForIdle(); 18951 verify(mMockNetd, times(1)).interfaceSetMtu(eq(ifaceName2), eq(mtu)); 18952 verifyMtuNeverSetOnWifiInterface(); 18953 } 18954 18955 @Test 18956 public void testCreateDeliveryGroupKeyForConnectivityAction() throws Exception { 18957 final NetworkInfo info = new NetworkInfo(0 /* type */, 2 /* subtype */, 18958 "MOBILE" /* typeName */, "LTE" /* subtypeName */); 18959 assertEquals("0;2;null", createDeliveryGroupKeyForConnectivityAction(info)); 18960 18961 info.setExtraInfo("test_info"); 18962 assertEquals("0;2;test_info", createDeliveryGroupKeyForConnectivityAction(info)); 18963 } 18964 18965 @Test 18966 public void testNetdWakeupAddInterfaceForWifiTransport() throws Exception { 18967 final LinkProperties wifiLp = new LinkProperties(); 18968 wifiLp.setInterfaceName(WIFI_IFNAME); 18969 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18970 mWiFiAgent.connect(false /* validated */); 18971 18972 final String expectedPrefix = makeNflogPrefix(WIFI_IFNAME, 18973 mWiFiAgent.getNetwork().getNetworkHandle()); 18974 verify(mMockNetd).wakeupAddInterface(WIFI_IFNAME, expectedPrefix, PACKET_WAKEUP_MARK_MASK, 18975 PACKET_WAKEUP_MARK_MASK); 18976 } 18977 18978 @Test 18979 public void testNetdWakeupAddInterfaceForCellularTransport() throws Exception { 18980 final LinkProperties cellLp = new LinkProperties(); 18981 cellLp.setInterfaceName(MOBILE_IFNAME); 18982 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18983 mCellAgent.connect(false /* validated */); 18984 18985 if (mDeps.isAtLeastU()) { 18986 final String expectedPrefix = makeNflogPrefix(MOBILE_IFNAME, 18987 mCellAgent.getNetwork().getNetworkHandle()); 18988 verify(mMockNetd).wakeupAddInterface(MOBILE_IFNAME, expectedPrefix, 18989 PACKET_WAKEUP_MARK_MASK, PACKET_WAKEUP_MARK_MASK); 18990 } else { 18991 verify(mMockNetd, never()).wakeupAddInterface(eq(MOBILE_IFNAME), anyString(), anyInt(), 18992 anyInt()); 18993 } 18994 } 18995 18996 @Test 18997 public void testNetdWakeupAddInterfaceForEthernetTransport() throws Exception { 18998 final String ethernetIface = "eth42"; 18999 19000 final LinkProperties ethLp = new LinkProperties(); 19001 ethLp.setInterfaceName(ethernetIface); 19002 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, ethLp); 19003 mEthernetAgent.connect(false /* validated */); 19004 19005 verify(mMockNetd, never()).wakeupAddInterface(eq(ethernetIface), anyString(), anyInt(), 19006 anyInt()); 19007 } 19008 19009 // UidFrozenStateChangedCallback is added in U API. 19010 // Returning UidFrozenStateChangedCallback directly makes the test fail on T- devices since 19011 // AndroidJUnit4ClassRunner iterates all declared methods and tries to resolve the return type. 19012 // Solve this by wrapping it in an AtomicReference. Because of erasure, this removes the 19013 // resolving problem as the type isn't seen dynamically. 19014 private AtomicReference<UidFrozenStateChangedCallback> getUidFrozenStateChangedCallback() { 19015 ArgumentCaptor<UidFrozenStateChangedCallback> activityManagerCallbackCaptor = 19016 ArgumentCaptor.forClass(UidFrozenStateChangedCallback.class); 19017 verify(mActivityManager).registerUidFrozenStateChangedCallback(any(), 19018 activityManagerCallbackCaptor.capture()); 19019 return new AtomicReference<>(activityManagerCallbackCaptor.getValue()); 19020 } 19021 19022 private BaseNetdUnsolicitedEventListener getRegisteredNetdUnsolicitedEventListener() 19023 throws RemoteException { 19024 ArgumentCaptor<BaseNetdUnsolicitedEventListener> netdCallbackCaptor = 19025 ArgumentCaptor.forClass(BaseNetdUnsolicitedEventListener.class); 19026 verify(mMockNetd).registerUnsolicitedEventListener(netdCallbackCaptor.capture()); 19027 return netdCallbackCaptor.getValue(); 19028 } 19029 19030 private static final int TEST_FROZEN_UID = 1000; 19031 private static final int TEST_UNFROZEN_UID = 2000; 19032 19033 /** 19034 * Send a UidFrozenStateChanged message to ConnectivityService. Verify that only the frozen UID 19035 * gets passed to socketDestroy(). 19036 */ 19037 @Test 19038 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19039 public void testFrozenUidSocketDestroy() throws Exception { 19040 final UidFrozenStateChangedCallback callback = 19041 getUidFrozenStateChangedCallback().get(); 19042 19043 final int[] uids = {TEST_FROZEN_UID, TEST_UNFROZEN_UID}; 19044 final int[] frozenStates = {UID_FROZEN_STATE_FROZEN, UID_FROZEN_STATE_UNFROZEN}; 19045 19046 callback.onUidFrozenStateChanged(uids, frozenStates); 19047 19048 waitForIdle(); 19049 19050 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids(Set.of(TEST_FROZEN_UID)); 19051 } 19052 19053 private void doTestDelayFrozenUidSocketDestroy(int transportType, 19054 boolean freezeWithNetworkInactive, boolean expectDelay) throws Exception { 19055 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 19056 final LinkProperties lp = new LinkProperties(); 19057 lp.setInterfaceName(transportToTestIfaceName(transportType)); 19058 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 19059 final int idleTimerLabel = getIdleTimerLabel(agent.getNetwork().netId, transportType); 19060 testAndCleanup(() -> { 19061 final UidFrozenStateChangedCallback uidFrozenStateChangedCallback = 19062 getUidFrozenStateChangedCallback().get(); 19063 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 19064 getRegisteredNetdUnsolicitedEventListener(); 19065 19066 mCm.registerDefaultNetworkCallback(defaultCallback); 19067 agent.connect(true); 19068 defaultCallback.expectAvailableThenValidatedCallbacks(agent); 19069 if (freezeWithNetworkInactive) { 19070 // Make network inactive 19071 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 19072 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 19073 } 19074 19075 // Freeze TEST_FROZEN_UID and TEST_UNFROZEN_UID 19076 final int[] uids1 = {TEST_FROZEN_UID, TEST_UNFROZEN_UID}; 19077 final int[] frozenStates1 = {UID_FROZEN_STATE_FROZEN, UID_FROZEN_STATE_FROZEN}; 19078 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids1, frozenStates1); 19079 waitForIdle(); 19080 19081 if (expectDelay) { 19082 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19083 } else { 19084 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids( 19085 Set.of(TEST_FROZEN_UID, TEST_UNFROZEN_UID)); 19086 clearInvocations(mDestroySocketsWrapper); 19087 } 19088 19089 // Unfreeze TEST_UNFROZEN_UID 19090 final int[] uids2 = {TEST_UNFROZEN_UID}; 19091 final int[] frozenStates2 = {UID_FROZEN_STATE_UNFROZEN}; 19092 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids2, frozenStates2); 19093 19094 // Make network active 19095 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(true /* isActive */, 19096 idleTimerLabel, TIMESTAMP, TEST_PACKAGE_UID); 19097 waitForIdle(); 19098 19099 if (expectDelay) { 19100 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids( 19101 Set.of(TEST_FROZEN_UID)); 19102 } else { 19103 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19104 } 19105 }, () -> { // Cleanup 19106 agent.disconnect(); 19107 }, () -> { 19108 mCm.unregisterNetworkCallback(defaultCallback); 19109 }); 19110 } 19111 19112 @Test 19113 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19114 public void testDelayFrozenUidSocketDestroy_ActiveCellular() throws Exception { 19115 doTestDelayFrozenUidSocketDestroy(TRANSPORT_CELLULAR, false /* freezeWithNetworkInactive */, 19116 false /* expectDelay */); 19117 } 19118 19119 @Test 19120 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19121 public void testDelayFrozenUidSocketDestroy_InactiveCellular() throws Exception { 19122 // When the default network is cellular and cellular network is inactive, closing socket 19123 // is delayed. 19124 doTestDelayFrozenUidSocketDestroy(TRANSPORT_CELLULAR, true /* freezeWithNetworkInactive */, 19125 true /* expectDelay */); 19126 } 19127 19128 @Test 19129 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19130 public void testDelayFrozenUidSocketDestroy_ActiveWifi() throws Exception { 19131 doTestDelayFrozenUidSocketDestroy(TRANSPORT_WIFI, false /* freezeWithNetworkInactive */, 19132 false /* expectDelay */); 19133 } 19134 19135 @Test 19136 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19137 public void testDelayFrozenUidSocketDestroy_InactiveWifi() throws Exception { 19138 doTestDelayFrozenUidSocketDestroy(TRANSPORT_WIFI, true /* freezeWithNetworkInactive */, 19139 false /* expectDelay */); 19140 } 19141 19142 /** 19143 * @param switchToWifi if true, simulate a migration of the default network to wifi 19144 * if false, simulate a cell disconnection 19145 */ 19146 private void doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(final boolean switchToWifi) 19147 throws Exception { 19148 final UidFrozenStateChangedCallback uidFrozenStateChangedCallback = 19149 getUidFrozenStateChangedCallback().get(); 19150 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 19151 getRegisteredNetdUnsolicitedEventListener(); 19152 19153 final LinkProperties wifiLp = new LinkProperties(); 19154 wifiLp.setInterfaceName(WIFI_IFNAME); 19155 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 19156 19157 final LinkProperties cellLp = new LinkProperties(); 19158 cellLp.setInterfaceName(MOBILE_IFNAME); 19159 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 19160 final int idleTimerLabel = 19161 getIdleTimerLabel(mCellAgent.getNetwork().netId, TRANSPORT_CELLULAR); 19162 19163 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 19164 mCm.registerDefaultNetworkCallback(defaultCallback); 19165 try { 19166 mCellAgent.connect(true); 19167 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 19168 19169 // Make cell network inactive 19170 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 19171 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 19172 19173 // Freeze TEST_FROZEN_UID 19174 final int[] uids = {TEST_FROZEN_UID}; 19175 final int[] frozenStates = {UID_FROZEN_STATE_FROZEN}; 19176 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids, frozenStates); 19177 waitForIdle(); 19178 19179 // Closing frozen sockets should be delayed since the default network is cellular 19180 // and cellular network is inactive. 19181 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19182 19183 if (switchToWifi) { 19184 mWiFiAgent.connect(true); 19185 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 19186 } else { 19187 mCellAgent.disconnect(); 19188 waitForIdle(); 19189 } 19190 19191 // Pending frozen sockets should be closed since the cellular network is no longer the 19192 // default network. 19193 verify(mDestroySocketsWrapper) 19194 .destroyLiveTcpSocketsByOwnerUids(Set.of(TEST_FROZEN_UID)); 19195 } finally { 19196 mCm.unregisterNetworkCallback(defaultCallback); 19197 } 19198 } 19199 19200 @Test 19201 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19202 public void testLoseCellDefaultNetwork_SwitchToWifi_ClosePendingFrozenSockets() 19203 throws Exception { 19204 doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(true /* switchToWifi */); 19205 } 19206 19207 @Test 19208 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19209 public void testLoseCellDefaultNetwork_NoDefaultNetwork_ClosePendingFrozenSockets() 19210 throws Exception { 19211 doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(false /* switchToWifi */); 19212 } 19213 19214 @Test 19215 public void testDisconnectSuspendedNetworkStopClatd() throws Exception { 19216 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 19217 final NetworkRequest networkRequest = new NetworkRequest.Builder() 19218 .addCapability(NET_CAPABILITY_DUN) 19219 .build(); 19220 mCm.requestNetwork(networkRequest, networkCallback); 19221 19222 final IpPrefix nat64Prefix = new IpPrefix(InetAddress.getByName("64:ff9b::"), 96); 19223 NetworkCapabilities nc = new NetworkCapabilities().addCapability(NET_CAPABILITY_DUN); 19224 final LinkProperties lp = new LinkProperties(); 19225 lp.setInterfaceName(MOBILE_IFNAME); 19226 lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 19227 lp.setNat64Prefix(nat64Prefix); 19228 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 19229 mCellAgent.connect(true /* validated */, false /* hasInternet */, 19230 false /* privateDnsProbeSent */); 19231 19232 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, mCellAgent.getNetwork().netId, 19233 nat64Prefix.toString()); 19234 19235 mCellAgent.suspend(); 19236 mCm.unregisterNetworkCallback(networkCallback); 19237 mCellAgent.expectDisconnected(); 19238 waitForIdle(); 19239 19240 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 19241 } 19242 19243 private static final int EXPECTED_TEST_METHOD_COUNT = 332; 19244 19245 @Test 19246 public void testTestMethodCount() { 19247 final Class<?> testClass = this.getClass(); 19248 19249 int actualTestMethodCount = 0; 19250 for (final Method method : testClass.getDeclaredMethods()) { 19251 if (method.isAnnotationPresent(Test.class)) { 19252 actualTestMethodCount++; 19253 } 19254 } 19255 19256 assertEquals("Adding tests in ConnectivityServiceTest is deprecated, " 19257 + "as it is too big for maintenance. Please consider adding new tests " 19258 + "in subclasses of CSTest instead.", 19259 EXPECTED_TEST_METHOD_COUNT, actualTestMethodCount); 19260 } 19261 19262 // Note : adding tests in ConnectivityServiceTest is deprecated, as it is too big for 19263 // maintenance. Please consider adding new tests in subclasses of CSTest instead. 19264 } 19265